我有一个控制器,
produces
设置为
@RestController
@RequestMapping(consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE)
通过 RestController
@RequestMapping(value = "/api/", method = RequestMethod.POST, produces = "application/xml;charset=windows-1251")
使用 POSTman,我得到类似
<tag field="Абонент найден"/>
的响应,看起来像是 UTF-8 字节被解码为 windows-1251,然后刷新到 HTTP 响应。
但事实上,我只需要具有相同字符的 UTF-8 字符串,但只是采用 windows-1251 编码。我应该在正文中更改什么,以使其符合我期望的编码,而不仅仅是更改 HTTP 响应的标头?
发现XML在接受端被强制重新编码为windows-1251:
@Override
public T handleResponse(HttpResponse response) throws IOException {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() != 200) {
LOGGER.error("Status code: " + statusLine.getStatusCode());
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
// only for logging
String xml = IOUtils.toString(entity.getContent(), "windows-1251");
entity.getContent().close();
if (responseClass == GetUIProvidersResponse.class) {
LOGGER.info("Logging for getUIProviders is disabled");
} else {
LOGGER.info(xml);
}
return xmlMapper.readValue(xml, responseClass);
}
为了使响应在真正的 windows-1251 中编码,我必须更新
DispatcherServlet
扩展名:
public class LoggableDispatcherServlet extends DispatcherServlet {
private static final Logger logger = LoggerFactory.getLogger(LoggableDispatcherServlet.class);
public LoggableDispatcherServlet(WebApplicationContext webApplicationContext) {
super(webApplicationContext);
}
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (!(request instanceof ContentCachingRequestWrapper)) {
request = new ContentCachingRequestWrapper(request);
}
if (!(response instanceof ContentCachingResponseWrapper)) {
response = new ContentCachingResponseWrapper(response);
}
HandlerExecutionChain handler = getHandler(request);
try {
super.doDispatch(request, response);
} finally {
log(request, response, handler);
updateResponse(response);
}
}
....
private void updateResponse(HttpServletResponse response) throws IOException {
ContentCachingResponseWrapper responseWrapper =
WebUtils.getNativeResponse(response, ContentCachingResponseWrapper.class);
String encoding = responseWrapper.getCharacterEncoding();
if (encoding.equals("windows-1251")) {
String responseString = new String(responseWrapper.getContentAsByteArray(),"UTF-8");
responseWrapper.resetBuffer();
responseWrapper.getOutputStream().write(responseString.getBytes("windows-1251"));
responseWrapper.copyBodyToResponse();
} else {
responseWrapper.copyBodyToResponse();
}
}
...
}