2017-01-13 1 views
0

XML을 사용하여 서버와 통신하는 모바일 클라이언트가 있습니다. 저는 새로운 전화기에서 아주 쉽게 접근 할 수있게 된 최근의 UTF-8 스마일을 보내야 할 때 문제가 생겼습니다. 예를 들면 :.스마일 같은 새로운 UTF-8에 대한 XML 지원

이제 안드로이드 애플리케이션은 인코딩과 보내기에 별다른 문제가 없지만 서버 쪽에서는 좀 더 폭발적인 경향이 있습니다.

우리는 관련 부분과 함께, 우리는 거대한 스택 트레이스를 얻을 수 위의 스마일 중 하나를 사용하여 메시지를 보내려고 경우

javax.xml.transform.TransformerException: org.xml.sax.SAXException: Invalid UTF-16 surrogate detected: d83d d83d ? 
java.io.IOException: Invalid UTF-16 surrogate detected: d83d d83d ? 
     at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source) 
     at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(Unknown Source) 

그리고 우리는 그것을 구문 분석하려고하면 :

2017-01-13 14:00:22,717 - com.zylinc.core.gatekeeper.stripes.DoBean - WARN - Could not handle request 
org.xml.sax.SAXParseException; lineNumber: 3; columnNumber: 93; Character reference "&# 
     at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) 
     at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) 
     at com.zylinc.core.gatekeeper.stripes.DoBean.parseRequest(DoBean.java:127) 
     at com.zylinc.core.gatekeeper.stripes.DoBean.execute(DoBean.java:56) 
     at com.zylinc.core.gatekeeper.Dispatcher.onRequest(Dispatcher.java:107) 
     at com.zylinc.core.gatekeeper.io.UntrustedSocketListener.handleRequest(UntrustedSocketListener.java:16) 
     at com.zylinc.core.gatekeeper.io.SocketListener$MessageHandler.run(SocketListener.java:228) 
     at java.lang.Thread.run(Unknown Source) 

는 경우에 XML은 다음과 같습니다 이제

<?xml version="1.0" encoding="UTF-8"?><action> 
<set> 
<absence requestid="0" from="2017 01 13 13 00 11" to="2017 01 13 22 59 11" subject="&#55357;&#56846;" user_id="CN=???????? ????????????,OU=TestUsers,OU=ZyUsers,DC=Zylinc,DC=com"/> 
</set> 
</action> 

,이 클라이언트를 JSON 출력, 그러나 이동할 때 잘 작동하는 것 같다 JSON을 사용하는 것은 우리가 하룻밤 사이에 할 수있는 일이 아닙니다. 사용 된 문자가 Java 버전과 비교하여 너무 새롭기 때문에 깨지기는하지만, 새로운 스마일이 메시징을 깨뜨리지 않도록하는 것이 좋습니다.

XML을 구문 분석에 대한 코드는 매우 정직 :

SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 
XMLReader xmlReader = parser.getXMLReader(); 
xmlReader.setContentHandler(handler); 
StringReader reader = new StringReader(xml); 
xmlReader.parse(new InputSource(reader)); 

편집 : XML을 생성

는 다음과 같이 수행됩니다

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
mDoc = builder.newDocument(); 
mRoot = mDoc.createElement("action"); 
mDoc.appendChild(mRoot); 

TransformerFactory transFactory = TransformerFactory.newInstance(); 
Transformer trans = transFactory.newTransformer(); 
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); 
trans.setOutputProperty(OutputKeys.INDENT, "yes"); 
trans.setOutputProperty(OutputKeys.VERSION, "1.1"); 

StringWriter sw = new StringWriter(); 
StreamResult result = new StreamResult(sw); 
DOMSource source = new DOMSource(mDoc); 
trans.transform(source, result); 

return sw.toString(); 

어디 텍스트를 추가 단순히입니다 :

xml.setAttribute(SUBJECT, obj.getSubject()); 

인코딩이나 기타를 지정해야합니까?

+0

이모티콘이 들어있는 요소를 base64로 인코딩 할 수 밖에 없습니다. ASCII 제어 코드조차도 XML 텍스트와 같이 올바르지 않습니다.  Stavr00

답변

3

잘못 인코딩하고 있습니다.

XML 문자 참조 표기법이 &#NNNNN; 인 경우 N은 대리 코드 쌍으로 나뉘어 유니 코드 코드 포인트가 아니라 유니 코드 코드 포인트 여야합니다. 예 : &#x1f60e;. 귀하의 예에서 &#55357;&#56846;은 합법이 아니므로 55357 및 56846은 코드 포인트가 아니기 때문에 서로 쌍을 이루는 두 반쪽입니다.

캐릭터를 직접 표현하는 경우 정확히 무엇을하고 있는지 확신 할 수 없지만 "잘못된 UTF-16 대리모가 감지되었습니다 : d83d d83d"라는 오류 메시지는 귀하가 잘못하고있다.

"UTF-8 like smileys"라는 제목은 유니 코드와 UTF-8 사이에 혼란 스러움을 나타냅니다. 유니 코드는 스마일을 정수 코드 포인트에 매핑합니다. 첫 번째 것은 16 진수 1f60e 또는 십진수 128526입니다. UTF-8은 유니 코드를 바이트 또는 옥텟의 스트림으로 인코딩 할 수있는 방법 중 하나이며 모든 유니 코드 코드 포인트를 1에서 4 바이트의 시퀀스로 인코딩 할 수 있습니다.

UTF-16은 대부분의 유니 코드 코드 포인트를 16 비트로 나타내지 만 사로 게이트 쌍이라고하는 16 비트 값 쌍을 사용하여 xffff보다 큰 인코딩입니다. Surrogate 쌍은 UTF-8에서 사용되지 않습니다. UTF-16에서 유니 코드 코드 포인트를 서로 게이트 쌍으로 인코딩 한 다음 UTF-8에서 독립적으로이 서로 게이트 쌍을 각각 인코딩하려고 시도하는 것은 상당히 잘못되었습니다. 그러나 나는 어떻게 든 이것이 당신이하는 일이라고 생각합니다.

+0

아래쪽에 XML을 만드는 방법을 추가 했으므로 아무 것도 보이지 않습니다. –

+0

XML을 StringWriter에 문자열로 생성합니다.이 문자열은 Java 문자 시퀀스 (효과적으로 UTF-16)입니다. 그러나 우리가 보여준 XML은 UTF-8이라고 주장합니다. 어떤 시점에서 UTF-16 문자는 UTF-8 8 중창으로 바뀌 었음에 틀림 없으며 이것은 아마도 문제가있는 곳일 것입니다. –