文档章节

MVC——统一报文格式的异常处理响应

alexzhu592
 alexzhu592
发布于 06/20 23:38
字数 1046
阅读 10
收藏 19
点赞 0
评论 0

 

    在我们写controller层的时候,常常会有这样的困惑,如果需要返回一个数据是,可能为了统一回去构造一个类似下列的数据格式:

{
  status:true,
  msg:"保存成功!",
  data:[]
}

    而且在写的时候,可能中间会有很多异常情况处理,需要一直写这样格式的返回数据,能不能统一处理,写controller层的时候,只关心怎么data数据要怎么写,至于其他的自动处理掉呢,spring 3.2的时候提供了一个注解@ControllerAdvice 和 @ExceptionHandler顾名思义就是控制增强和异常处理器,在拦截器层面把返回的报文统一,同时可以对异常情况的报文进行规范。

    在网上找到一段一个大神写的,异常处理的例子,首先定义了一个常用的异常状态工具类:

package com.drskj.apiservice.common.utils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;import com.google.common.collect.Maps;
//格式化返回客户端数据格式(json)
public class ReturnFormat {
    private static Map<String,String>messageMap = Maps.newHashMap();
    //初始化状态码与文字说明
    static {
        messageMap.put("0", "");

        messageMap.put("400", "Bad Request!");
        messageMap.put("401", "NotAuthorization");
        messageMap.put("405", "Method Not Allowed");
        messageMap.put("406", "Not Acceptable");
        messageMap.put("500", "Internal Server Error");

        messageMap.put("1000", "[服务器]运行时异常");
        messageMap.put("1001", "[服务器]空值异常");
        messageMap.put("1002", "[服务器]数据类型转换异常");
        messageMap.put("1003", "[服务器]IO异常");
        messageMap.put("1004", "[服务器]未知方法异常");
        messageMap.put("1005", "[服务器]数组越界异常");
        messageMap.put("1006", "[服务器]网络异常");
    }
    public static String retParam(int status,Object data) {
        OutputJson json = new OutputJson(status, messageMap.get(String.valueOf(status)), data);
        return json.toString();
    }
}

   其实我觉得上面用枚举类会不会更好,个人建议啦,然后定义好了常用的异常响应码和提示后,开始写控制器增强类,对应常用的服务器端异常情况的处理:

package com.drskj.apiservice.handler;

import java.io.IOException;

import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.drskj.apiservice.common.utils.ReturnFormat;
/**
 * 异常增强,以JSON的形式返回给客服端
 * 异常增强类型:NullPointerException,RunTimeException,ClassCastException,
         NoSuchMethodException,IOException,IndexOutOfBoundsException
         以及springmvc自定义异常等,如下:
SpringMVC自定义异常对应的status code  
           Exception                       HTTP Status Code  
ConversionNotSupportedException         500 (Internal Server Error)
HttpMessageNotWritableException         500 (Internal Server Error)
HttpMediaTypeNotSupportedException      415 (Unsupported Media Type)
HttpMediaTypeNotAcceptableException     406 (Not Acceptable)
HttpRequestMethodNotSupportedException  405 (Method Not Allowed)
NoSuchRequestHandlingMethodException    404 (Not Found) 
TypeMismatchException                   400 (Bad Request)
HttpMessageNotReadableException         400 (Bad Request)
MissingServletRequestParameterException 400 (Bad Request)
 *
 */
@ControllerAdvice
public class RestExceptionHandler{
    //运行时异常
    @ExceptionHandler(RuntimeException.class)  
    @ResponseBody  
    public String runtimeExceptionHandler(RuntimeException runtimeException) {  

        return ReturnFormat.retParam(1000, null);
    }  

    //空指针异常
    @ExceptionHandler(NullPointerException.class)  
    @ResponseBody  
    public String nullPointerExceptionHandler(NullPointerException ex) {  
        ex.printStackTrace();
        return ReturnFormat.retParam(1001, null);
    }   
    //类型转换异常
    @ExceptionHandler(ClassCastException.class)  
    @ResponseBody  
    public String classCastExceptionHandler(ClassCastException ex) {  
        ex.printStackTrace();
        return ReturnFormat.retParam(1002, null);  
    }  

    //IO异常
    @ExceptionHandler(IOException.class)  
    @ResponseBody  
    public String iOExceptionHandler(IOException ex) {  
        ex.printStackTrace();
        return ReturnFormat.retParam(1003, null); 
    }  
    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)  
    @ResponseBody  
    public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {  
        ex.printStackTrace();
        return ReturnFormat.retParam(1004, null);
    }  

    //数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)  
    @ResponseBody  
    public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {  
        ex.printStackTrace();
        return ReturnFormat.retParam(1005, null);
    }
    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseBody
    public String requestNotReadable(HttpMessageNotReadableException ex){
        System.out.println("400..requestNotReadable");
        ex.printStackTrace();
        return ReturnFormat.retParam(400, null);
    }
    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseBody
    public String requestTypeMismatch(TypeMismatchException ex){
        System.out.println("400..TypeMismatchException");
        ex.printStackTrace();
        return ReturnFormat.retParam(400, null);
    }
    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseBody
    public String requestMissingServletRequest(MissingServletRequestParameterException ex){
        System.out.println("400..MissingServletRequest");
        ex.printStackTrace();
        return ReturnFormat.retParam(400, null);
    }
    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseBody
    public String request405(){
        System.out.println("405...");
        return ReturnFormat.retParam(405, null);
    }
    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    @ResponseBody
    public String request406(){
        System.out.println("404...");
        return ReturnFormat.retParam(406, null);
    }
    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class,HttpMessageNotWritableException.class})
    @ResponseBody
    public String server500(RuntimeException runtimeException){
        System.out.println("500...");
        return ReturnFormat.retParam(406, null);
    }
}

  返回格式实体类OutPutJson;这里用到了知名的fastjson将对象转json:

package com.drskj.apiservice.common.utils;

import java.io.Serializable;

import com.alibaba.fastjson.JSON;

public class OutputJson implements Serializable{

    /**
     * 返回客户端统一格式,包括状态码,提示信息,以及业务数据
     */
    private static final long serialVersionUID = 1L;
    //状态码
    private int status;
    //必要的提示信息
    private String message;
    //业务数据
    private Object data;

    public OutputJson(int status,String message,Object data){
        this.status = status;
        this.message = message;
        this.data = data;
    }
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public String toString(){
        if(null == this.data){
            this.setData(new Object());
        }
        return JSON.toJSONString(this);
    }
}

最后自定义一个Controller层的注解,在实现HandlerExceptionResolver 时候,实现对异常的处理(这个还没有想好怎么实现)。

本文转载自:http://www.cnblogs.com/nosqlcoco/p/5562107.html

共有 人打赏支持
alexzhu592
粉丝 1
博文 19
码字总数 17544
作品 0
厦门
程序员
七天学会ASP.NET MVC (六)——线程问题、异常处理、自定义URL

本节又带了一些常用的,却很难理解的问题,本节从文件上传功能的实现引出了线程使用,介绍了线程饥饿的解决方法,异常处理方法,了解RouteTable自定义路径 。 系列文章 七天学会ASP.NET MVC...

葡萄城控件技术团队
2015/07/14
0
0
springboot + shiro 权限注解、请求乱码解决、统一异常处理

springboot + shiro 权限注解、请求乱码解决、统一异常处理 前篇 后台权限管理系统 相关: spring boot + mybatis + layui + shiro后台权限管理系统 springboot + shiro之登录人数限制、登录...

wyait
06/06
0
0
02http协议及httpd基础

http协议及httpd基础 ——以下内容摘自马哥教育课堂 HTTP/2.0 目前没有大规模应用 可以查看相关rfc文档 一次完整的http工作过程浅析: (1)处理连接 处理客户端请求——接收/拒绝请求 tcp连接...

zhuhc1988
2017/01/08
0
0
CoAP协议学习笔记——CoAP格式详解

  CoAP是受限制的应用协议(Constrained Application Protocol)的代名词。在当前由PC机组成的世界,信息交换是通过TCP和应用层协议HTTP实现的。但是对于小型设备而言,实现TCP和HTTP协议显然...

中成才
2016/09/01
87
0
SpringMvc基础知识

1.SpringMvc是什么 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-...

王念博客
2016/03/27
78
0
SpringMVC源码解析(三)——HandlerAdapter

前言 上篇讲的是,HandlerMapping 初始化过程中,是如何将 Handler 与 请求的 url 建立起映射的,我们可以假想一下,“ http://localhost/test ” 的请求过来了,通过映射关系我们找到了 Ha...

MarvelCode
06/30
0
0
HTTP详解(一)

一、socket介绍二、TCP FSM有限状态机三、http相关概念四、http服务器程序 一、socket介绍 1.socket: C/S Client:发起应用请求的程序 Server:响应请求(提供服务)的程序 LISTEN:Socket c/s双方...

MT_IT
2017/11/22
0
0
spring mvc 统一异常处理

1、定义一个统一异常处理类 @ControllerAdvice,是spring3.2提供的新注解, 一般扫描context:component-scan扫描时也能扫描到,不需要在配置文件配置 但如果你的spring-mvc配置文件使用如下方...

qiun
2016/06/24
308
0
http理论及术语

个把月前,阿拉在某处看到有人对大神的描述——公司内部加外援搞了几天没解决的网络问题,只见那人抓了数据包,分析出数据首部信息有误,然后用了某工具将1改成了0,遂网络恢复。 阿拉以为那...

阿拉杜美美
2017/10/16
0
0
Linux自学笔记——套接字与http协议基础

WebService 应用层:http,https 传输层协议:TCP, UDP,SCTP 进程间通信:IPC Socket:ip:port IANA定义的端口信息: 0-1023:众所周知,永久地分配给固定的应用使用,特权端口; 1024-419...

claude_liu
2017/10/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

spring boot中swagger2使用

1.pom.xml中添加 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version>......

说回答
1分钟前
0
0
tomcat虚拟路径的几种配置方法

tomcat虚拟路径的几种配置方法 一般我们都是直接引用webapps下面的web项目,如果我们要部署一个在其它地方的WEB项目,这就要在TOMCAT中设置虚拟路径了,Tomcat的加载web顺序是先加载 $Tomcat_ho...

Helios51
13分钟前
1
0
Mac 安装jupyter notebook的过程

MAC台式机 python:mac下自带Python 2.7.10 1.先升级了pip安装工具:sudo python -m pip install --upgrade --force pip 2.安装setuptools 工具:sudo pip install setuptools==33.1.1 3.安装......

火力全開
18分钟前
0
0
导航守卫解释与例子

“导航”表示路由正在发生改变。 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。 记住...

tianyawhl
18分钟前
0
0
Java日志框架-logback配置文件多环境日志配置(开发、测试、生产)(原始解决方法)

说明:这种方式应该算是最通用的,原理是通过判断标签实现。 <!-- if-then form --> <if condition="some conditional expression"> <then> ... </then> </if> ......

浮躁的码农
33分钟前
1
0
FTP传输时的两种登录方式和区别

登录方式 匿名登录 用户名为: anonymous。 密码为:任何合法 email 地址。 授权登录 用户名为:用户在远程系统中的用户帐号。 密码为:用户在远程系统中的用户密码。 区别 匿名登录 只能访问...

寰宇01
34分钟前
0
0
plsql developer 配置监听(不安装oracle客户端)

plsql developer 配置监听(不安装oracle客户端)

微小宝
41分钟前
1
0
数据库(分库分表)中间件对比

本人的宗旨就是,能copy的,绝对不手写。 分区:对业务透明,分区只不过把存放数据的文件分成了许多小块,例如mysql中的一张表对应三个文件.MYD,MYI,frm。 根据一定的规则把数据文件(MYD)和索...

奔跑吧代码
45分钟前
2
0
Netty与Reactor模式详解

在学习Reactor模式之前,我们需要对“I/O的四种模型”以及“什么是I/O多路复用”进行简单的介绍,因为Reactor是一个使用了同步非阻塞的I/O多路复用机制的模式。 I/O的四种模型 I/0 操作 主要...

hutaishi
51分钟前
1
0
【2018.07.16学习笔记】【linux高级知识 20.16-20.19】

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

lgsxp
57分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部