如何强制@RestController将body编码为特定编码?

问题描述 投票:0回答:1

我有一个控制器,

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 响应的标头?

java spring encoding spring-restcontroller
1个回答
0
投票

发现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();
        }
    }

   ...
}
© www.soinside.com 2019 - 2024. All rights reserved.