Springboot | The eighth chapter: Unification anomaly, data check processing

Source: Internet
Author: User
Tags getmessage

Objective

In a Web application, exceptions are very common when request processing occurs. Therefore, when the application of various types of anomalies, the exception of the capture or two processing (such as SQL Anomaly can not be thrown out) is very necessary, such as in the development of external API services, agreed to the parameters of the response format, such as, the respCode respMsg caller based on the error code to carry out their own business logic. This chapter focuses on the unification of exceptions and data validation processing.

springboot, by default, when sending an exception, the Jump value /error request is displayed incorrectly, depending on the different Content-Type error results, such as JSON request, the JSON format parameters are returned directly.
When a browser accesses an exception:

postmanWhen using Access:

    • Unified exception Handling
      • Creating a global uniform exception handling class
    • Data validation
      • Custom Check Annotations
    • Summarize
    • At last
    • Cliché

      Unified exception Handling

      Obviously, the default exception page is not friendly to the user or the caller, so we generally do the exception tip information to implement our own business.

Creating a global uniform exception handling class

Use @ControllerAdvice and @ExceptionHandler define a unified exception handling class

    • @ControllerAdvice: Controller enhancements that enable the @exceptionhandler, @InitBinder, @ModelAttribute annotation methods to be applied to all @RequestMapping annotations.

    • @ExceptionHandler: Exception handler, which is used to process a defined exception when it appears

Create Exception class: Commonexceptionhandler

@ControllerAdvicepublic class CommonExceptionHandler {    /**     *  拦截Exception类的异常     * @param e     * @return     */    @ExceptionHandler(Exception.class)    @ResponseBody    public Map<String,Object> exceptionHandler(Exception e){        Map<String,Object> result = new HashMap<String,Object>();        result.put("respCode", "9999");        result.put("respMsg", e.getMessage());        //正常开发中,可创建一个统一响应实体,如CommonResp        return result;     }}

Extra different exceptions (such as custom exceptions), when different exception handling is required, you can write multiple exceptionhandler methods, annotations ExceptionHandler Specify the exception classes to be handled, such as

    /**     * 拦截 CommonException 的异常     * @param ex     * @return     */    @ExceptionHandler(CommonException.class)    @ResponseBody    public Map<String,Object> exceptionHandler(CommonException ex){        log.info("CommonException:{}({})",ex.getMsg(), ex.getCode());        Map<String,Object> result = new HashMap<String,Object>();        result.put("respCode", ex.getCode());        result.put("respMsg", ex.getMsg());        return result;     }

due to the addition @ResponseBody , the returned json format is

Indicates that the exception has been intercepted.
can intercept different anomalies, to carry out different abnormal hints, such as,, and NoHandlerFoundException HttpMediaTypeNotSupportedException AsyncRequestTimeoutException so on , here is not listed, the reader can join their own after the actual operation.

Returns when the page is returned ModelAndView , as

@ExceptionHandler(value = Exception.class)    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {        ModelAndView mav = new ModelAndView();        mav.addObject("exception", e);        mav.addObject("url", req.getRequestURL());        mav.setViewName(DEFAULT_ERROR_VIEW);        return mav;    }

Since the work is only a front-end separation of development mode, so generally there is no direct return to the requirements of the resource page, generally return a fixed response format, such as,, respCode respMsg data The front end through respCode the value of the judgment of business judgment, is the pop window or jump page.

Data validation

In the Web development, for the request parameters, the general need to verify the validity of the parameters, the original method of writing a field by one to judge, this way is not universal, so Java JSR 303: Bean Validation specification is to solve the problem.

JSR 303Just a specification, and there is no specific implementation, the current is usually only hibernate-validator to carry out uniform parameter verification.

JSR303 the type of validation defined

Constraint More Information
@Null The annotated element must be anull
@NotNull The annotated element must not be anull
@AssertTrue The annotated element must be atrue
@AssertFalse The annotated element must be afalse
@Min(value) The annotated element must be a number whose value must be greater than or equal to the specified minimum value
@Max(value) The annotated element must be a number whose value must be less than or equal to the specified maximum value
@DecimalMin(value) The annotated element must be a number whose value must be greater than or equal to the specified minimum value
@DecimalMax(value) The annotated element must be a number whose value must be less than or equal to the specified maximum value
@Size(max, min) The size of the annotated element must be within the specified range
@Digits (integer, fraction) The annotated element must be a number whose value must be within an acceptable range
@Past The annotated element must be a past date
@Future The annotated element must be a future date
@Pattern(value) The annotated element must conform to the specified regular expression

Hibernate Validator Additional constraint

Constraint More Information
@Email The annotated element must be an e-mail address
@Length The size of the annotated string must be within the specified range
@NotEmpty The annotated string must be non-empty
@Range The annotated element must be within the appropriate range

Create an entity class

@Data@NoArgsConstructor@AllArgsConstructorpublic class DemoReq {        @NotBlank(message="code不能为空")    String code;        @Length(max=10,message="name长度不能超过10")    String name;}

Then in the control layer method, you can add @Valid , so that before the visit, the request parameters will be tested.

    @GetMapping("/demo/valid")    public String demoValid(@Valid DemoReq req) {        return req.getCode() + "," + req.getName();    }

startup, after accesshttp://127.0.0.1:8080/demo/valid

When the correct parameters are added,http://127.0.0.1:8080/demo/valid?code=3&name=s

So the unified calibration of the data is completed, for the use of other annotations, we can Google, basically all very simple, for the existing annotations can not meet the verification needs, but also for the development of custom annotations, a brief explanation, the compilation of custom annotations

If you do not use @valid, you can also write a tool class programmatically to verify the entity parameters.

public class ValidatorUtil {    private static Validator validator = ((HibernateValidatorConfiguration) Validation            .byProvider(HibernateValidator.class).configure()).failFast(true).buildValidatorFactory().getValidator();    /**     * 实体校验     *      * @param obj     * @throws CommonException     */    public static <T> void validate(T obj) throws CommonException {        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj, new Class[0]);        if (constraintViolations.size() > 0) {            ConstraintViolation<T> validateInfo = (ConstraintViolation<T>) constraintViolations.iterator().next();            // validateInfo.getMessage() 校验不通过时的信息,即message对应的值            throw new CommonException("0001", validateInfo.getMessage());        }    }}

Use

    @GetMapping("/demo/valid")    public String demoValid(@Valid DemoReq req) {        //手动校验        ValidatorUtil.validate(req);        return req.getCode() + "," + req.getName();    }
Custom Check Annotations

Custom annotations, the primary implementation ConstraintValidator of the processing class can be, here has written a checksum constant annotation as an example: The parameter value can only be a specific value.

Custom annotations

@Documented//指定注解的处理类@Constraint(validatedBy = {ConstantValidatorHandler.class })@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })@Retention(RUNTIME)public @interface Constant {   String message() default "{constraint.default.const.message}";   Class<?>[] groups() default {};   Class<? extends Payload>[] payload() default {};   String value();}

Annotation processing Classes

public class ConstantValidatorHandler implements ConstraintValidator<Constant, String> {    private String constant;    @Override    public void initialize(Constant constraintAnnotation) {        //获取设置的字段值        this.constant = constraintAnnotation.value();    }    @Override    public boolean isValid(String value, ConstraintValidatorContext context) {        //判断参数是否等于设置的字段值,返回结果        return constant.equals(value);    }}

Use

    @Constant(message = "verson只能为1.0",value="1.0")    String version;

Run:

At this point, the custom annotations are in effect. You can develop according to the actual needs.

You can see that when the checksum is not passed, the return of the exception information is not friendly, at this time, the use of unified exception processing, check exceptions to special processing, in particular, for the exception handling class
There are several situations (request entities annotated by @requestbody and @requestparam, check exception classes are different)

@ExceptionHandler (methodargumentnotvalidexception.class) public map<string,object> handlebindexception (        Methodargumentnotvalidexception ex) {Fielderror fielderror = Ex.getbindingresult (). Getfielderror ();        Log.info ("parameter check exception: {} ({})", Fielderror.getdefaultmessage (), Fielderror.getfield ());        map<string,object> result = new hashmap<string,object> ();        Result.put ("Respcode", "01002");        Result.put ("Respmsg", Fielderror.getdefaultmessage ());    return result;        } @ExceptionHandler (Bindexception.class) public map<string,object> handlebindexception (Bindexception ex) { Verify that the parameter check except for the requestbody annotation corresponds to the bindingresult of beanpropertybindingresult fielderror fielderror = Ex.getbindi        Ngresult (). Getfielderror ();        Log.info ("Required check exception: {} ({})", Fielderror.getdefaultmessage (), Fielderror.getfield ());        map<string,object> result = new hashmap<string,object> ();        Result.put ("Respcode", "01002"); ResULt.put ("Respmsg", Fielderror.getdefaultmessage ());    return result; }

After launch, the prompt is friendly.

So it is necessary to unify the anomaly.

Summarize

This chapter is mainly to explain the uniform exception handling and the validity of the data verification, while a simple implementation of a custom annotation class, when you meet the existing annotations can not be resolved by the form of a custom, of course, for general purpose, the use @Pattern(正则表达式) is basically achievable.

At last

At present, many big guys on the internet have a springboot series of tutorials, if there is a similar, please forgive me. This article is the author in front of the computer word knocking, each step is practice. If there is something wrong in the text, also hope to put forward, thank you.

Cliché
    • Personal QQ:499452441
    • Public Number:lqdevOps

Personal blog: https://blog.lqdev.cn

Complete Example: chapter-8

Original address: http://blog.lqdev.cn/2018/07/20/springboot/chapter-eight/

Springboot | The eighth chapter: Unification anomaly, data check processing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.