一、问题背景
在提供接口给别人访问获取数据时,偶然看到他人不传接口指定参数,也能获得HTTP状态码200,只不过响应结果为空。这样显示是不符合逻辑的,调用者会以为调用成功,实则却并没有成功访问。
经过打断点调试,发现访问请求并没有进入该方法,并且该方法的AOP前置通知也没有进。拉下日志文件分析可看到输出了异常信息,说明进入到了全局异常捕获类,去除全局异常捕获方法,HTTP正常响应400。由此得知,全局异常捕获方法写法有误。
二、异常捕获方法
@ExceptionHandler(Exception.class)
public void handleException(Exception e) {
logger.error("---------------------- handleException start ---------------------- ");
logger.error(e.getMessage(), e);
logger.error("---------------------- handleException end ---------------------- ");
}
三、Controller代码
@GetMapping("/services/business/getInfo")
public String getBusiInfo(@RequestParam String spsxslbm) {
log.info("信息查询调用参数spsxslbm: {}", spsxslbm);
ResponseResult responseResult = new ResponseResult();
if(StringUtils.isNotBlank(spsxslbm)) {
responseResult.success(hjwsGjmService.getBusiInfo(spsxslbm));
} else {
responseResult.fail("调用参数为空,获取数据失败");
}
return JSONObject.toJSONString(responseResult);
}
四、不带参数调用
五、问题解决
上面分析到问题出现在异常捕获方法上,具体问题其实就是异常捕获方法的返回值 void ,返回 void 其实是代表自己在该方法中处理返回结果并把结果写入 Response 响应中返回。
这样也能很好的解释为什么不带参数访问响应为空了,因为捕获异常方法中,我并没有做写入 response 的操作。
@ExceptionHandler(Exception.class)
public Object handleException(Exception e) {
logger.error("---------------------- handleException start ---------------------- ");
logger.error(e.getMessage(), e);
logger.error("---------------------- handleException end ---------------------- ");
return e.getMessage();
}
问:不知道为什么此处返回的404,而不是400?
六、拓展
全局异常捕获处理方法支持的返回值类型有以下:
1、ModelAndView
2、Model
3、Map
4、View
5、String
6、@ResponseBody注解方法,设置响应内容
7、HttpEntity<?> 或者 ResponseEntity<?>:可以设置响应头和响应体内容
8、void:须将响应内容写入 response 中