springmvc学习笔记--REST API的异常处理
前言:
最近使用springmvc写了不少rest api, 觉得真是一个好框架. 之前描述的几篇关于rest api的文章, 其实还是不够完善. 比如当遇到参数缺失, 类型不匹配的情况时, 直接抛出异常, 返回的内容是400+的错误页面, 而不是json内容, 这让移动端的调用方很难处理.
本文主要讲述对于rest api, springmvc对异常的解决处理方案.
系列整理:
springmvc学习笔记系列的文章目录:
• idea创建springmvc项目
• 面向移动端的REST API
• Jackson的使用和定制
REST API的设计原则博文
• 移动互联网实战—Web Restful API设计和基础架构
场景构造:
大背景, 我们已借助使用Jackson框架和注解@ResonseBody来实现pojo对象以json形式返回.
先来构造几个案例, 来描述我们所要解决的问题.
共同的测试代码:
@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+的错误页面.
解决方案:
基于上文的场景, 遇到异常时, 返回的都是400+/500+的错误页面, 一方面客户端sdk解析和处理麻烦, 另一方面泄露了内部的错误细节. 那是否一种办法拦截异常, 并返回自己定义的错误数据格式呢?
答案是肯定的, springmvc引入了织入@ControlAdvice.
其对异常的处理, 非常的方便, 可简单参考如下sample.
@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的入门和上手确实非常快, 但要真正的理解. 确实还是需要花功夫, 这边只是简单介绍一下, 并没有深入源码. 希望将来有一天有机会讲讲背后的技术原理.
公众号&游戏站点:
个人微信公众号: 木目的H5游戏世界

个人游戏作品集站点, www.mmxfgame.com, 请点击访问: http://120.26.221.54/.
springmvc学习笔记--REST API的异常处理的更多相关文章
- springmvc学习笔记---面向移动端支持REST API
前言: springmvc对注解的支持非常灵活和飘逸, 也得web编程少了以往很大一坨配置项. 另一方面移动互联网的到来, 使得REST API变得流行, 甚至成为主流. 因此我们来关注下spring ...
- 史上最全的SpringMVC学习笔记
SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于Spring ...
- SpringMVC:学习笔记(8)——文件上传
SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...
- springmvc学习笔记(简介及使用)
springmvc学习笔记(简介及使用) 工作之余, 回顾了一下springmvc的相关内容, 这次也为后面复习什么的做个标记, 也希望能与大家交流学习, 通过回帖留言等方式表达自己的观点或学习心得. ...
- springmvc学习笔记(常用注解)
springmvc学习笔记(常用注解) 1. @Controller @Controller注解用于表示一个类的实例是页面控制器(后面都将称为控制器). 使用@Controller注解定义的控制器有如 ...
- SpringMVC学习笔记之二(SpringMVC高级参数绑定)
一.高级参数绑定 1.1 绑定数组 需求:在商品列表页面选中多个商品,然后删除. 需求分析:功能要求商品列表页面中的每个商品前有一个checkbok,选中多个商品后点击删除按钮把商品id传递给Cont ...
- springmvc学习笔记(19)-RESTful支持
springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...
- springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定
springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定 标签: springmvc springmvc学习笔记13-springmvc注解开发之集合类型參数绑定 数组绑定 需 ...
- springMVC 学习笔记(一):springMVC 入门
springMVC 学习笔记(一):spring 入门 什么是 springMVC springMVC 是 spring 框架的一个模块,springMVC 和 spring 无需通过中间整合层进行整 ...
随机推荐
- 利用Nginx+Mono+Fastcgi代替IIS对Asp.Net进行反向代理
Nginx的好处相信我不必多说了,它作为一个相当轻量级的开源Web 服务器以及反向代理服务器而深受欢迎.越来越多的公司已经对它产生兴趣,包括我们公司的许多部门,利用它进行负载均衡和资源管理,之前写过一 ...
- android webview 漏洞背后的节操
by superhei 2013/09/06 [注:本文提到的都是我个人的观点,该行为也是私人行为,与任何组织.公司无关.另:水军请自重!] 一.前言 这两天,一个2+年前的android web ...
- hdu 4627 The Unsolvable Problem
http://acm.hdu.edu.cn/showproblem.php?pid=4627 分类讨论一下就可以 代码: #include<iostream> #include<cs ...
- Android在Eclipse上的环境配置
哈哈,首先转一个:https://my.oschina.net/fusxian/blog/293935 谢谢分享者 1.android SDK安装出现Failed to fetch URL http: ...
- ROS主题发布订阅控制真实的机器人下位机
先模拟控制小乌龟 新建cmd_node.ccpp文件: #include"ros/ros.h" #include"geometry_msgs/Twist.h" ...
- arm-linux-gcc-4.3.2安装步骤
安装交叉编译工具链: 1.首先以root用户登入 2.复制arm-linux-gcc-4.3.2.tgz到根目录下tmp文件夹里 3.解压命令tar xvzf arm-linux-gcc-4. ...
- redis OK
http://redis.readthedocs.org/en/2.4/set.html1, client.end();redis.expire(key,10) ,lsize,llen APPEND ...
- 【Noip2012】解题报告【字符】【贪心】【高精度】【倍增】【set】
目录:1:vigenere密码[字符]2:国王游戏[贪心][高精度]3:开车旅行[倍增][set] 题目: VJ P1778 vigenere密码 Accepted 标签:NOIP提高组2012 ...
- java基础之类与继承 详解
Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相关知 ...
- goldengate 12c对teradata的支持
OGG12c在2014.4.24发布了对TD的最新支持版本,软件可在此下载:https://edelivery.oracle.com.新版本特性如下: 当前支持TD 14.1的捕获和交付,仍然基于Te ...