Если какой -либо друг -программист сказал, что он не столкнулся с проблемой искаженного кода Китая, я бы не хотел в это верить. Сегодня, когда я делал умный ответ на подписку WeChat, я запутался в огненной яме с искаженным кодом Китая. Когда я впервые решил проблему, я приветствовал и полностью забыла боль, которую она когда -то принесла мне.
1. Описание проблемы
Видя, что искаженные коды в красной рамке были голых, но я был беспомощным. Это было так плохо.
2. Ищите решение
Столкнувшись с проблемой, вы можете заставлять себя только решить ее ножом. Что вы можете сделать?
Прежде всего, мы должны понять механизм интеллектуального ответа WeChat и нарисовать картину следующим образом:
PS, пожалуйста, извиняйтесь за то, что не использовали инструменты.
Далее, давайте сосредоточимся на ключевых моментах и посмотрим, где важен искаженный код.
1. Контроллер возвращается к пользователю
response.setheader ("content-type", "text/html; charset = utf-8"); // браузер.Только этот код, метод кодирования для определения ответа, является UTF-8. Логично, что искаженная проблема должна была улучшить, но результат все еще нет.
2. Jaxb 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); // Удалить заголовок сообщения BytearrayOutputStream OS = new BytearRayOutputStream (); Xmlserializer serializer = getXmlSerializer (OS); М.Маршал (obj, serializer.ascontenthandler ()); result = os.toString ("UTF-8"); } catch (Exception e) {e.printstackTrace (); } logger.info ("Text:" + Result); return Result;} private xmlSerializer getXmlSerializer (outputStream OS) {outputFormat of = new outputFormat (); formatcdatatag (); of.setcdatelements (cdatanode); of.setpreservespace (true); of.setindenting (true); of.setomitxmldeclaration (true); of.setencoding ("UTF-8"); Xmlserializer serializer = new XmlSerializer (OF); serializer.setOutputByteStream (OS); вернуть сериализатор;} Вот три ключевых момента:
1. M.SetProperty (Marshaller.jaxb_encoding, "UTF-8");
2. getxmlserializer (OS)
3. Os.ToString ("UTF-8");
Вы можете видеть, что вышеупомянутые три места включают транскодирование. Во -первых, установите кодирование маршаллера; Во -вторых, установите весь кодирование XMLSerializer; На третьем месте установите строку, кодирующую возвращаемого BytearrayOutputStream. Все три необходимы.
На этот раз это должно было решить проблему, но решение все еще находится в китайском искаженном. Так что мне делать?
3. Среда вывода Tomcat неверна
В ответ на этот момент кто -то онлайн предоставляет такое решение.
Установить java_opts =% java_opts% logging_manager% -dfile.encoding = utf -8
После настройки перезагрузки Tomcat проблема в том, что его можно решить, но побочный эффект заключается в том, что весь Tomcat запускает вывод на сервере (окно CMD Tomcat) всегда был искажен, и я думаю, что это решение не рекомендуется.
Добавьте следующий код в начальную войну
System.getProperty ("file.encoding");Вы будете удивлены, обнаружив, что работающая среда Tomcat (Window Server 2008) оказалась GBK. Интересно, не удивлены ли вы. Я был напуган, почему это не UTF-8? Если это GBK, я добавлю больше страниц UTF-8 к двум вышеуказанным шагам, и я не понимаю.
3. Решить проблему
С приведенным выше опытом мы изменяем следующий код WeChat4J, в основном второй точку.
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 кодирование" + кодирование + "System File.encoding" + System.getProperty ("file.encoding")); M.SetProperty (marshaller.jaxb_encoding, кодирование); M.SetProperty (marshaller.jaxb_formatted_output, true); M.SetProperty (marshaller.jaxb_fragment, true); // Удалить заголовок сообщения BytearrayOutputStream OS = new BytearRayOutputStream (); Xmlserializer serializer = getXmlSerializer (OS); М.Маршал (obj, serializer.ascontenthandler ()); result = os.toString (кодирование); } catch (Exception e) {e.printstackTrace (); } logger.info ("Text:" + Result); return Result;} private xmlSerializer getXmlSerializer (outputStream OS) {outputFormat of = new outputFormat (); formatcdatatag (); of.setcdatelements (cdatanode); of.setpreservespace (true); of.setindenting (true); of.setomitxmldeclaration (true); String encoding = config.instance (). GetJaxb_encoding (); of.setencoding (кодирование); Xmlserializer serializer = new XmlSerializer (OF); serializer.setOutputByteStream (OS); вернуть сериализатор;}Среди этих двух методов мы добавляем настраиваемый метод кодирования для автоматического установки GBK (GBK настроен на моем сервере), GB2312 и UTF-8.
Таким образом, вы обнаружите, что фоновый выход WeChat4J больше не в китайском искаженном виде, но информация, возвращаемая пользователю, еще более грязная.
Как это можно сделать? Я программист, и я действительно хочу поклясться несколько ругательства. Но не бойтесь. Поскольку журнал регистрации WeChat4J больше не в китайском искаженном виде, можно только сказать, что на первом этапе есть еще одна проблема.
Регулировать
response.setheader ("content-type", "text/html; charset = utf-8"); // browser кодирование response.getOutputStream (). write (result.getBytes ("utf-8")); Обратите внимание, что это не может быть GBK, это может быть только UTF-8. Я сказал, что не знаю, почему, менеджер по продукту WeChat дал объяснение.
Ключевым моментом является то, что JaxB и ответ совместно разрешают искаженные коды WeChat4J китайские коды следующим образом:
WeChatController.java - это URL, который вы выделили на платформу общественного развития WeChat. Ответ корректируется следующим образом
response.setheader ("content-type", "text/html; charset = utf-8"); // browser кодирование response.getOutputStream (). write (result.getBytes ("utf-8"));WeChat4j's jaxbparser.java, отрегулируйте методы Toxml (Object obj) и GetXmlSerializer (Outsstream OS) соответственно:
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" + кодирование + "System File.encoding" + System.getProperty ("file.coding")); M.SetProperty (marshaller.jaxb_encoding, кодирование); M.SetProperty (marshaller.jaxb_formatted_output, true); M.SetProperty (marshaller.jaxb_fragment, true); // Удалить заголовок сообщения BytearrayOutputStream OS = new BytearRayOutputStream (); Xmlserializer serializer = getXmlSerializer (OS); М.Маршал (obj, serializer.ascontenthandler ()); result = os.toString (кодирование); } catch (Exception e) {e.printstackTrace (); } logger.info ("Text:" + Result); return Result;} private xmlSerializer getXmlSerializer (outputStream OS) {outputFormat of = new outputFormat (); formatcdatatag (); of.setcdatelements (cdatanode); of.setpreservespace (true); of.setindenting (true); of.setomitxmldeclaration (true); String encoding = config.instance (). GetJaxb_encoding (); // gbk of.setencoding (кодирование); Xmlserializer serializer = new XmlSerializer (OF); serializer.setOutputByteStream (OS); вернуть сериализатор;} Хорошо, все идет хорошо.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.