Si algún amigo programador dijo que no había encontrado el problema del código confuso chino, no me gustaría creerlo. Hoy, cuando estaba haciendo una respuesta inteligente a la cuenta de suscripción de WeChat, salté al pozo de fuego del código confuso chino de una manera confusa. Cuando resolví el problema por primera vez, animé y olvidé por completo el dolor que una vez me trajo.
1. Descripción del problema
Al ver eso, los códigos confusos en el marco rojo me estaban provocando, pero estaba indefenso. Fue tan malo.
2. Busque una solución
Al enfrentar un problema, solo puede forzarlo a resolverlo con un cuchillo. ¿Qué puedes hacer?
En primer lugar, debemos entender el mecanismo de WeChat Intelligent Responder y dibujar la imagen de la siguiente manera:
PD, por favor, disculpe por no usar bien las herramientas.
A continuación, centrémonos en los puntos clave y veamos dónde es importante el código confuso.
1. El controlador regresa al usuario
Response.setheader ("Content-type", "Text/html; charset = utf-8"); // browser encoding respuesta.getOutputStream (). Write (result.getBytes ());Solo este código, el método de codificación para especificar la respuesta es UTF-8. Es lógico que el problema confuso haya mejorado, pero el resultado aún no lo es.
2.Jaxb's toxml
public String tOxml (object obj) {string result = null; intente {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); // Eliminar el encabezado del mensaje bytearRayOutputPutStream OS = new ByteArRayOutputStream (); XMLSerializer Serializer = getXMLSerializer (OS); M.Marshal (OBJ, Serializer.AsContentHandler ()); result = OS.ToString ("UTF-8"); } catch (Exception e) {E.PrintStackTrace (); } logger.info ("Texto de respuesta:" + resultado); Resultado de retorno;} private xmlSerializer getXMLSerializer (OutputStream OS) {outputFormat of = new OutputFormat (); formatcdatatag (); de.setCDataelements (Cdatanode); of.setPreserveSpace (verdadero); de.setIndenting (verdadero); de.setomitxmlDeclaration (verdadero); of.setEncoding ("UTF-8"); XMLSerializer Serializer = nuevo XMLSerializer (OF); Serializer.setOutputByTream (OS); Return Serializer;} Aquí hay tres puntos clave:
1. M.SetProperty (Marshaller.jaxb_encoding, "UTF-8");
2. GetXMLSerializer (OS)
3. OS.ToString ("UTF-8");
Puede ver que los tres lugares anteriores implican la transcodificación. En primer lugar, coloque la codificación de Marshaller; En segundo lugar, establezca toda la codificación XMLSerializer; En el tercer lugar, establezca la codificación de cadena del bytearRayOutputStream devuelto. Los tres son indispensables.
Esta vez, debería haber resuelto el problema, pero la solución aún está en chino confusión. Entonces, ¿qué debo hacer?
3. El entorno de salida de Tomcat es incorrecto
En respuesta a este punto, alguien en línea proporciona dicha solución.
Establecer java_opts =% java_opts%% logging_manager% -dfile.encoding = UTF -8
Después de configurar, reiniciar Tomcat, el problema es que se puede resolver, pero el efecto secundario es que todo Tomcat ejecuta la salida en el servidor (la ventana CMD de Tomcat) siempre ha sido confusa, y creo que esta solución no es aconsejable.
Agregue el siguiente código a la guerra en ejecución
System.getProperty ("File.Encoding");Se sorprenderá al descubrir que el entorno en ejecución de Tomcat (Window Server 2008) resultó ser GBK. Me pregunto si no te sorprende. Tenía miedo, ¿por qué no es UTF-8? Si es GBK, agregaré más páginas UTF-8 a los dos pasos anteriores, y no entiendo.
3. Resuelve el problema
Con la experiencia anterior, modificamos el siguiente código WECHAT4J, principalmente el segundo punto.
public String tOxml (object obj) {string result = null; intente {jaxbContext context = jaxbContext.newinStance (obj.getClass ()); Marshaller M = context.CreateMarShaller (); String coding = config.instance (). GetJaxb_encoding (); logger.debug ("toxml codificación" + codificación + "archivo del sistema.Encoding" + System.getProperty ("File.Encoding")); M.SetProperty (Marshaller.jaxb_encoding, codificación); M.SetProperty (Marshaller.jaxb_formatted_output, true); M.SetProperty (marshaller.jaxb_fragment, true); // Eliminar el encabezado del mensaje bytearRayOutputPutStream OS = new ByteArRayOutputStream (); XMLSerializer Serializer = getXMLSerializer (OS); M.Marshal (OBJ, Serializer.AsContentHandler ()); result = OS.ToString (codificación); } catch (Exception e) {E.PrintStackTrace (); } logger.info ("Texto de respuesta:" + resultado); Resultado de retorno;} private xmlSerializer getXMLSerializer (OutputStream OS) {outputFormat of = new OutputFormat (); formatcdatatag (); de.setCDataelements (Cdatanode); of.setPreserveSpace (verdadero); de.setIndenting (verdadero); de.setomitxmlDeclaration (verdadero); String coding = config.instance (). GetJaxb_encoding (); de.setEncoding (codificación); XMLSerializer Serializer = nuevo XMLSerializer (OF); Serializer.setOutputByTream (OS); Return Serializer;}Entre estos dos métodos, agregamos un método de codificación configurable para configurar automáticamente GBK (GBK está configurado en mi servidor), GB2312 y UTF-8.
De esta manera, encontrará que la salida de fondo de WeChat4j ya no está en chino confusión, pero la información devuelta al usuario es aún más complicada.
¿Cómo se puede hacer esto? Soy un programador y realmente quiero jurar algunas malas palabras. Pero no tengas miedo. Dado que el registro de registro de WeChat4J ya no está en chino confusión, solo se puede decir que hay otro problema en la primera etapa.
Ajustar
respuesta.setheader ("Content-type", "text/html; charset = utf-8"); // browser codificando respuesta.getOutputStream (). Write (result.getBytes ("UTF-8")); Tenga en cuenta que esto no puede ser GBK, solo puede ser UTF-8. Dije que no sé por qué, el gerente de productos de WeChat dio una explicación.
El punto clave es que Jaxb y la respuesta resuelven conjuntamente los códigos confusos chinos de WeChat4j se declaran de la siguiente manera:
WeChatController.java es la URL que asignó a la plataforma de desarrollo público de WeChat. La respuesta se ajusta de la siguiente manera
respuesta.setheader ("Content-type", "text/html; charset = utf-8"); // browser codificando respuesta.getOutputStream (). Write (result.getBytes ("UTF-8"));Jaxbparser.java de WeChat4J, ajuste los métodos TOXML (object obj) y getXMLSerializer (OutputStream OS) respectivamente:
public String tOxml (object obj) {string result = null; intente {jaxbContext context = jaxbContext.newinStance (obj.getClass ()); Marshaller M = context.CreateMarShaller (); String encoding = config.instance (). GetJaxb_encoding (); // gbk logger.debug ("toxml codificación" + codificación + "archivo del sistema.encoding" + system.getproperty ("file.encoding")); M.SetProperty (Marshaller.jaxb_encoding, codificación); M.SetProperty (Marshaller.jaxb_formatted_output, true); M.SetProperty (marshaller.jaxb_fragment, true); // Eliminar el encabezado del mensaje bytearRayOutputPutStream OS = new ByteArRayOutputStream (); XMLSerializer Serializer = getXMLSerializer (OS); M.Marshal (OBJ, Serializer.AsContentHandler ()); result = OS.ToString (codificación); } catch (Exception e) {E.PrintStackTrace (); } logger.info ("Texto de respuesta:" + resultado); Resultado de retorno;} private xmlSerializer getXMLSerializer (OutputStream OS) {outputFormat of = new OutputFormat (); formatcdatatag (); de.setCDataelements (Cdatanode); of.setPreserveSpace (verdadero); de.setIndenting (verdadero); de.setomitxmlDeclaration (verdadero); String coding = config.instance (). GetJaxb_encoding (); // gbk of.setEncoding (codificación); XMLSerializer Serializer = nuevo XMLSerializer (OF); Serializer.setOutputByTream (OS); Return Serializer;} Ok, todo va bien.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.