前言:
  最近使用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的异常处理的更多相关文章

  1. springmvc学习笔记---面向移动端支持REST API

    前言: springmvc对注解的支持非常灵活和飘逸, 也得web编程少了以往很大一坨配置项. 另一方面移动互联网的到来, 使得REST API变得流行, 甚至成为主流. 因此我们来关注下spring ...

  2. 史上最全的SpringMVC学习笔记

    SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于Spring ...

  3. SpringMVC:学习笔记(8)——文件上传

    SpringMVC--文件上传 说明: 文件上传的途径 文件上传主要有两种方式: 1.使用Apache Commons FileUpload元件. 2.利用Servlet3.0及其更高版本的内置支持. ...

  4. springmvc学习笔记(简介及使用)

    springmvc学习笔记(简介及使用) 工作之余, 回顾了一下springmvc的相关内容, 这次也为后面复习什么的做个标记, 也希望能与大家交流学习, 通过回帖留言等方式表达自己的观点或学习心得. ...

  5. springmvc学习笔记(常用注解)

    springmvc学习笔记(常用注解) 1. @Controller @Controller注解用于表示一个类的实例是页面控制器(后面都将称为控制器). 使用@Controller注解定义的控制器有如 ...

  6. SpringMVC学习笔记之二(SpringMVC高级参数绑定)

    一.高级参数绑定 1.1 绑定数组 需求:在商品列表页面选中多个商品,然后删除. 需求分析:功能要求商品列表页面中的每个商品前有一个checkbok,选中多个商品后点击删除按钮把商品id传递给Cont ...

  7. springmvc学习笔记(19)-RESTful支持

    springmvc学习笔记(19)-RESTful支持 标签: springmvc springmvc学习笔记19-RESTful支持 概念 REST的样例 controller REST方法的前端控 ...

  8. springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定

    springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定 标签: springmvc springmvc学习笔记13-springmvc注解开发之集合类型參数绑定 数组绑定 需 ...

  9. springMVC 学习笔记(一):springMVC 入门

    springMVC 学习笔记(一):spring 入门 什么是 springMVC springMVC 是 spring 框架的一个模块,springMVC 和 spring 无需通过中间整合层进行整 ...

随机推荐

  1. Junit4的简单使用

    junit4的简单使用 测试套件的使用 测试类1 package com.westward; import static org.junit.Assert.*; import org.junit.Te ...

  2. Android Phonebook编写联系人UI加载及联系人保存流程(四)

    2014-01-07 10:23:22 将百度空间里的东西移过来. 5. KindSectionView KindSectionView是何方神圣呢?它又是怎么怎么和一个DataKind,以及一个Ra ...

  3. 数据结构-bubble sort

    #gcc version 4.5.3 (GCC) #include <iostream> #include <algorithm> template <typename ...

  4. 常见的Web负载均衡方法

    用户手动选择 通过在主站首页入口提供不同线路,不同服务器链接的方式,来实现负载均衡.在一些提供下载业务的网站中比较常见,如:华军软件园. DNS轮询 大多域名注册商都支持对同一主机名添加多条A记录,这 ...

  5. web安全 -- 常见攻击方法及预防措施

    一.sql注入 sql注入,是指攻击者在猜测出服务器上要执行sql后:通过输入数据,拼接原来要执行的sql而形成新的sql:从而到达改变原来查询的意义的目的. -- 原来sql select xxx ...

  6. VS2010下配置OCI编程

    OCI是Oracle官方出品的用于C/C++语言连接.操作Oracle数据库的API.在windows操作系统下使用VS等IDE编写.编译C++程序十分方便.简单,不需要使用Makefile.使用OC ...

  7. 【转】CentOS yum安装和卸载软件的使用方法

    在CentOS yum安装和卸载软件的使用方法安装方法安装一个软件时.   CentOS yum -y install httpd安装多个相类似的软件时   CentOS yum -y install ...

  8. 数据库范式(1NF 2NF 3NF BCNF)详解一

    数据结构设计模式编程制造 数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的.结构明晰的,同时,不会发生插入(insert).删除(delete)和更新(update)操作异常 ...

  9. PAT 10-0 说反话

    我写了两种实现方法,其中第二种是参考Yomman园友的(http://www.cnblogs.com/yomman/p/4271949.html).我的方法(方法一)是用一个数组存放输入的字符串,另一 ...

  10. hadoop环境搭建遇到问题集锦

    1  在hadoop的bin目录下, 运行hadoop version命令,提示“hadoop:没有此命令” 解决办法: ./hadoop version或者$HADOOP_HOME/bin放在PAT ...