Wenn ein Programmierer Freund sagte, dass er nicht auf das Problem des chinesischen verstümmelten Code gestoßen war, möchte ich es nicht glauben. Als ich heute auf das WeChat -Abonnement -Konto intelligent antwortete, sprang ich auf verwirrte Weise in die Feuerstelle des chinesischen verstümmelten Code. Als ich das Problem zum ersten Mal löste, jubelte ich und vergaß völlig den Schmerz, den sie mir einst mitbrachte.
1. Problembeschreibung
Als die verstümmelten Codes im roten Rahmen nackt nackt provozierten, provozierte ich nackt, aber ich war hilflos. Es war so schlimm.
2. Suchen Sie eine Lösung
Wenn Sie sich einem Problem stellen, können Sie sich nur zwingen, es mit einem Messer zu lösen. Was kannst du tun?
Zunächst müssen wir den Mechanismus der intelligenten Antwort von WeChat verstehen und das Bild wie folgt zeichnen:
PS, bitte entschuldigen Sie, dass Sie die Tools nicht gut verwendet haben.
Konzentrieren wir uns als nächstes auf die wichtigsten Punkte und sehen, wo der verstümmelte Code wichtig ist.
1. Controller kehrt zum Benutzer zurück
response.setheader ("content-type", "text/html; charset = utf-8"); // Browser codierung responseNur dieser Code ist die Codierungsmethode zur Angabe der Antwort UTF-8. Es ist logisch, dass sich das verstümmelte Problem hätte verbesserten müssen, aber das Ergebnis ist immer noch nicht.
2.JAXBs Toxml
public String toxml (Objekt obj) {String result = null; try {jaxbContext context = jaxbContext.newinstance (obj.getClass ()); Marshaller m = context.createMarshaller (); M.SetProperty (Marshaller.jaxb_encoding, "UTF-8"); M.SetProperty (Marshaller.jaxb_Formatted_output, true); M.SetProperty (Marshaller.jaxb_Fragment, true); // Entfernen Sie den Nachrichtenheader BytearrayoutputStream os = new bytearrayoutputStream (); XMLSerializer serializer = getXmlSerializer (OS); m.marshal (obj, serializer.ascontentHandler ()); result = os.toString ("utf-8"); } catch (Ausnahme e) {e.printstacktrace (); } logger.info ("Antworttext:" + Ergebnis); Rückgabeergebnis;} privater XMLSerializer getXmlSerializer (outputStream os) {outputFormat von = new OutputFormat (); formatcdataGag (); von.setcdataelements (cdatanode); von.setpreservespace (true); von.setIndenting (wahr); von.setomitxmldeClaration (true); Of.Setencoding ("UTF-8"); XMLSerializer Serializer = neuer XMLSerializer (von); serializer.SetoutputByTestream (OS); Serializer zurückgeben;} Hier sind drei wichtige Punkte:
1. M.SetProperty (Marshaller.jaxb_encoding, "UTF-8");
2. GetxMlSerializer (Betriebssystem)
3.. Os.ToString ("UTF-8");
Sie können sehen, dass die oben genannten drei Orte Transcodierung beinhalten. Setzen Sie in erster Linie die Marshaller -Codierung; Stellen Sie an zweiter Stelle die gesamte XMLSerializer -Codierung ein. Setzen Sie an dritten Stelle die Zeichenfolgecodierung des zurückgegebenen BytearrayoutputStream. Alle drei sind unverzichtbar.
Dieses Mal hätte es das Problem lösen sollen, aber die Lösung ist immer noch in chinesischen verstümmelten. Also, was soll ich tun?
3.. Tomcats Ausgangsumgebung ist falsch
Als Antwort auf diesen Punkt bietet jemand online eine solche Lösung.
Setzen Sie java_opts =% java_opts%% Logging_Manager% -dfile.encoding = utf -8
Nach dem Einrichten und Neustart von Tomcat ist das Problem, dass es gelöst werden kann. Der Nebeneffekt besteht jedoch darin, dass der gesamte Tomcat die Ausgabe auf dem Server (Tomcat -CMD -Fenster) immer verstümmelt, und ich denke, diese Lösung ist nicht ratsam.
Fügen Sie dem laufenden Krieg den folgenden Code hinzu
System.getProperty ("Datei.encoding");Sie werden überrascht sein, dass sich die laufende Umgebung von Tomcat (Window Server 2008) als GBK herausstellte. Ich frage mich, ob Sie nicht überrascht sind. Ich hatte Angst, warum ist es nicht UTF-8? Wenn es sich um GBK handelt, werde ich den oben genannten zwei Schritten weitere UTF-8-Seiten hinzufügen, und ich verstehe nicht.
3. Lösen Sie das Problem
Mit der obigen Erfahrung ändern wir den folgenden Wechat4J -Code, hauptsächlich den zweiten Punkt.
public String toxml (Objekt obj) {String result = null; try {jaxbContext context = jaxbContext.newinstance (obj.getClass ()); Marshaller m = context.createMarshaller (); String coding = config.instance (). GetJaxb_encoding (); logger.debug ("toxml coding" + coding + "systemdatei.encoding" + system.getProperty ("file.encoding")); M.SetProperty (Marshaller.jaxb_encoding, Codierung); M.SetProperty (Marshaller.jaxb_Formatted_output, true); M.SetProperty (Marshaller.jaxb_Fragment, true); // Entfernen Sie den Nachrichtenheader BytearrayoutputStream os = new bytearrayoutputStream (); XMLSerializer serializer = getXmlSerializer (OS); m.marshal (obj, serializer.ascontentHandler ()); result = os.toString (codieren); } catch (Ausnahme e) {e.printstacktrace (); } logger.info ("Antworttext:" + Ergebnis); Rückgabeergebnis;} privater XMLSerializer getXmlSerializer (outputStream os) {outputFormat von = new OutputFormat (); formatcdataGag (); von.setcdataelements (cdatanode); von.setpreservespace (true); von.setIndenting (wahr); von.setomitxmldeClaration (true); String coding = config.instance (). GetJaxb_encoding (); of.setencoding (codieren); XMLSerializer Serializer = neuer XMLSerializer (von); serializer.SetoutputByTestream (OS); Serializer zurückgeben;}Unter diesen beiden Methoden fügen wir eine konfigurierbare Codierungsmethode zum automatischen Setzen von GBK hinzu (GBK ist auf meinem Server konfiguriert), GB2312 und UTF-8.
Auf diese Weise werden Sie feststellen, dass die Hintergrundausgabe von WeChat4J nicht mehr in chinesischen verstümmelt ist, aber die an den Benutzer zurückgegebenen Informationen sind noch chaotischer.
Wie kann das getan werden? Ich bin ein Programmierer und möchte wirklich ein paar schwörende Worte schwören. Aber haben Sie keine Angst. Da das Logger -Protokoll von Wechat4J nicht mehr in chinesischen verstümmelten chinesisch ist, kann nur gesagt werden, dass es in der ersten Stufe ein weiteres Problem gibt.
Anpassen
response.setheader ("content-type", "text/html; charset = utf-8"); // Browser codierung response Beachten Sie, dass dies nicht GBK sein kann, es kann nur UTF-8 sein. Ich sagte, ich weiß nicht warum, der Produktmanager von Wechats gab eine Erklärung ab.
Der entscheidende Punkt ist, dass JAXB und Reaktion Wechat4J chinesische verstümmelte Codes gemeinsam wie folgt deklariert werden:
WechatController.java ist die URL, die Sie der WeChat Public Development Platform zugewiesen haben. Die Antwort wird wie folgt angepasst
response.setheader ("content-type", "text/html; charset = utf-8"); // Browser codierung responseWechat4Js jaxbparser.java, passen Sie die Methoden ToxML (Object OBJ) und GETXMLSerializer (OutputStream OS) an:
public String toxml (Objekt obj) {String result = null; try {jaxbContext context = jaxbContext.newinstance (obj.getClass ()); Marshaller m = context.createMarshaller (); String coding = config.instance (). GetJaxb_encoding (); // gbk logger.debug ("toxml codieren" + codieren + "Systemdatei.Coding" + System.getProperty ("Datei.encoding"); M.SetProperty (Marshaller.jaxb_encoding, Codierung); M.SetProperty (Marshaller.jaxb_Formatted_output, true); M.SetProperty (Marshaller.jaxb_Fragment, true); // Entfernen Sie den Nachrichtenheader BytearrayoutputStream os = new bytearrayoutputStream (); XMLSerializer serializer = getXmlSerializer (OS); m.marshal (obj, serializer.ascontentHandler ()); result = os.toString (codieren); } catch (Ausnahme e) {e.printstacktrace (); } logger.info ("Antworttext:" + Ergebnis); Rückgabeergebnis;} privater XMLSerializer getXmlSerializer (outputStream os) {outputFormat von = new OutputFormat (); formatcdataGag (); von.setcdataelements (cdatanode); von.setpreservespace (true); von.setIndenting (wahr); von.setomitxmldeClaration (true); String coding = config.instance (). GetJaxb_encoding (); // gbk von.setencoding (codieren); XMLSerializer Serializer = neuer XMLSerializer (von); serializer.SetoutputByTestream (OS); Serializer zurückgeben;} Ok, alles läuft gut.
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Lernen aller hilfreich sein und ich hoffe, jeder wird Wulin.com mehr unterstützen.