Se algum amigo programador dissesse que não encontrou o problema do código chinês ilegal, eu não gostaria de acreditar. Hoje, quando eu estava dando uma resposta inteligente à conta de assinatura do WeChat, entrei na fogueira do código ilegal chinês de uma maneira confusa. Quando resolvi o problema pela primeira vez, aplaudi e esqueci completamente a dor que ela uma vez me trouxe.
1. Descrição do problema
Vendo isso, os códigos iluminados no quadro vermelho estavam me provocando nu, mas eu estava impotente. Foi tão ruim.
2. Procure uma solução
Ao enfrentar um problema, você só pode se forçar a resolvê -lo com uma faca. O que você pode fazer?
Primeiro de tudo, devemos entender o mecanismo da resposta inteligente do WeChat e desenhar o quadro da seguinte forma:
PS, por favor, peça desculpas por não usar bem as ferramentas.
Em seguida, vamos nos concentrar nos pontos -chave e ver onde o código iluminado é importante.
1. O controlador retorna ao usuário
Response.setheader ("content-type", "text/html; charset = utf-8"); // navegador de codificação Response.getOutputStream (). write (resultado.getBytes ());Apenas esse código, o método de codificação de especificar a resposta é UTF-8. É lógico que o problema de iluminação tenha melhorado, mas o resultado ainda não é.
2.Jaxb's toxml
public String toxml (object obj) {string resultado = null; tente {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); // Remova o cabeçalho da mensagem bytearrayOutputStream OS = new ByteArrayOutputStream (); XMLSerializer serializador = getxmlSerializer (OS); M.Marshal (OBJ, serializer.ascontentHandler ()); resultado = os.toString ("UTF-8"); } catch (Exceção e) {e.printStackTrace (); } logger.info ("Texto da resposta:" + resultado); resultado de retorno;} private xmlSerializer getxmlSerializer (OUTUTPLETREAM) {outputFormat de = new O outputFormat (); formatcdatatag (); de.SetcDataElements (CDATANODE); de.setPreserveSpace (true); de.setindenting (true); de.SetomitxMldClaration (true); de.setEncoding ("UTF-8"); XMLSerializer serializador = novo XMLSerializer (de); serializer.setOutputByTestream (OS); retornar serializador;} Aqui estão três pontos -chave:
1.
2. GetxmlSerializer (OS)
3. OS.ToString ("UTF-8");
Você pode ver que os três lugares acima envolvem transcodificação. Em primeiro lugar, defina a codificação do Marshaller; Em segundo lugar, defina toda a codificação XMLSerializer; Em terceiro lugar, defina a codificação da string do retorno bytearTrayOutputStream. Todos os três são indispensáveis.
Desta vez, deveria ter resolvido o problema, mas a solução ainda está em chinês iluminada. Então, o que devo fazer?
3. O ambiente de saída do Tomcat está errado
Em resposta a esse ponto, alguém online fornece essa solução.
Definir java_OPTS =% java_OPTS% Logging_Manager% -dfile.encoding = UTF -8
Depois de configurar, reiniciar o Tomcat, o problema é que ele pode ser resolvido, mas o efeito colateral é que todo o Tomcat executa a saída no servidor (a janela CMD do Tomcat) sempre foi distorcida e acho que essa solução não é aconselhável.
Adicione o seguinte código à guerra em execução
System.getProperty ("file.encoding");Você ficará surpreso ao descobrir que o ambiente de corrida do TomCat (Window Server 2008) acabou sendo GBK. Eu me pergunto se você não está surpreso. Eu estava com medo, por que não é UTF-8? Se for GBK, adicionarei mais páginas UTF-8 às duas etapas acima, e não entendo.
3. Resolva o problema
Com a experiência acima, modificamos o seguinte código WECHAT4J, principalmente o segundo ponto.
public String toxml (object obj) {string resultado = null; tente {JaxbContext context = JaxbContext.NewInstance (obj.getClass ()); Marshaller m = context.createmarshaller (); String coding = config.instance (). Getjaxb_encoding (); logger.debug ("toxml coding" + coding + "system file.encoding" + system.getProperty ("file.encoding")); M.SetProperty (marshaller.jaxb_encoding, codificação); M.SetProperty (marshaller.jaxb_formatted_output, true); M.SetProperty (marshaller.jaxb_fragment, true); // Remova o cabeçalho da mensagem bytearrayOutputStream OS = new ByteArrayOutputStream (); XMLSerializer serializador = getxmlSerializer (OS); M.Marshal (OBJ, serializer.ascontentHandler ()); resultado = os.toString (codificação); } catch (Exceção e) {e.printStackTrace (); } logger.info ("Texto da resposta:" + resultado); resultado de retorno;} private xmlSerializer getxmlSerializer (OUTUTPLETREAM) {outputFormat de = new O outputFormat (); formatcdatatag (); de.SetcDataElements (CDATANODE); de.setPreserveSpace (true); de.setindenting (true); de.SetomitxMldClaration (true); String coding = config.instance (). Getjaxb_encoding (); de.setEncoding (codificação); XMLSerializer serializador = novo XMLSerializer (de); serializer.setOutputByTestream (OS); retornar serializador;}Entre esses dois métodos, adicionamos um método de codificação configurável para definir automaticamente GBK (GBK está configurado no meu servidor), GB2312 e UTF-8.
Dessa forma, você descobrirá que a saída de fundo do WECHAT4J não está mais em chinês iluminada, mas as informações retornadas ao usuário são ainda mais confusas.
Como isso pode ser feito? Sou um programador e realmente quero jurar algumas palavras. Mas não tenha medo. Como o registro do Logger do WeChat4J não está mais em chinês iluminado, só pode -se dizer que há outro problema no primeiro estágio.
Ajustar
Response.setheader ("content-type", "text/html; charset = utf-8"); // navegador de codificação Response.getOutputStream (). write (resultado.getBytes ("utf-8")); Observe que isso não pode ser GBK, só pode ser UTF-8. Eu disse que não sei por que, o gerente de produtos da WeChat deu uma explicação.
O ponto principal é que o JAXB e a resposta resolvem conjuntamente os códigos chineses de WeChat4j são declarados da seguinte forma:
WeChatcontroller.java é o URL que você alocou para a plataforma de desenvolvimento público do WeChat. A resposta é ajustada da seguinte forma
Response.setheader ("content-type", "text/html; charset = utf-8"); // navegador de codificação Response.getOutputStream (). write (resultado.getBytes ("utf-8"));Os métodos Jaxbparser.java do WeChat4j, ajuste os métodos TOXML (Object OBJ) e GetxmlSerializer (OUTUTREMSTREAM), respectivamente:
public String toxml (object obj) {string resultado = null; tente {JaxbContext context = JaxbContext.NewInstance (obj.getClass ()); Marshaller m = context.createmarshaller (); String coding = config.instance (). Getjaxb_encoding (); // gbk logger.debug ("toxml coding" + coding + "system file.encoding" + system.getProperty ("file.encoding"); M.SetProperty (marshaller.jaxb_encoding, codificação); M.SetProperty (marshaller.jaxb_formatted_output, true); M.SetProperty (marshaller.jaxb_fragment, true); // Remova o cabeçalho da mensagem bytearrayOutputStream OS = new ByteArrayOutputStream (); XMLSerializer serializador = getxmlSerializer (OS); M.Marshal (OBJ, serializer.ascontentHandler ()); resultado = os.toString (codificação); } catch (Exceção e) {e.printStackTrace (); } logger.info ("Texto da resposta:" + resultado); resultado de retorno;} private xmlSerializer getxmlSerializer (OUTUTPLETREAM) {outputFormat de = new O outputFormat (); formatcdatatag (); de.SetcDataElements (CDATANODE); de.setPreserveSpace (true); de.setindenting (true); de.SetomitxMldClaration (true); String coding = config.instance (). Getjaxb_encoding (); // gbk de.setEncoding (codificação); XMLSerializer serializador = novo XMLSerializer (de); serializer.setOutputByTestream (OS); retornar serializador;} OK, tudo está indo bem.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.