1 背景
1.1 版本信息
- springcloud版本:Dalston.SR1
- springboot版本:1.5.3.Release
- JDK版本:1.8
1.2 缺陷描述
当我从Controller或者ControllerAdvice直接返回一个JSON字符串时,通过response.setContentType("application/json;charset=UTF-8");
失败,前端实际拿到的content-type为text/plain;charset=UTF-8
.如果前端对头部有校验的话,很可能会出现拿不到数据的情况.以下为示例代码,当调用/fail接口就可以看到结果
- 全局异常处理类
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(value = {Exception.class})
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public Object defaultHandler(HttpServletResponse response,Exception e) throws JsonProcessingException {
log.error(e.getMessage(),e);
response.setContentType("application/json;charset=UTF-8");
if(e instanceof PSQLException
|| e instanceof PersistenceException
|| e instanceof MyBatisSystemException
|| e instanceof BadSqlGrammarException){
return ResultObject.exception(1,"内部错误:数据库操作失败");
}
if(e instanceof HttpHostConnectException
|| e instanceof RetryableException){
return ResultObject.exception(1,"连接失败:请检查第三方系统接入状态");
}
return "{\n" +
" \"code\": 1,\n" +
" \"msg\": \"未知错误,请联系管理员\"\n" +
"}";
}
}
- controller层代码
@Api(value = "测试", tags = "测试")
@RequestMapping("/test")
@RestController
public class TestController {
@GetMapping(value = "/fail")
@ApiOperation("失败")
public String fail() {
int i=1/0;
return "fail";
}
}
swagger调用结果:
- 响应结果是正常的json串
- 头部信息异常
2 解决办法
目前尚未查到具体原因,但是通过设置@RequestMapping中的produces属性可以达到修改响应头的目的
3 总结
当你出现以下状况
- 响应体为正常json串
- 通过response的setHeader或者setContentType修改content-type
- 前端接收的响应头信息为:text/plain;charset=UTF-8
- controller层返回类型为String,而不是对象
那么!!可以尝试修改RequestMapping代码
@GetMapping(value = "/fail",produces="application/json;charset=UTF-8")
虽然这不是最好的办法,但是可以临时解决一下问题,与君共勉