ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringMVC3的ResponseBody返回字符串(JSON)乱码问题解决

2019-08-04 13:43:40  阅读:209  来源: 互联网

标签:charset return String java Charset 乱码 ResponseBody JSON import


原文链接:http://www.cnblogs.com/coprince/p/3490199.html

近日做一个小项目,用spring mvc 做到ajax请求获取jquery ztree 异步获取树返回json对象时出现了乱码,试了各种办法,查了各种资料,一开始以为是数据库的编码有问题,经测试没问题,又以为是jetty需要设置下响 应头,正在查找时突然想到可能是mvc的responseBody的问题,网上一查,果然是,用了一个设置最简单的办法,解决了问题,特将文章转贴于此, 与我一样遇到此问题的朋友们共享。

添加@RequestMapping注解,配置produces的值

@RequestMapping(value = "/add", produces = {"application/json;charset=UTF-8"})

SpringMVC3的ResponseBody返回字符串乱码问题解决

SpringMVC的@ResponseBody注解可以将请求方法返回的对象直接转换成JSON对象,但是当返回值是String的时候,中文会乱码, 原因是因为其中字符串转换和对象转换用的是两个转换器,而String的转换器中固定了转换编码为"ISO-8859-1",网上也很多种解决方法,有通 过配置Bean编码的,也有自己重写转换器的,我这里多次尝试未果,只能自己解决。

有两种解决办法:

1.返回字符串时,将字符串结果转换

return new String("你好".getBytes(), "ISO-8859-1");

2.添加@RequestMapping注解,配置produces的值

 

@RequestMapping(value = "/add", params = {"callback"}, produces = {"text/javascript;charset=UTF-8"})

 

以上提供的方法虽然需要额外配置,但相对灵活,喜欢一次性永久搞定的,还是应该考虑网上的方法,修改源码,或者替换默认的字符串转换器。

但是在使用<mvc:annotation-driven />配置的前提下,貌似网上的方法都不可靠,可能跟版本或者配置有关系 

这边提供一种修改方法,我这边使用的是3.1的mvc

1.参考网上将默认的StringHttpMessageConverter重写一遍,将其中的编码改为UTF-8

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.util.FileCopyUtils;

public class UTF8StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private final List<Charset> availableCharsets;

    private boolean writeAcceptCharset = true;

    public UTF8StringHttpMessageConverter() {
        super(new MediaType("text", "plain", DEFAULT_CHARSET), MediaType.ALL);
        this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values());
    }

    /**
     * Indicates whether the {@code Accept-Charset} should be written to any outgoing request.
     * <p>Default is {@code true}.
     */
    public void setWriteAcceptCharset(boolean writeAcceptCharset) {
        this.writeAcceptCharset = writeAcceptCharset;
    }

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

    @Override
    protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException {
        Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
        return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
    }

    @Override
    protected Long getContentLength(String s, MediaType contentType) {
        Charset charset = getContentTypeCharset(contentType);
        try {
            return (long) s.getBytes(charset.name()).length;
        }
        catch (UnsupportedEncodingException ex) {
            // should not occur
            throw new InternalError(ex.getMessage());
        }
    }

    @Override
    protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {
        if (writeAcceptCharset) {
            outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
        }
        Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
        FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset));
    }

    /**
     * Return the list of supported {@link Charset}.
     *
     * <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses.
     *
     * @return the list of accepted charsets
     */
    protected List<Charset> getAcceptedCharsets() {
        return this.availableCharsets;
    }

    private Charset getContentTypeCharset(MediaType contentType) {
        if (contentType != null && contentType.getCharSet() != null) {
            return contentType.getCharSet();
        }
        else {
            return DEFAULT_CHARSET;
        }
    }

}

2.context配置

 

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                                                          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                                                          http://www.springframework.org/schema/context 
                                                          http://www.springframework.org/schema/context/spring-context-3.1.xsd
                                                          http://www.springframework.org/schema/aop 
                                                          http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                                                          http://www.springframework.org/schema/tx 
                                                          http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                                                          http://www.springframework.org/schema/mvc 
                                                          http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
                                                          http://www.springframework.org/schema/context 
                                                          http://www.springframework.org/schema/context/spring-context-3.1.xsd">


    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="yourpackage.UTF8StringHttpMessageConverter" />
        </mvc:message-converters>
    </mvc:annotation-driven>

......
    
</beans>

 

 

 

 

转载于:https://www.cnblogs.com/coprince/p/3490199.html

标签:charset,return,String,java,Charset,乱码,ResponseBody,JSON,import
来源: https://blog.csdn.net/weixin_30859423/article/details/98463839

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有