JAXB 와 response 를 위 한 인 코딩 을 설정 하여 wechat4j 중국어 난 장 판 문 제 를 해결 합 니 다.

만약 프로그래머 가 된 동료 가 자신 이 중국어 난 장 판 에 부 딪 히 지 않 았 다 고 말한다 면 나 는 믿 고 싶 지 않다.오늘 은 위 챗 구독 번호 의 스마트 답장 을 하 다가 중국어 난 코드 라 는 불구 덩이 에 얼떨결에 뛰 어 들 었 다.문 제 를 막 해 결 했 을 때,모두 환호 하 며 껑 충 껑 충 뛰 었 는데,그녀 가 일찍이 나 에 게 준 고통 을 완전히 잊 어 버 렸 다.
문제 설명
这里写图片描述
보 셨 습 니까?빨 간 테두리 안의 난 장 판 은 적나라 하 게 나 에 게 도발 을 했 지만 나 는 어 쩔 수 없 었 습 니 다.정말 엉망 이 었 습 니 다.
2.해결 의 길 찾기
문제 에 직면 하면 칼 을 들 고 스스로 해결 하 라 고 강요 해 야 지,어 쩌 겠 어?
먼저,위 챗 스마트 답장 의 체 제 를 파악 해 야 한다.그림 은 다음 과 같다.

ps.도 구 를 잘 사용 하지 못 한 점 양해 바 랍 니 다.
이어서 우 리 는 코드 가 어떤 위치 에서 발생 하 는 지 에 중점 을 두 었 다.
1.controller 사용자 에 게 되 돌려 주기

response.setHeader("content-type", "text/html;charset=UTF-8");//      
response.getOutputStream().write(result.getBytes());
이 코드 에 대해 response 를 지정 하 는 인 코딩 방식 은 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);

    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;
}

여기에 세 가지 중요 한 점 이 있다.
1. m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
2. getXMLSerializer(os)
3. os.toString("UTF-8");
상기 세 곳 은 모두 코드 를 바 꾸 고 첫 번 째 곳 은 Marshaller 의 인 코딩 을 설정 하 는 것 을 볼 수 있 습 니 다.두 번 째,전체 XMLserializer 의 인 코딩 을 설정 합 니 다.세 번 째,되 돌아 오 는 ByteArray OutputStream 의 string 인 코딩 을 설정 합 니 다.세 군데 에 하나 가 없어 서 는 안 된다.
이번에 이렇게 투철 하 니 문 제 를 해 결 했 겠 지.하지만 여전히 중국어 난 장 판 을 해결 하면 어 떡 하지?
3.tomcat 의 출력 환경 이 이상 하 다.
이 점 에 대해 인터넷 에서 이런 해결 방향 을 제공 하 는 사람 이 있다.
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER% -Dfile.encoding=UTF-8
설정 후 tomcat 를 다시 시작 합 니 다.문 제 는 해결 할 수 있 지만 부작용 은 전체 tomcat 가 서버 에서 출력(tomcat 의 cmd 창)을 실행 하 는 것 입 니 다.이 방안 은 바람 직 하지 않다 고 생각 합 니 다.
실행 중인 war 에 다음 코드 를 추가 합 니 다.

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 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);//      

    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;
}

이 두 가지 방법 중,encoding 에 설정 가능 한 인 코딩 방식 을 추가 하면 GBK(내 서버 에 GBK 가 설정 되 어 있 음),GB 2312,UTF-8 을 수 동 으로 설정 할 수 있 습 니 다.
이렇게 하면 wechat4j 의 배경 출력 은 더 이상 중국어 코드 가 아 닌 것 을 발견 할 수 있 지만 사용자 에 게 되 돌아 오 는 정 보 는 더욱 복잡 해 집 니 다.
这里写图片描述
어떻게 이 럴 수가 있어,이 프로그래머 를 놀 리 다 니,정말 욕 을 몇 마디 하고 싶 구나.하지만 겁 먹 지 마 세 요.wechat4j 의 logger 로 그 는 더 이상 중국어 로 어 지 럽 히 지 않 으 니 첫 번 째 부분 에 또 문제 가 생 겼 다 고 할 수 밖 에 없습니다.
조정 하 잖 아.

response.setHeader("content-type", "text/html;charset=UTF-8");//      
response.getOutputStream().write(result.getBytes("UTF-8"));
주의 하 세 요.여 기 는 GBK 가 아니 라 UTF-8 밖 에 안 됩 니 다.왜 그런 지 잘 모 르 겠 습 니 다.위 챗 의 제품 매니저 가 설명 해 드 리 겠 습 니 다.
중점,JAXB 와 response 가 합작 하여 wechat4j 중국어 난 장 판 을 해결 하 는 방법 은 다음 과 같다.
WeChatController.Java 는 위 챗 대중 개발 플랫폼 에 배 치 된 URL 입 니 다.response 는 다음 과 같이 조정 합 니 다.

response.setHeader("content-type", "text/html;charset=UTF-8");//      
response.getOutputStream().write(result.getBytes("UTF-8"));
wechat4j 의 JaxbParser.java 는 toXML(Object obj)과 getXMLserializer(OutputStream 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 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);//      

    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;
}

됐어,만사 가 다 잘 됐어.
这里写图片描述
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기