@ControllerAdvice的使用

 

其实@ControllerAdvice有3个作用:

  1. 全局异常处理
  2. 全局数据绑定
  3. 全局数据预处理

3.7.1 全局异常处理

就是自定义一个全局异常类,然后通过@ControllerAdvice捕获处理

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice

public class GlobalExceptionHandler {

    private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    public static final String SYSTEM_ERROR = "服务器正忙,请稍后再试...";

    @ResponseBody

    @ExceptionHandler(CustomUnCheckedException.class)

    public ResultData handleryException(HttpServletRequest request, CustomUnCheckedException ex){

        logger.error("自定义异常:{}",ex);

        ResultData resultData = new ResultData<>();

        resultData.setResultCode(ex.getCode());

        System.out.println(ex.getCode());

        resultData.setResultMsg(ex.getMessage());

        return resultData;

    }

    @ResponseBody

    @ExceptionHandler(Exception.class)

    public ResultData handlerException(HttpServletRequest request, Exception ex){

        logger.error("异常:{}",ex);

        ResultData resultData = new ResultData<>();

        resultData.setResultCode(ResultStateEnum.FAIL.getCode());

        resultData.setResultMsg(SYSTEM_ERROR);

        return resultData;

    }

}

自定义全局异常:

public class CustomUnCheckedException extends RuntimeException implements Serializable {

    private static final long serialVersionUID = 2516912856988538515L;

private static final Integer DEFAULT_CODE = 0;// 默认结果码0代表成功

private static final String DEFAULT_OUT_MSG = "成功";

private Integer code;//结果码,省略getter方法

    public String getOutMsg() {

        if (code.equals(DEFAULT_CODE)) { return getMessage();}

        CustomExceptionCodeEnum customExceptionCodeEnum = CustomExceptionCodeEnum.getByCode(code);

        if (customExceptionCodeEnum != null) {

            return customExceptionCodeEnum.getDesout();

        }

        return getMessage();

    }

 

    public String getInMsg() {

        CustomExceptionCodeEnum customExceptionCodeEnum =

CustomExceptionCodeEnum.getByCode(code);

        if (customExceptionCodeEnum != null) { return customExceptionCodeEnum.getDesin();}

        return getMessage();

    }

// 构造器 多种支持

    public CustomUnCheckedException() { super();}

    public CustomUnCheckedException(Throwable e) { super(e); }

    public CustomUnCheckedException(Integer errorCode) { this.code = errorCode; }

    public CustomUnCheckedException(CustomExceptionCodeEnum mcode, Throwable e) {

        super(mcode.getDesin(), e);

        this.code = mcode.getCode();

    }

    public CustomUnCheckedException(Integer code, Throwable e) {

        super(CustomExceptionCodeEnum.getInMsg(code), e);

        this.code = code;

    }

    public CustomUnCheckedException(Integer code, String message) {

        super(message); this.code = code;

    }

    public CustomUnCheckedException(Integer code, String message, Throwable e) {

        super(message, e);

        this.code = code;

    }

}

//错误码

public enum  CustomExceptionCodeEnum {

    DB_OPERATOR__ERROR_001(1, "数据库操作发生异常", "数据库操作发生异常"),

    SYS_NO_REPEAT_OPERATION(2, "SYS_NO_REPEAT_OPERATION", "请勿重复操作!");

    private Integer code; /**错误码*/  //省略getter

    private String desin; /** 内部描述 */

    private String desout; /** 外部描述 */

    CustomExceptionCodeEnum(Integer code, String desin, String desout) {

        this.code = code; this.desin = desin; this.desout = desout;

}

//通过错误码获取CustomExceptionCodeEnum实例

    public static CustomExceptionCodeEnum getByCode(Integer code) {

        if (null != code) {

            for (CustomExceptionCodeEnum mnum : values()) {

                if (mnum.getCode().equals(code)) { return mnum; }                

            }

        }

        return null;

    }//根据错误码获取内部描述

    public static String getInMsg(Integer code) {

        if ( null != code ) {

            for (CustomExceptionCodeEnum mnum : values()) {

                if (mnum.getCode().equals(code)) { return mnum.getDesin();}                   

            }

        }

        return null;

    }//根据错误码获取外部描述

    public static String getOutMsg(String code) {

        if (code != null && !"".equals(code.trim())) {

            for (CustomExceptionCodeEnum mnum : values()) {

                if (mnum.getCode().equals(code)) { return mnum.getDesout();}

           }

        }

        return null;

    }

}

3.7.2 全局数据绑定

定义需要绑定的数据

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ModelAttribute;

import java.util.HashMap;

import java.util.Map;

@ControllerAdvice

public class MyGlobalDataBindHandler {

    @ModelAttribute(name="allen") //对应Map的Key

    public Map myData(){

        Map map = new HashMap<>();

        map.put("age",99);//对应Map的value

        map.put("gender","男");//对应Map的value

        return map;

    }

}

测试类:

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController

public class TestController2 {

    @RequestMapping("/test2")

    public String test2(Model model){

        Map map = model.asMap();

        System.out.println(map);//{allen={gender=男, age=99}}

        return "test2";

    }

}

3.7.3 全局数据预处理

利用@ControllerAdvice、@InitBinder(“b”)、WebDataBinder、@ModelAttribute("b") 实现拦截并实现数据的预处理

@ControllerAdvice

public class MyGlobalDataPrecessingHandler {

    @InitBinder("b")

    public void b(WebDataBinder binder){ binder.setFieldDefaultPrefix("b."); }

    @InitBinder("a")

    public void a(WebDataBinder binder){ binder.setFieldDefaultPrefix("a."); }        

}

 

public class Author {//省略setter&getter&toString方法

    private  String name; private  Integer age;

}

 

public class Book {//省略setter&getter&toString方法

    private String name; private Double price;

}

import org.springframework.web.bind.WebDataBinder;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.InitBinder;

测试类

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class TestController3 {

//http://localhost:18080/add/book?name=allen基于springboot的书&price=100&name=allen&age=28

    @RequestMapping("/add/book")

    public void addBook(Book book,Author author){

        System.out.println(book);//Book{name='allen基于springboot的书,allen', price=100.0}

        System.out.println(author);//Author{name='allen基于springboot的书,allen', age=28}

}

//http://localhost:18080/add/book2?b.name=allen基于springboot的书&b.price=100&a.name=allen&a.age=28

    @RequestMapping("/add/book2")

    public void addBook2(@ModelAttribute("b") Book book, @ModelAttribute("a")Author author){

        System.out.println(book);//Book{name='allen基于springboot的书', price=100.0}

        System.out.println(author);//Author{name='allen', age=28}

    }

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(spring)