`

Spring3.0 使用@ResponseBody处理json出现乱码

 
阅读更多

   本来是使用的Jackson来处理普通对象到json对象的转换工作 ,无奈在对象中的属性为空时Jackson默认是将为空的属性也转换,然后就报错。犹豫 而且当前场景无法使用Jackson自带的注解等方式排除null属性,于是乎我便痛下狠心,用json-lib自己转换直接返回json字符串。结果异常是没了,但是乱码又出现了。。。

  根据之前的经验,我发现出现的乱码都是“???”一堆的问号,直觉告诉我又是ISO8859-1在作祟。于是乎,查了查源码,果然在 StringHttpMessageConverter中发现了端倪。

public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {

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

	private final List<Charset> availableCharsets;

	private boolean writeAcceptCharset = true;

	public StringHttpMessageConverter() {
		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 {
		MediaType contentType = inputMessage.getHeaders().getContentType();
		Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
		return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset));
	}

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

	@Override
	protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException {
		if (writeAcceptCharset) {
			outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets());
		}
		MediaType contentType = outputMessage.getHeaders().getContentType();
		Charset charset = contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET;
		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;
	}

}

   (⊙o⊙)… 也不知道 为啥SpringMVC的开发者将ISO-8859-1设置为默认编码格式。得亏 SpringMVC提供了配置方式来解决这个问题。开源的东西的优势立马就体现出来了。

  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="messageConverters">  
             <list>  
                 <bean class = "org.springframework.http.converter.StringHttpMessageConverter">  
                    <property name = "supportedMediaTypes">  
                          <list>  
                              <value>text/html;charset=UTF-8</value>  
                         </list>  
                    </property>  
                 </bean>  
            </list>  
        </property>  
</bean> 

 

 看了网上不少都说必须 将以上配置放在<context:component-scan/>前面  我就有点儿丈二和尚摸不到头脑了  这都是不沾边的东西 有嘛关系吗?

 

   具体要说的话应该是跟<mvc:annotation-driven/>关系比较大 (如果你不使用这种注解方式 就更容易了) 需要我们将上面的配置放在<mvc:annotation-driven/>之前。下面是鄙人做的小测试。

/**
 * @Author: Sonicery_D
 * @Date: 2014-10-10
 */
public class ExtBeanFactoryProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
			throws BeansException {
		String[] beanNames = beanFactory.getBeanNamesForType(AnnotationMethodHandlerAdapter.class);
		for(String name : beanNames){
			System.out.println("---------------"+name+"-----start----");
			AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter)beanFactory.getBean(name);
			HttpMessageConverter<String>[] converters = (HttpMessageConverter<String>[])adapter.getMessageConverters();
			for(HttpMessageConverter<String> converter : converters){
				for(MediaType type :converter.getSupportedMediaTypes()){
					if(type==null ||type.getCharSet() == null){
						System.out.println("encoding:null");
					}else{
						System.out.println("encoding:"+type.getCharSet().name());
					}
				}
			}
			System.out.println("---------------"+name+"-----end----");
		}
	}

}

 放在<mvc:annotation-driven/>之前:

---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0-----start----
encoding:UTF-8
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0-----end----
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#1-----start----
- Hibernate Validator 4.1.0.Final
encoding:null
encoding:null
encoding:ISO-8859-1
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:UTF-8
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#1-----end----
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#2-----start----
encoding:null
encoding:null
encoding:ISO-8859-1
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#2-----end----

 放在<mvc:annotation-driven/>之后

---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0-----start----
- Hibernate Validator 4.1.0.Final
encoding:null
encoding:null
encoding:ISO-8859-1
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:UTF-8
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#0-----end----
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#1-----start----
encoding:UTF-8
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#1-----end----
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#2-----start----
encoding:null
encoding:null
encoding:ISO-8859-1
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
encoding:null
---------------org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter#2-----end----

哈哈  结果显而易见。

分享到:
评论

相关推荐

    springMVC3使用@ResponseBody向浏览器返回 json,注意区分jar包前缀

    --处理 @ResponseBody 中文乱码问题 --&gt; &lt;bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"&gt; &lt;property name="messageConverters"&gt; &lt;list&gt; &lt;!-- Support...

    SpringMVC中解决@ResponseBody注解返回中文乱码问题

    另外,还需要在项目的Maven依赖中引入Jackson库,以便Spring MVC可以使用`MappingJacksonHttpMessageConverter`处理JSON数据: ```xml &lt;groupId&gt;org.codehaus.jackson &lt;artifactId&gt;jackson-mapper-asl ...

    json 中文乱码解决方案

    在处理JSON数据时,经常会出现中文乱码的问题,尤其是在不同编码格式间进行转换时更为常见。本文将详细介绍如何解决JSON中的中文乱码问题,并提供几种简单实用的方法来帮助开发者避免这类问题的发生。 #### 一、...

    用ajax传递json到前台中文出现问号乱码问题的解决办法

    后来发现,因为在controller中返回json用了@ResponseBody,而spring源码中@ResponseBody 的实现类发现其默认的编码是 iso-8859-1,而项目用的编码为utf-8,所以传中文会出现乱码。 这里我使用了注解来解决: @...

    SSM框架整合(解决中文乱码,二级缓存,JSON,事务)

    在Controller方法中,可以使用`@ResponseBody`注解将返回值直接转化为JSON响应。 根据提供的文件名,`test.sql`可能包含一些测试用的SQL脚本,用于初始化数据库。`.png`文件可能是流程图或配置示意图,帮助理解配置...

    jackon 2.9.1

    总结来说,Jackson 2.9.1是一个用于处理JSON的Java库,常与Spring MVC结合使用,通过`@ResponseBody`注解实现将Java对象直接转换为JSON并返回给客户端。在实际应用中,需要注意依赖包的正确引入,以及处理字符集以...

    Java Web项目中Spring框架处理JSON格式数据的方法

    在Java Web项目中,Spring框架通过Spring MVC提供了一种灵活的方式来处理JSON格式的数据。...通过上述方法,可以在Java Web项目中使用Spring框架简洁高效地处理JSON格式数据,从而提高开发效率并优化用户的交互体验。

    Springmvc如何返回xml及json格式数据

    在Spring MVC中,开发Web应用时,经常需要处理XML和JSON这两种常见的数据交换格式。`@ResponseBody`注解是Spring MVC提供的一种将方法返回值直接转换为HTTP响应体内容的机制,而不需要视图解析器参与。以下是关于...

    bundery#docs#问题3

    问题POST提交乱码@ResponseBody 返回乱码解决://添加 produces = "application/json;

    spring mvc 自學筆記

    在 Spring MVC 中处理中文乱码通常有两种方法: - **设置字符编码过滤器**:通过配置一个全局的字符编码过滤器来解决所有请求的乱码问题。 ```java @WebFilter(urlPatterns = "/*") public class ...

    解决SpringMvc后台接收json数据中文乱码问题的几种方法

    当前端通过Ajax使用JSON格式向SpringMvc后台发送数据时,可能出现中文乱码。这通常是因为服务器默认的字符编码不支持UTF-8导致的。以下是两种解决方法: - 方式一:在Controller方法中手动转码 在接收到请求参数...

    Spring MVC面试宝典1.pdf

    在控制器中,可以使用@ResponseBody注解返回JSON数据给前端。 ##### 3.4 如何解决POST请求中文乱码问题,GET的又如何处理呢? - **POST请求**:在web.xml中配置过滤器CharacterEncodingFilter来设置字符编码。 - **...

    Spring MVC面试题(2022最新版)

    此外,还可以使用`@RestController`,该注解是`@Controller`和`@ResponseBody`的组合,适用于只返回JSON或XML数据而不返回视图的情况。 **@Controller注解的作用**:用于定义一个类为Spring MVC控制器,该类将处理...

    基于java反射机制的山寨版WEB2

    在"基于Java反射机制的山寨版WEB2"项目中,开发者利用这一特性创建了一个简易的Web应用程序,实现了文件上传下载、处理中文乱码、NEW和SPRING模式的支持以及JSON数据交互等功能。 1. **文件上传下载与中文乱码处理*...

    SpringMVC面试题(2024最新版).docx

    - 与AJAX交互通常通过`@ResponseBody`或JSON处理。 **处理中文乱码**: POST请求通过设置Filter解决,GET请求可以通过设置`CharacterEncodingFilter`。 **异常处理**: 可以自定义异常处理器,比如使用@...

    SpringMVC请求/响应乱码问题解决方案解析

    SpringMVC请求/响应乱码问题是指在使用SpringMVC框架进行Web开发时,请求参数或响应内容出现乱码的问题。这种问题的出现是由于字符编码的不一致所引起的。本文将详细介绍SpringMVC请求/响应乱码问题解决方案,并提供...

    Springmvc完成ajax功能实例详解

    Jackson是Java中广泛使用的JSON处理库,它允许我们将Java对象序列化为JSON字符串,反之亦然。确保在项目中添加Jackson的依赖,例如`jackson-databind`,以便能够进行JSON转换。 在Spring MVC中,使用`@ResponseBody...

    Spring MVC 关于controller的字符编码问题

    在处理这些参数时,Spring MVC会自动进行编码和解码,但需要注意的是,如果你在请求体中使用非英文字符,确保客户端和服务器都使用一致的字符集,否则仍然可能出现编码问题。 总结来说,Spring MVC中处理Controller...

    Bootstrap分页

    //处理乱码 Map, Object&gt; map = new HashMap, Object&gt;(); username=(username==null)?"":username; map.put("username", username);//username必须要和ibatis配置的property=username一致 Integer ...

Global site tag (gtag.js) - Google Analytics