springboot2.x basic tutorial: jsr303 interface parameter verification, combined with unified exception interception

JSR is the abbreviation of Java Specification Requests, which means Java Specification Proposal. It is a formal request for adding a standardized technical specification to JCP (Java Community Process). Anyone can submit a JSR to add new APIs and services to the Java platform. JSR has become an important standard in the Java world.
JSR-303 is a sub-specification in JAVA EE 6, called Bean Validation, Hibernate Validator is the reference implementation of Bean Validation. Hibernate Validator provides the implementation of all the built-in constraints in the JSR 303 specification, in addition to some additional constraint. If you want to know more about Hibernate Validator, please check http://www.hibernate.org/subprojects/validator.html
The backend interface developed by the SpringBoot project often makes basic checks on whether the parameters are empty and the length of the parameters. Here, SpringBoot can easily integrate JSR303, easily verify interface parameters through annotations, and can customize verification rules.

JSR303 Annotation Introduction

JSR303 comes with constraints

Hibernate Validator additional constraints

SpringBoot project integration

Project introduction dependency

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

Introduction to Hibernate Validator

Hibernate Validator's validation mode has two situations

  1. Quick failure (one verification fails, error message is returned quickly)
  2. Normal mode (by default, all attributes will be verified, and then all verification failure information will be returned)
    We generally use the first one, SpringBoot needs to enable configuration
/**
 * 配置Jsr303 hibernate validator快速失败模式
 */
@Configuration
public class Jsr303Config {
    @Bean
    public Validator validator(){
        ValidatorFactory validatorFactory = Validation
                .byProvider( HibernateValidator.class )
                .configure()
                .failFast( true )
                .buildValidatorFactory();
        return validatorFactory.getValidator();
    }
}

Basic use

Use the @Valid annotation on the method to open the verification, and use the BindingResult to receive the verification result

@Data
public class LoginDTO {
    @Size(min = 8,message = "账号长度大于8")
    String account;
    @NotBlank(message = "密码不能为空")
    String passwd;
}
    @PostMapping("/logon")
    public R logon(@Valid LoginDTO loginDTO, BindingResult result){
        check(result);
        return R.ok("");
    }
    public static void check(BindingResult result){
        StringBuffer sb=new StringBuffer();
        if(result.hasErrors()){
            for (ObjectError error : result.getAllErrors()) {
                sb.append(error.getDefaultMessage());
            }
            ExUtil.throwBusException(sb.toString());
        }
    }

Jsr303 used with unified exception

In the project, I usually define a unified exception class that belongs to the business. Here, after the verification fails, the custom verification information is assembled and a custom BusinessException is thrown.

public class BusinessException extends RuntimeException {

    private static final long serialVersionUID = 1L;
    private int code = ApiCommonCodeEnum.FAIL.getCode();
    public BusinessException(String message) {
        super(message);
    }
	//防止篇幅过长省略其他代码
}
//异常工具类
public class ExUtil {
    public static void throwBusException(String msg){
        throw new BusinessException(msg);
    }
	//......
}

Then it is intercepted by the unified exception and returns to the previously defined R interface. The failure information is contained in the msg field.
Post part of the unified exception interception code

@Component
@Slf4j
public class ExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
        if(ex instanceof BusinessException){
            R result= R.fill(((BusinessException) ex).getCode(),null,ex.getMessage());
            outputJSON(httpServletResponse, Charsets.UTF_8.toString(), JsonUtil.toJson(result));
            return null;
        }else {
            R result=R.failed(ex.getMessage());
            outputJSON(httpServletResponse, Charsets.UTF_8.toString(), JsonUtil.toJson(result));
            return null;
        }
    }
    private void outputJSON(HttpServletResponse response, String charset, String jsonStr) {
        PrintWriter out = null;
        try {
            if (response != null) {
                response.setCharacterEncoding(charset);
                response.setContentType("text/html;charset=" + charset);
                response.setHeader("Pragma", "No-cache");
                response.setHeader("Cache-Control", "no-cache");
                response.setDateHeader("Expires", 0);
                out = response.getWriter();
                out.print(jsonStr);
            }
        } catch (Exception e) {
            log.error(ExUtil.getSimpleMessage(e));
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}

Interface test effect


A thousand miles begins with a single step. Here is the fourth article in the SpringBoot tutorial series. All project source codes can be downloaded on my GitHub .
For more content, follow WeChat official account:
Insert picture description here

Guess you like

Origin blog.csdn.net/github_35592621/article/details/108248784