前言:
最近使用springmvc写了很多rest api, 以为真是一个好框架. 以前描述的几篇关于rest api的文章, 其实仍是不够完善. 好比当遇到参数缺失, 类型不匹配的状况时, 直接抛出异常, 返回的内容是400+的错误页面, 而不是json内容, 这让移动端的调用方很难处理.
本文主要讲述对于rest api, springmvc对异常的解决处理方案.html
系列整理:
springmvc学习笔记系列的文章目录:
• idea建立springmvc项目
• 面向移动端的REST API
• Jackson的使用和定制
REST API的设计原则博文
• 移动互联网实战—Web Restful API设计和基础架构java
场景构造:
大背景, 咱们已借助使用Jackson框架和注解@ResonseBody来实现pojo对象以json形式返回.
先来构造几个案例, 来描述咱们所要解决的问题.
共同的测试代码:spring
@Controller @RequestMapping("/math") public class TestController { @RequestMapping(value="/div", method= RequestMethod.GET) @ResponseBody public int div(@RequestParam("a") int a, @RequestParam("b") int b) { // *) div zero error return a / b; } }
1). 场景一(参数缺失, 类型不匹配)
case 1:
http://localhost:8080/math/div?a=10
参数b缺失, 返回400错误页
case 2:
http://localhost:8080/math/div?a=10&b=hehe
参数b类型不对, 类型转换失败
咱们的但愿是, 将这些参数缺乏/类型不匹配的异常, 以JSON串的形式返回, 而不是以400的错误页面返回.
2). 场景二(业务代码抛出异常)
case 1:
http://localhost:8080/math/div/a=10&b=0
发生除零异常
内部抛出业务异常很是常见, 防不胜防, 返回是500+的错误页面.json
解决方案:
基于上文的场景, 遇到异常时, 返回的都是400+/500+的错误页面, 一方面客户端sdk解析和处理麻烦, 另外一方面泄露了内部的错误细节. 那是否一种办法拦截异常, 并返回本身定义的错误数据格式呢?
答案是确定的, springmvc引入了织入@ControlAdvice.
其对异常的处理, 很是的方便, 可简单参考以下sample.api
@ControllerAdvice public class RestApiControlAdvice { @ExceptionHandler(value=RuntimeException.class) @ResponseBody public String handle(RuntimeException e) { // *记入异常日志 return e.getMessage(); } @ExceptionHandler(value=Exception.class) @ResponseBody public String handle(Exception e) { // *记入异常日志 return e.getMessage(); } }
经过结合注解@ExceptionHanlder, 来定义具体的异常处理, 以及返回的结果.
这边须要注意的是, @ExceptionHandler可定义多个, 当多个匹配时, 按编写最先的处理函数优先处理. 这边就像try/catch那种常见的状况了, 既顺序敏感. 最佳实践, 须要把处于顶层的异常类搁置到代码最尾端.
固然对于参数缺失/类型不匹配的处理, 能够以下定义.微信
@ExceptionHandler(value=MissingServletRequestParameterException.class) @ResponseBody public TResult<Void> handle(MissingServletRequestParameterException e) { return "Miss parameter " + e.getParameterName() + ":" + e.getParameterType(); } @ExceptionHandler(value= TypeMismatchException.class) @ResponseBody public String handle(TypeMismatchException e) { return e.getErrorCode() + ", required type: " + e.getRequiredType() + ", but value: " + e.getValue(); }
业务上的异常代码, 每每能够抽象出一个异常基类.架构
总结:
springmvc的入门和上手确实很是快, 但要真正的理解. 确实仍是须要花功夫, 这边只是简单介绍一下, 并无深刻源码. 但愿未来有一天有机会讲讲背后的技术原理.mvc
公众号&游戏站点:
我的微信公众号: 木目的H5游戏世界
我的游戏做品集站点, www.mmxfgame.com, 请点击访问: http://120.26.221.54/. app