相关文章推荐
礼貌的凳子  ·  unity3D ...·  1 年前    · 
乖乖的手术刀  ·  json schema oneof-掘金·  1 年前    · 

SpringMVC中Controller处理response.setContentType()及header为"application/json;charset=utf-8"无效问题分析

一. 异常问题

我在SpringMVC中创建了一个处理器Controller,处理器方法内部利用response对象设置content-type,内容类型设置为“application/json;charset=UTF-8”,在该方法对外输出中文时,结果发现还是乱码。代码如下:

    @ResponseBody
    @RequestMapping(value = "/error",method = RequestMethod.GET)
    public String showError(HttpServletResponse response) throws IOException {
        //专门用来处理通过注解方式实现的处理器的!
        //RequestMappingHandlerMapping
        //RequestMappingHandlerAdapter--->invokeHandlerMethod()
        response.setContentType("application/json;charset=UTF-8");
        return "失败";

结果在请求时,发现依然乱码:

二. 原因分析

后来经过追踪源码,发现是因为SpringMVC源码内部做了特殊处理,导致通过response.setContentType("application/json;charset=UTF-8")方法设置请求头编码无效。

SpringMVC中是通过RequestMappingHandlerAdapter来处理通过注解方式定义的请求处理器方法的,然后在该类中,有一个invokeHandlerMethod()方法,内部通过ServletInvocableHandlerMethod中的invokeAndHandle调用目标方法,并处理返回值。

如果return value != null,则通过returnvalueHandlers来处理,内部会调用MessageConverter转换成相应的报文格式。

HttpOutputMessage中的outputMessage,对应的实例是 org.springframework.http.server.ServletServerHttpResponse。在写入数据的同时,会设置response的header,包括content-type(根据RequestMapping 的 produces 属性 计算出来)。也就是说,当请求方法在带有返回值的情况下,在controller中设置content-type是无效的,会被消息转换器覆盖掉。

三.解决办法

1.解决方式一,利用produces属性

    @ResponseBody
    //@GetMapping("/show")
    @RequestMapping(value = "/show",method = RequestMethod.GET,produces = {"application/json;charset=UTF-8"})
    public String showCharacter(){
        return "成功";

2. 解决方式二,请求方法不要带返回值

    @ResponseBody
    @RequestMapping(value = "/error",method = RequestMethod.GET)
    public void showError(HttpServletResponse response) throws IOException {
        //专门用来处理通过注解方式实现的处理器的!
        //RequestMappingHandlerMapping
        //RequestMappingHandlerAdapter--->invokeHandlerMethod()
        //AbstractHttpMessageConverter
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream out = response.getOutputStream();
        IOUtils.write("失败".getBytes("UTF-8"),out);
        //IOUtils.write("失败",out);
        out.flush();
        //return "失败";
                    SpringMVC中Controller处理response.setContentType()及header为"application/json;charset=utf-8"无效问题分析一. 异常问题我在SpringMVC中创建了一个处理器Controller,处理器方法内部利用response对象设置content-type,内容类型设置为“application/json;charset=UTF-8”,在该方法对外输出中文时,结果发现还是乱码。代码如下:    @ResponseBody
    使用服务器端控制AJAX页面缓存:
        response.setHeader( "Pragma", "no-cache" );
        response.addHeader( "Cache-Control", "must-revalidate" );
        response.addHeader( "Cache-Control", 
				
首先是我确认了response.setContentType("application/json;charset=utf-8")是设置正确了,因为我是从我的另外一个复制过来的,复制过来就没生效 代码如下: 找不到头绪,看了一下前端请求头信息: 确定是response.setContentType("application/json;charset=utf-8")没有生效,代码是没有错...
String authorization = request.getHeader("Authorization"); 在拦截器获取header的Authorization 为空,但postman测试正常 前端报跨域错误,controller已经配置了@CrossOrigin. 项目采用前后端分离,服务器端添加了全局的跨域配置,但是却出现了跨域问题分析了多次请求发现有一部分请求并没... 使用Spring Boot开发项目的过程,难免会遇到向响应头写入一些信息,例如更新了的token,用户详情等信息。在请求头添加,请求时就可以通过过滤器,拦截器等验证或者获得请求头传递的信息。但是如果使用@RestController注解,在过滤器、拦截器修改响应头是无效的。那么怎么解决呢? 话不多说,直接上代码,以在响应头添加token为例 @ControllerAdvice public class HeaderModifierAdvice implements Response
1、一秒刷新页面一次 response.setHeader("refresh","1"); 2、二秒跳到其他页面 response.setHeader("refresh","2;URL=otherPagename"); 3、没有缓存: response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Contro
解决方法一: 在RequestMapping里设置 produces = { “application/json;charset=UTF-8” }: 但是麻烦,每个controller都要写一次。 @ResponseBody @RequestMapping(value = "/get", produces = "application/json; charset=utf-8") 解决方法二:
response.setContentType(MIME)的作用是使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。 例如web浏览器就是通过MIME类型来判断文件是GIF图片。通过MIME类型来处理json字符串。 Tomcat的安装目录\conf\web.xml 就定义了大量MIME类型 ,可以参考。 response.setC
response.getOutputStream().write(b); response.setHeader("Content-Type","application/gzip"); response.setHe...
Controller方法的返回值可以有以下几种: 1、返回ModelAndView 返回ModelAndView时最常见的一种返回结果。需要在方法结束的时候定义一个ModelAndView对象,并对Model和View分别进行设置。 2、返回String 1):字符串代表逻辑视图名 真实的访问路径=“前缀”+逻辑视图名+“后缀” 注意:如果返回的String代表逻辑视图名的话,那么Mo
内容类型,客户端通过Content-Type设置,对应Controller的consumes配置@RestController public class ConsumersController { /**客户端发送json数据 * "firstName":"yi", * "lastName":"cj" // Content-Typeapplication/json,接收json类型的请求 @GetMa.
如下图注释代理设置内的这俩类似的不要手动设置 add_header Cache-Control no-cache; 这样会被nginx覆盖,也就是会在你的后面加上这句,也就是重复的一个头,会以最后一次为准语法:expires [time|@time-of-day|epoch|max|off] 默认值:expires off 使用字段:http, server, location 这个指令控制是否在应答标记一个过期时间,如果是,如何标记。 ·off 将禁止修改头部的 Expires和Cache-Contr
由于 StringHttpMessageConverter 类,默认采用的字符集是 ISO-8859-1 package org.springframework.http.converter; public class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> { private static final MediaType APPLICATION_PLUS_JSON = new
public String test(HttpServletRequest request, HttpServletResponse response) { response.setContentType("application/pdf"); return "true"; 问题:spring架构使用response.setContentType不...
解决WARN Establishing SSL connection without servers identity verification is not recommended问题 26073