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;
}
됐어,만사 가 다 잘 됐어.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Linux 에서 난 코드 파일 삭제파일 이름 이 어 지 러 울 때 키 보드 를 통 해 파일 이름 을 입력 할 수 없 기 때문에 터미널 에서 rm, mv 등 명령 으로 파일 을 직접 관리 할 수 없습니다. 그러나 우 리 는 모든 파일 에 i 노드 번호...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.