SpringMVC 数据json字符串(String)响应乱码问题

在我们解决问题前,先来查看这样一张图 

由此可知SpringMVC接收和响应数据时都会经过HttpMessageConverter接口类

而我们的问题是响应json字符串(String),那么自然会调用HttpMessageConverter的某一实现类来完成相关数据的编码转换。

可以发现在org.springframework.http.converter.StringHttpMessageConverter是实现此过程的实现类。因此我们如要解决乱码问题需要从此处下手。

解决方案1

public static final Charset DEFAULT_CHARSET = Charset.forName("ISO-8859-1");

我们发现StringHttpMessageConverter类里面默认编码是ISO-8859-1,所以我们在返回json串时会乱码,因此我们可以重写一个类继承自StringHttpMessageConverter,重写其内部方法,并且设置默认编码为UTF-8

public class UTF8StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private volatile List<Charset> availableCharsets;
    private boolean writeAcceptCharset;

    public UTF8StringHttpMessageConverter() {
        this(DEFAULT_CHARSET);
    }

    public UTF8StringHttpMessageConverter(Charset defaultCharset) {
        super(defaultCharset, new MediaType[]{MediaType.TEXT_PLAIN, MediaType.ALL});
        this.writeAcceptCharset = true;
    }

    public void setWriteAcceptCharset(boolean writeAcceptCharset) {
        this.writeAcceptCharset = writeAcceptCharset;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return String.class == clazz;
    }

    @Override
    protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
        Charset charset = this.getContentTypeCharset(inputMessage.getHeaders().getContentType());
        return StreamUtils.copyToString(inputMessage.getBody(), charset);
    }

    @Override
    protected Long getContentLength(String str, MediaType contentType) {
        Charset charset = this.getContentTypeCharset(contentType);

        try {
            return (long)str.getBytes(charset.name()).length;
        } catch (UnsupportedEncodingException var5) {
            throw new IllegalStateException(var5);
        }
    }

    @Override
    protected void writeInternal(String str, HttpOutputMessage outputMessage) throws IOException {
        if (this.writeAcceptCharset) {
            outputMessage.getHeaders().setAcceptCharset(this.getAcceptedCharsets());
        }

        Charset charset = this.getContentTypeCharset(outputMessage.getHeaders().getContentType());
        StreamUtils.copy(str, charset, outputMessage.getBody());
    }

    protected List<Charset> getAcceptedCharsets() {
        if (this.availableCharsets == null) {
            this.availableCharsets = new ArrayList(Charset.availableCharsets().values());
        }

        return this.availableCharsets;
    }

    private Charset getContentTypeCharset(MediaType contentType) {
        return contentType != null && contentType.getCharset() != null ? contentType.getCharset() : this.getDefaultCharset();
    }
}

然后只需要将该类,注册到Spring的annotaion 处理序列中即可,下次SpringMVC返回json数据时会自动调用用户自定义的converter

<mvc:annotation-driven>
      <mvc:message-converters register-defaults="true">
            <bean class="com.javazhan.controller.UTF8StringHttpMessageConverter"/>
      </mvc:message-converters>
</mvc:annotation-driven>

解决方案2

对springMVC框架内默认的Converter进行重新配置,配置其对于UTF-8等编码的支持

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.StringHttpMessageConverter">
            <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=UTF-8</value>
                    <value>application/json;charset=UTF-8</value>
                    <value>text/plain;charset=UTF-8</value>
                    <value>application/xml;charset=UTF-8</value>
                </list>
            </property>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

解决方案3

使用produces属性

在RequestMapping使用(produces = “text/html; charset=utf-8”)produces 作用根据请求头中的Accept进行匹配,如请求头“Accept:text/html”时即可匹配。

如果类型是:application/json ,设置为:produces = “application/json; charset=utf-8”


解决方案4

在以前学servlet过程中,记得是可以设置响应的数据编码格式的,这样也可以完成乱码问题的解决

    response.setContentType("text/html;charset=utf-8");
    PrintWriter out=response.getWriter();
    out.println(data.toString());
    out.flush();
    out.close();

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值