Returns a uniform object type
package com.miaosha.response;

public class CommonReturnType {
    // Indicate the return processing result of the corresponding request "success" or "fail"
    private String status;
    // If status=success, data contains the JSON data required by the front-end
    // If status=fail, data uses the common error code format
    private Object data;

    // Define a generic creation method
    // Return the correct information
    public static CommonReturnType create(Object result){
        return CommonReturnType.create(result,"success");
    }

    // Return error message, where result is a generic error message
    public static CommonReturnType create(Object result,String status){
        CommonReturnType type = new CommonReturnType();
        type.setStatus(status);
        type.setData(result);
        return  type;
    }

    public String getStatus(a) {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Object getData(a) {
        return data;
    }

    public void setData(Object data) {
        this.data = data; }}Copy the code

Use cases:

return CommonReturnType.create(itemVO);// Success, with a message returned
Copy the code
return CommonReturnType.create(null);// Succeeded, no message is returned
Copy the code
return CommonReturnType.create(responseData,"fail");// Failed, an error message is returned
Copy the code
An error message is returned

Wrapper business exception class implementation: BusinessException and EmBusinessError inherit CommonError, So that the external can not only have the assembly definition of errCode and errMsg through new EmBusinessError or New BusinessException, but also jointly implement a setErrMsg method. Can be used to override errMsg originally defined in EmBusinessError.

The code:

package com.miaosha.error;

public interface CommonError {
    public int getErrCode(a);
    public String getErrMsg(a);
    public CommonError serErrMsg(String errMsg);
}
Copy the code
package com.miaosha.error;

public enum EmBusinessError implements CommonError {
    // Common error type 10001
    PARAMETER_VALIDATION_ERROR(10001."Invalid parameter"),
    UNKNOW_ERROR(10002."Unknown error"),

    // the beginning of 20000 is defined as a user information related error
    USER_NOT_EXIST(20001."User does not exist"),
    USER_LOGIN_FAIL(20002."User's phone number or password is incorrect"),
    USER_NOT_LOGIN(20003."User not logged in yet"),

    //30000 starts with transaction information incorrectly defined
    STOCK_NOT_ENOUGH(30001."Out of stock"),;// constructor
    private EmBusinessError(int errCode,String errMsg){
        this.errCode = errCode;
        this.errMsg = errMsg;
    }

    private int errCode;
    private String errMsg;

    @Override
    public int getErrCode(a) {
        return this.errCode;
    }

    @Override
    public String getErrMsg(a) {
        return this.errMsg;
    }

    @Override
    public CommonError serErrMsg(String errMsg) {
        this.errMsg = errMsg;
        return this; }}Copy the code
package com.miaosha.error;

// Wrapper business exception class implementation
public class BusinessException extends Exception implements CommonError {

    private CommonError commonError;

    // Take the EmBusinessError pass argument directly to construct a business exception
    public BusinessException(CommonError commonError){
        super(a);this.commonError = commonError;
    }

    // Accept custom errMsg to construct a business exception
    public BusinessException(CommonError commonError,String errMsg){
        super(a);this.commonError = commonError;
        this.commonError.serErrMsg(errMsg);
    }

    @Override
    public int getErrCode(a) {
        return this.commonError.getErrCode();
    }

    @Override
    public String getErrMsg(a) {
        return this.commonError.getErrMsg();
    }

    @Override
    public CommonError serErrMsg(String errMsg) {// Error messages used to change common error types
        this.commonError.serErrMsg(errMsg);
        return this; }}Copy the code

Using the user registration service implementation as an example:

	@Override
    @Transactional
    public void register(UserModel userModel) throws BusinessException {
        if (userModel==null) {throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR);
        }
        ValidationResult result = validator.validate(userModel);
        if (result.isHasErrors()){
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR,result.getErrMsg());
        }
Copy the code

The BusinessException from new is thrown directly into the Tomcat container layer, which handles such an exception by returning an error page of 500.

Is there a mechanism for intercepting Tomcat’s exception handling and then fixing the problem?

Here we use a Spring MVC handlerException that comes with Spring Boot to solve this problem.

Exception handling

Define ExceptionHandler to resolve Exceptions that are not absorbed by the Controller layer (for business logic processing problems or business logic errors rather than errors that the server cannot handle)

package com.miaosha.controller;

import com.miaosha.error.BusinessException;
import com.miaosha.error.EmBusinessError;
import com.miaosha.response.CommonReturnType;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

public class BaseController {
    // Define ExceptionHandler to resolve exceptions that are not absorbed by the Controller layer (for business logic processing problems or business logic errors, not errors that cannot be handled by the server)
    @ExceptionHandler(Exception.class)// Need to specify what kind of exception will be received before it enters its processing, defined as the root class
    @ResponseStatus(HttpStatus.OK)// Catch the exception thrown by controller and return httpstatus. OK, that is, status=200
    @ResponseBody // Handler Exception returns only the path to the page, and does not handle the @responseBody form corresponding to the ViewObject class
    public Object handlerException(HttpServletRequest request, Exception ex){
        Map<String,Object> responseData = new HashMap<>();
        if (ex instanceof BusinessException){
            BusinessException businessException = (BusinessException)ex;
            responseData.put("errCode",businessException.getErrCode());
            responseData.put("errMsg",businessException.getErrMsg());
        }else {
            responseData.put("errCode", EmBusinessError.UNKNOW_ERROR.getErrCode());
            responseData.put("errMsg",EmBusinessError.UNKNOW_ERROR.getErrMsg());
        }
        return CommonReturnType.create(responseData,"fail"); }}Copy the code

It is the common logic for all controllers, so all controllers inherit it.

Reference:

Moocs Course “SpringBoot To Build e-commerce Infrastructure Kill Project”

Recommended just start SpringBoot students to watch, the teacher’s foundation is particularly good