• 1, the preface
  • 2. Custom exception handling
  • 3. Complete code

1, the preface

During project development, we will inevitably encounter business code exceptions, whether server 500 or other exceptions. So let’s talk a little bit about how to get rid of try-catch and get exception response all the same;

Error type:

1. Custom business service code exceptions (according to the needs of their respective projects)

2. ServletException HTTP request exception

3, internal code exception: such as mysql query table name error

404: This is not available in the unified exception and requires additional processing

Normally, we would write:

JobController

@getMapping ("/list") public Result getList() {Result Result; try { List<Job> jobList = jobService.findAll(); result = ResultGenerator.getSuccessResult(jobList); } catch (Exception e) { e.printStackTrace(); result = ResultGenerator.getFailResult(e.getMessage()); } return result; }Copy the code

The result is shown below:


It’s a bit of a hassle, a lot of try-catches.

So is there a way to help us automatically intercept errors?

2. Custom exception handling

HandlerExceptionResolver, exception handling is the class;

Source:

public interface HandlerExceptionResolver {
    @Nullable
    ModelAndView resolveException(HttpServletRequest var1, HttpServletResponse var2, @Nullable Object var3, Exception var4);
}
Copy the code

Request, response, hendler, exception;

Next, we rewrite WebMvcConfigurer. ConfigureHandlerExceptionResolvers to deal with abnormal:

com.scaffold.test.config.WebMvcConfig

package com.scaffold.test.config;

import com.alibaba.fastjson.JSON;
import com.scaffold.test.base.Result;
import com.scaffold.test.base.ResultCode;
import com.scaffold.test.base.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.NoHandlerFoundException; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List;  @Configuration public class WebMvcConfig implements WebMvcConfigurer {   private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);   // Unified exception handling  @Override  public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {  exceptionResolvers.add((request, response, handler, e) -> {  Result result = new Result();  // Error handling  if (e instanceof ServiceException) {  // 1. Service failure exceptions, such as incorrect account or password  result.setCode(ResultCode.FAIL).setMessage(e.getMessage());  logger.info(e.getMessage());  } else if (e instanceof ServletException) {  // 2. Call failed  result.setCode(ResultCode.FAIL).setMessage(e.getMessage());  } else {  // 3. Internal error  result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("Interface [" + request.getRequestURI() + "] Internal error, please contact administrator");  String message;  if (handler instanceof HandlerMethod) {  HandlerMethod handlerMethod = (HandlerMethod) handler;  message = String.format("Interface [%s] exception, method: %s.%s, exception Summary: %s". request.getRequestURI(),  handlerMethod.getBean().getClass().getName(),  handlerMethod.getMethod().getName(),  e.getMessage());  } else {  message = e.getMessage();  }  result.setMessage(message);  logger.error(message, e);  }  responseResult(response, result);  return new ModelAndView();  });  }   // Process the returned data format  private void responseResult(HttpServletResponse response, Result result) {  response.setCharacterEncoding("UTF-8");  response.setHeader("Content-type"."application/json; charset=UTF-8");  response.setStatus(200);  try {  response.getWriter().write(JSON.toJSONString(result));  } catch (IOException ex) {  logger.error(ex.getMessage());  }  }  } Copy the code

1. Service failure exceptions: ServiceException ServiceException class

package com.scaffold.test.base;

/ * ** Service (service) exceptions, such as incorrect account or password, are only recorded at the INFO level@see WebMvcConfigurer
* /
public class ServiceException extends RuntimeException {  public ServiceException(a) {  }   public ServiceException(String message) {  super(message);  }   public ServiceException(String message, Throwable cause) {  super(message, cause);  } }  Copy the code
// Some code
if (e instanceof ServiceException) {
  // 1. Service failure exceptions, such as incorrect account or password
  result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
  logger.info(e.getMessage());
} Copy the code

Error 400 code;

2. Call failure: Servlet is abnormal

if (e instanceof ServletException) {
 // 3. Call failed
 result.setCode(ResultCode.FAIL).setMessage(e.getMessage());
}
Copy the code

The result is shown below:


3, internal code exception: such as mysql query table name error

String message;
if (handler instanceof HandlerMethod) {
 HandlerMethod handlerMethod = (HandlerMethod) handler;
 message = String.format("Interface [%s] exception, method: %s.%s, exception Summary: %s". request.getRequestURI(),
 handlerMethod.getBean().getClass().getName(),  handlerMethod.getMethod().getName(),  e.getMessage()); } else {  message = e.getMessage(); } result.setMessage(message); logger.error(message, e); Copy the code

The result is shown below:


404: This is not available in the unified exception and requires additional processing

404 Failed to enter unified exception processing, as shown below:


Therefore, global exception handling does not catch 404 errors, so you need to write a special class to handle 404 exceptions

com.scaffold.test.base.NotFoundException

package com.scaffold.test.base;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 @RestController public class NotFoundException implements ErrorController {   private static final String ERROR_PATH = "/error";   @RequestMapping(ERROR_PATH)  public Result error(a) {  Result result = new Result();  // 2. The interface does not exist  result.setCode(ResultCode.NOT_FOUND).setMessage("Interface does not exist");  return result;  }   @Override  public String getErrorPath(a) {  return ERROR_PATH;  } } Copy the code

3. Complete code

Com. Scaffold. Test. Base. The Result: a unified return entity class

package com.scaffold.test.base;

import lombok.Data;

/ * ** Unified API response result encapsulation* /  @Data public class Result {   private int code;   private String message = "success";   private Object data;   public Result setCode(ResultCode resultCode){  this.code = resultCode.code;  return this;  }   public Result setMessage(String message){  this.message = message;  return this;  }   public Result setData(Object data){  this.data = data;  return this;  }  } Copy the code

Com. Scaffold. Test. Base. The ResultCode: unified returns a response code, reference the HTTP status code

package com.scaffold.test.base;

/ * ** Enumeration of response codes, refer to the semantics of HTTP status codes* /
 public enum ResultCode {  SUCCESS(200),/ / success  FAIL(400),/ / fail  UNAUTHORIZED(401),// Unauthenticated (signature error)  NOT_FOUND(404),// The interface does not exist  INTERNAL_SERVER_ERROR(500);// Server internal error   public int code;   ResultCode(int code) {  this.code = code;  } } Copy the code

Unified exception to intercept: com. Scaffold. Test. Config. WebMvcConfig

package com.scaffold.test.config;

import com.alibaba.fastjson.JSON;
import com.scaffold.test.base.Result;
import com.scaffold.test.base.ResultCode;
import com.scaffold.test.base.ServiceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;  import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List;  @Configuration public class WebMvcConfig implements WebMvcConfigurer {   private final Logger logger = LoggerFactory.getLogger(WebMvcConfigurer.class);   // Unified exception handling  @Override  public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {  exceptionResolvers.add((request, response, handler, e) -> {  Result result = new Result();  // Exception handling  if (e instanceof ServiceException) {  // 1. Service failure exceptions, such as incorrect account or password  result.setCode(ResultCode.FAIL).setMessage(e.getMessage());  logger.info(e.getMessage());  }else if (e instanceof ServletException) {  // 2. Call failed  result.setCode(ResultCode.FAIL).setMessage(e.getMessage());  } else {  // 3. Other internal errors  result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("Interface [" + request.getRequestURI() + "] Internal error, please contact administrator");  String message;  if (handler instanceof HandlerMethod) {  HandlerMethod handlerMethod = (HandlerMethod) handler;  message = String.format("Interface [%s] exception, method: %s.%s, exception Summary: %s". request.getRequestURI(),  handlerMethod.getBean().getClass().getName(),  handlerMethod.getMethod().getName(),  e.getMessage());  } else {  message = e.getMessage();  }  result.setMessage(message);  logger.error(message, e);  }  responseResult(response, result);  return new ModelAndView();  });  }   // Process the response data format  private void responseResult(HttpServletResponse response, Result result) {  response.setCharacterEncoding("UTF-8");  response.setHeader("Content-type"."application/json; charset=UTF-8");  response.setStatus(200);  try {  response.getWriter().write(JSON.toJSONString(result));  } catch (IOException ex) {  logger.error(ex.getMessage());  }  } } Copy the code

404 intercept processing: com. Scaffold. Test. Base. NotFoundException

package com.scaffold.test.base;

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 @RestController public class NotFoundException implements ErrorController {   private static final String ERROR_PATH = "/error";   @RequestMapping(ERROR_PATH)  public Result error(a) {  Result result = new Result();  // 4. The interface does not exist  result.setCode(ResultCode.NOT_FOUND).setMessage("Interface does not exist");  return result;  }   @Override  public String getErrorPath(a) {  return ERROR_PATH;  } }  Copy the code

This article is formatted using MDNICE