You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制@RestController将响应体编码为指定字符集?

问题场景

我有一个@RestController,类上配置了如下@RequestMapping注解:

@RestController
@RequestMapping(consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_XML_VALUE) 

同时在方法上配置了:

@RequestMapping(value = "/api/", method = RequestMethod.POST, produces = "application/xml;charset=windows-1251")

使用Postman请求后得到的响应为<tag field="Абонент найден"/>,这本质是UTF-8编码的字节被客户端以windows-1251解码导致的乱码。

需求是:将Java中的Unicode字符串转换为windows-1251编码的字节输出,而非仅修改HTTP响应头的charset声明。


解决方案

1. 全局配置XML消息转换器编码

Spring默认的XML消息转换器(如Jaxb2RootElementHttpMessageConverter或MappingJackson2XmlHttpMessageConverter)会用UTF-8编码响应内容,需要修改其默认编码为windows-1251。创建Web配置类:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 针对JAXB处理XML的场景
        Jaxb2RootElementHttpMessageConverter xmlConverter = new Jaxb2RootElementHttpMessageConverter();
        MediaType windows1251Xml = new MediaType("application", "xml", Charset.forName("windows-1251"));
        xmlConverter.setSupportedMediaTypes(Collections.singletonList(windows1251Xml));
        converters.add(xmlConverter);

        // 若使用Jackson处理XML,替换为以下代码
        // MappingJackson2XmlHttpMessageConverter jacksonXmlConverter = new MappingJackson2XmlHttpMessageConverter();
        // jacksonXmlConverter.setDefaultCharset(Charset.forName("windows-1251"));
        // converters.add(jacksonXmlConverter);
    }
}

该配置会让所有XML响应直接以windows-1251编码生成字节,配合@RequestMapping的produces声明,客户端能正确解析。

2. 方法级手动处理响应输出

如果仅需单个接口生效,可以直接操作HttpServletResponse,手动控制编码输出:

@RequestMapping(value = "/api/", method = RequestMethod.POST)
public void handleRequest(HttpServletResponse response) throws IOException {
    // 业务逻辑生成的结果字符串(Java中为Unicode编码)
    String result = "<tag field=\"Абонент найден\"/>";

    // 设置响应头
    response.setContentType("application/xml;charset=windows-1251");
    // 将Unicode字符串转换为windows-1251字节序列并写入响应流
    response.getOutputStream().write(result.getBytes(Charset.forName("windows-1251")));
}

注意:Java字符串本身是Unicode编码,调用getBytes("windows-1251")会直接将字符映射为windows-1251对应的字节,避免了中间的UTF-8转换环节。

3. Spring Boot配置文件全局指定编码

在application.properties中添加配置,直接指定XML消息转换器的编码:

spring.http.converters.xml.charset=windows-1251
spring.http.converters.xml.enabled=true

此方式适合Spring Boot项目,无需编写配置类,简单直接。


核心原因说明

你遇到的乱码是编码不匹配导致的:Spring默认用UTF-8生成响应字节,而响应头声明windows-1251,客户端用windows-1251解码UTF-8字节,出现“乱码”。正确逻辑是直接生成windows-1251编码的字节,同时响应头声明对应charset,确保客户端解码时用相同编码。

内容的提问来源于stack exchange,提问作者Eljah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:44:49