SpringBoot- @ ControllerAdvice intercepted an exception and unified treatment

SpringBootTo simplify the Springcreation of applications, a series of problems running, debugging, deployment and the birth of the product,

自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工程

 

The actual project development, the program is often a wide range of abnormal happens, especially as our server developer,

Always keep the front-end interface to write call, in the case of division of labor, can not avoid the occurrence of an abnormality, if the wrong information directly exposed to the user directly,

This experience can be imagined, and for hackers, abnormal detailed information will often offer a very big help ...

First Look abnormal

A simple interface to request exception

@GetMapping ( "/ test1" )
 public String test1 () {
     // here is only simulated abnormal, assuming the service processing when the error, a null pointer or the like ... 
    int I = 10/0 ;
     return "test1" ; 
}

Open a browser to access it when found

Or is postmansimulation tools

If this interface is a call to a third party or the company's own system, we see this miscalculation ... it was a runaway.

Stupid way (highly not recommended)

Use try-catchmode, manually capture the abnormality information, and returns a corresponding result set, I believe many people have seen a similar code (for example: Result encapsulated object);

Although this method of indirect problems exposed resolve the error, the same disadvantages are also apparent, increasing the number of code amount, when the abnormality corresponding to the case where excess catchlayer increasingly more up,

Difficult to manage these businesses match between the exception and error code, so the best way is through a simple configuration global control ....

@GetMapping ( "/ test2" )
 public the Map <String, String> test2 () { 
    the Map <String, String> Result = new new the HashMap <> (16 );
     // the TODO directly capture all the code blocks, and then Cache 
    the try {
         int = 10 I / 0 ; 
        result.put ( "code", "200 is" ); 
        result.put ( "Data", "return result set concrete" ); 
    } the catch (Exception E) { 
        result.put ( "code" , "500" ); 
        result.put ( "Message", "request error" );
    }
    return result;
}

Specific code

Through the above reading can understand why we all need to roughly abnormal globally captured, then look at Spring Bootsolutions offered

Import dependence

In pom.xmlthe add spring-boot-starter-web-dependent can

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Custom exception

In the application development process, in addition to the system itself unusual, different business scenarios used in the anomaly are not the same, for the title 轻松搞定全局异常more appropriate definition of their own exceptions, to see how to capture ...

/**
 * 自定义异常
 */
public class CustomException extends RuntimeException {
    private static final long serialVersionUID = 4564124491192825748L;

    private int code;

    public CustomException() {
        super();
    }
    public CustomException(int code, String message) {
        super(message);
        this.setCode(code);
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
}

Abnormal Templates

Define the return format, this abnormal Style abnormal information is more unified

/**
 * 异常信息模板
 */
public class ErrorResponseEntity {

    private int code;
    private String message;

    public ErrorResponseEntity(int code, String message) {
        this.code = code;
        this.message = message;
    }
    // 省略 get/set
}

Control Layer

Look closely and is not usually normal write code lacks distinction, do not rush, then look ....

Import com.winterchen.exception.CustomException;
 Import org.springframework.web.bind.annotation.GetMapping;
 Import org.springframework.web.bind.annotation.RestController; 

@RestController 
public  class ExceptionController { 

    @GetMapping ( "/ Test3" )
     public Test3 String (Integer NUM) {
         // TODO demo requires, in fact, if the parameter is null by @RequestParam (required = true) can be controlled 
        iF (NUM == null ) {
             the throw  new new customException (400, "NUM can not be empty." ); 
        } 
        int I = 10 / NUM;
         return "result:" + i;
    }
}

Exception Handling (key)

Notes Overview

  • @ControllerAdviceTrapping Controllerlayer thrown <wiz_tmp_highlight_tag class = "cm-searching "> abnormal, if the added @ResponseBodyreturn information was JSONformat.
  • @RestControllerAdviceCorresponds to @ControllerAdvicethe @ResponseBodybinding body.
  • @ExceptionHandlerUnified treating one exception class <wiz_tmp_highlight_tag class = "cm-searching">, reduce code repetition rate, reduce complexity.

Create a GlobalExceptionHandlerclass and add the @RestControllerAdviceannotation can define an exception notification class, and then add on the method defined @ExceptionHandlerto achieve unusual catch ...

import com.winterchen.exception.CustomException;
import com.winterchen.exception.ErrorResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
Import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; 

Import the javax.servlet.http.HttpServletRequest;
 Import javax.servlet.http.HttpServletResponse; 

/ ** 
 * global exception handler 
 * / 
@RestControllerAdvice 
public  class GlobalExceptionHandler the extends {ResponseEntityExceptionHandler 

    / ** 
     * define a plurality of exception can be captured @ExceptionHandler ({}) 
     * @param Request Request 
     * @param E exception 
     * @param response response 
     * @return response result
      * /
    @ExceptionHandler (. CustomException class )
     public ErrorResponseEntity customExceptionHandler (the HttpServletRequest Request, Final Exception E, the HttpServletResponse Response) { 
        response.setStatus (HttpStatus.BAD_REQUEST.value ()); 
        customException Exception = (customException) E;
         return  new new ErrorResponseEntity (exception.getCode (), exception.getMessage ()); 
    } 

    / ** 
     * capture RuntimeException abnormal 
     * If you think through if (e instanceof xxxException) too much trouble in a exceptionHandler 
     * then you can also write your own deal with a number of different exceptionHandler different abnormal 
     * @param Request Request 
     *@param e        exception
     * @param response response
     * @return 响应结果
     */
    @ExceptionHandler(RuntimeException.class)
    public ErrorResponseEntity runtimeExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        RuntimeException exception = (RuntimeException) e;
        return new ErrorResponseEntity(400, exception.getMessage());
    }

    /**
     * 通用的接口映射异常处理方
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(new ErrorResponseEntity(status.value(), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            Exception MethodArgumentTypeMismatchException= (MethodArgumentTypeMismatchException) EX; 
            logger.error ( "failed parameter conversion process:".. + Exception.getParameter () getMethod () getName () + ", Parameter:" + exception.getName ()
                     + ", Information:" + exception.getLocalizedMessage ());
             return  new new ResponseEntity <> ( new new ErrorResponseEntity (status.value (), "the parameter conversion failed" ), Status); 
        } 
        return  new new ResponseEntity <> ( new new ErrorResponseEntity (status.value (), " parameter conversion failed " ), Status); 
    } 
}

The main function

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootExceptionApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootExceptionApplication.class, args);
    }
}

test

Upon completion Preparations start Chapter17Application, it can be found through the following test results, really so easy, the code became clean, scalability is also changed for the better ...

Visit http: // localhost: 8080 / test3

{ "Code": 400, "message": "num not be blank"}

Visit http: // localhost:? 8080 / test3 num = 0

{"code":400,"message":"/ by zero"}

Visit http: // localhost: 8080 / test3 num = 5?

result:2

 

Reprinted link: http://blog.battcn.com/2018/06/01/springboot/v2-other-exception/

 

Guess you like

Origin www.cnblogs.com/JimmyThomas/p/12080607.html