If any programmer friend said that he had not encountered the problem of Chinese garbled code, I would not want to believe it. Today, when I was making smart reply to the WeChat subscription account, I jumped into the fire pit of Chinese garbled code in a confused way. When I first solved the problem, I cheered and completely forgot the pain she once brought to me.
1. Problem description
Seeing that, the garbled codes in the red frame were nakedly provoking me, but I was helpless. It was so bad.
2. Seek a solution
When facing a problem, you can only force yourself to solve it with a knife. What can you do?
First of all, we must understand the mechanism of WeChat intelligent reply, and draw the picture as follows:
ps, please apologize for not using the tools well.
Next, let’s focus on the key points and see where the garbled code is important.
1. Controller returns to the user
response.setHeader("content-type", "text/html;charset=UTF-8");// Browser encoding response.getOutputStream().write(result.getBytes());Just this code, the encoding method of specifying the response is UTF-8. It is logical that the garbled problem should have improved, but the result is still not.
2.JAXB's toXML
public String toXML(Object 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);// Remove the message header ByteArrayOutputStream os = new ByteArrayOutputStream(); XMLSerializer serializer = getXMLSerializer(os); m.marshal(obj, serializer.asContentHandler()); result = os.toString("UTF-8"); } catch (Exception e) { e.printStackTrace(); } logger.info("response text:" + result); return result;}private XMLSerializer getXMLSerializer(OutputStream os) { OutputFormat of = new OutputFormat(); formatCDataTag(); of.setCDataElements(cdataNode); of.setPreserveSpace(true); of.setIndenting(true); of.setOmitXMLDeclaration(true); of.setEncoding("UTF-8"); XMLSerializer serializer = new XMLSerializer(of); serializer.setOutputByteStream(os); return serializer;} Here are three key points:
1. m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
2. getXMLSerializer(os)
3. os.toString("UTF-8");
You can see that the above three places involve transcoding. In the first place, set the Marshaller encoding; in the second place, set the entire XMLSerializer encoding; in the third place, set the string encoding of the returned ByteArrayOutputStream. All three are indispensable.
This time, it should have solved the problem, but the solution is still in Chinese garbled. So what should I do?
3. Tomcat's output environment is wrong
In response to this point, someone online provides such a solution.
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER% -Dfile.encoding=UTF-8
After setting up, restarting tomcat, the problem is that it can be solved, but the side effect is that the entire tomcat runs the output on the server (tomcat's cmd window) has always been garbled, and I think this solution is not advisable.
Add the following code to the running war
System.getProperty("file.encoding");You will be surprised to find that the running environment of tomcat (window server 2008) turned out to be GBK. I wonder if you are not surprised. I was scared, why is it not UTF-8? If it is GBK, I will add more UTF-8 pages to the above two steps, and I don’t understand.
3. Solve the problem
With the above experience, we modify the following wechat4j code, mainly the second point.
public String toXML(Object obj) { String result = null; try { JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller m = context.createMarshaller(); String encoding = Config.instance().getJaxb_encoding(); logger.debug("toXML encoding " + encoding + "System file.encoding " + System.getProperty("file.encoding")); m.setProperty(Marshaller.JAXB_ENCODING, encoding); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); m.setProperty(Marshaller.JAXB_FRAGMENT, true);// Remove the message header ByteArrayOutputStream os = new ByteArrayOutputStream(); XMLSerializer serializer = getXMLSerializer(os); m.marshal(obj, serializer.asContentHandler()); result = os.toString(encoding); } catch (Exception e) { e.printStackTrace(); } logger.info("response text:" + result); return result;}private XMLSerializer getXMLSerializer(OutputStream os) { OutputFormat of = new OutputFormat(); formatCDataTag(); of.setCDataElements(cdataNode); of.setPreserveSpace(true); of.setIndenting(true); of.setOmitXMLDeclaration(true); String encoding = Config.instance().getJaxb_encoding(); of.setEncoding(encoding); XMLSerializer serializer = new XMLSerializer(of); serializer.setOutputByteStream(os); return serializer;}Among these two methods, we add a configurable encoding method to automatically set GBK (GBK is configured on my server), GB2312, and UTF-8.
In this way, you will find that the background output of wechat4j is no longer in Chinese garbled, but the information returned to the user is even more messy.
How can this be done? I am a programmer and I really want to swear a few swear words. But don't be afraid. Since wechat4j's logger log is no longer in Chinese garbled, it can only be said that there is another problem in the first stage.
Adjust
response.setHeader("content-type", "text/html;charset=UTF-8");// Browser encoding response.getOutputStream().write(result.getBytes("UTF-8")); Note that this cannot be GBK, it can only be UTF-8. I said I don’t know why, WeChat’s product manager gave an explanation.
The key point is that JAXB and response jointly resolve wechat4j Chinese garbled codes are declared as follows:
WeChatController.Java is the URL you allocated to the WeChat public development platform. The response is adjusted as follows
response.setHeader("content-type", "text/html;charset=UTF-8");// Browser encoding response.getOutputStream().write(result.getBytes("UTF-8"));Wechat4j's JaxbParser.java, adjust the toXML (Object obj) and getXMLSerializer (OutputStream os) methods respectively:
public String toXML(Object obj) { String result = null; try { JAXBContext context = JAXBContext.newInstance(obj.getClass()); Marshaller m = context.createMarshaller(); String encoding = Config.instance().getJaxb_encoding();// GBK logger.debug("toXML encoding " + encoding + "System file.encoding " + System.getProperty("file.encoding")); m.setProperty(Marshaller.JAXB_ENCODING, encoding); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); m.setProperty(Marshaller.JAXB_FRAGMENT, true);// Remove the message header ByteArrayOutputStream os = new ByteArrayOutputStream(); XMLSerializer serializer = getXMLSerializer(os); m.marshal(obj, serializer.asContentHandler()); result = os.toString(encoding); } catch (Exception e) { e.printStackTrace(); } logger.info("response text:" + result); return result;}private XMLSerializer getXMLSerializer(OutputStream os) { OutputFormat of = new OutputFormat(); formatCDataTag(); of.setCDataElements(cdataNode); of.setPreserveSpace(true); of.setIndenting(true); of.setOmitXMLDeclaration(true); String encoding = Config.instance().getJaxb_encoding();//GBK of.setEncoding(encoding); XMLSerializer serializer = new XMLSerializer(of); serializer.setOutputByteStream(os); return serializer;} OK, everything is going well.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.