Difference @Validated & @Valid annotations

1. Different specifications of both employed package and the corresponding annotations introduced:

Spring is @Validated annotation framework authentication mechanism to verify the Validation parameters to be used, the use of Spring's specifications JSR-303, JSR-303 standard which is a variant of the specification).

Notes package need to be introduced to: import org.springframework.validation.annotation.Validated;

@Valid javax is provided by using a JSR-303 standard specification.

Notes package need to be introduced to: import javax.validation.Valid;

In addition, @ Valid with BindingResult result parameter calibration can be output directly in accordance with the custom format to where we want.

2. a code examples, when the request is a request Post: @RequestBody calibration parameters

2.1 parameters need to be validated RequetBody:

package com.test.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import java.math.BigDecimal;
import java.util.Map;

@Data
@Accessors(chain = true)
public final class TestDTO {

    @NotBlank(message = "Missing Mandatory Field")
    String id;

    @NotBlank(message = "Missing Mandatory Field")
    String name;

    @NotBlank(message = "Missing Mandatory Field")
    String sex;
}

2.2 TestDTO as the argument Controller

package com.test.controller;

import com.test.model.*;
import com.test.TestService;
import com.accenture.atchk.blockchain.util.CommonUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping(value = "/test/v1.0")
public class TestController {

    private static final ObjectMapper jackson = new ObjectMapper();

    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    TestService testService;

    @Autowired
    public TestController(TestService testService) {
        this.testService = testService;
    }

    @PostMapping(value = "/valid")
    public ResponseEntity<List<OutcomeDTO>> submit(@Valid @RequestBody TestDTO testDTO, BindingResult bindingResult) {

        CommonUtils.parameterChecking(bindingResult);

        String today = OffsetDateTime.now().format(DateTimeFormatter.ofPattern("uuuu-MM-dd"));

        List<OutcomeDTO> outcomeDTOList = testService.submit(today, testDTO.getId(), testDTO);
        logger.info("Record outcome list for TransactionId {}: {}", testDTO.getId(), outcomeDTOList);

        Map<String, MemberAccountTxnDTO> result = testService.recordOutcome(today, transactionDTO.getId() + ":" + UUID.randomUUID().toString(), outcomeDTOList);
        if (result != null) {
            result.forEach((key, value) -> {
                try {
                    logger.info("Record outcome result key {}: {}", key, jackson.writeValueAsString(value));
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
            });
        } else {
            logger.info("Result is null");
        }
        return new ResponseEntity<>(outcomeDTOList, HttpStatus.OK);
    }
}

note:

1.RequestBody would like to join with BindnigResult above adjacent, otherwise the following occurs:

Example code:

    @PatchMapping(value = "/{test1}/tests/{test2}")
    public ResponseEntity<BaseSuccessResponse> test(@Valid @RequestBody RequestBody request,@PathVariable(name = "test1") String test1,BindingResult bindingResult,@PathVariable(name = "test2") String test2) throws Exception {
        CommonUtils.parameterChecking(bindingResult);
        
        BaseSuccessResponse baseSuccessResponse = testService.testValid(request, test1, test2);
        return new ResponseEntity<>(baseSuccessResponse, HttpStatus.OK);
    }

Examples of code analysis: As RequestBody request with an interval between BindingResult parameters, this time on custom parameters exception information does not appear if the time RequestBody in a field is Null!

Such as: error message does not appear as Missing Mandatory Field, but will appear System Exception!

2. If a plurality of requests occur RequestBody parameter in Post, and the BindingResult @Valid necessary to use a plurality, such as:

public void test()( @RequestBody @Valid RequestBody bodyOne, BindingResult result,
                    @RequestBody @Valid RequestBody bodyTwo, BindingResult result2){
      CommonUtils.parameterChecking(result);
      CommonUtils.parameterChecking(result2);
}

2.3 parameter calibrating tools CommomUtils.java

package com.test.util;

import com.test.CustomException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import com.test.enums.Error;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**当想要使得CommonUtils作为Bean使用@Autowired注入时需要使用@Component来生成Bean实例
  *@Autowired 
  *private CommonUtils commonUtils;
  *@Component 
  *public class CommonUtils{}
  **/

public class CommonUtils {

    public static void parameterChecking(BindingResult bindingResult) throws CustomException {
        if (bindingResult.hasErrors()) {
            List<FieldError> listError = bindingResult.getFieldErrors();
            Set<String> parameters = new HashSet<>();
            Iterator keys = listError.iterator();
            FieldError iterator = null;
            while (keys.hasNext()) {
                iterator = (FieldError) keys.next();
                String field = iterator.getField();
                parameters.add(field);
            }
            if (iterator != null) {
                throw new CustomException(Error.getErrorByMessage(iterator.getDefaultMessage()), parameters);
            }
        }
    }
}

4. Examples of two codes, when the request is a Get Request: @RequestParam parameter calibrating

A checksum bean manner, i.e. @Valid notes, there is no way to check RequestParam content, usually in processing Get Request (parameters or less), it will verify the following ways:

package com.test.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/test/v1.0")
public class TestController {

    private static final ObjectMapper jackson = new ObjectMapper();

    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    或者
    @GetMapping(value = "/test")
    public void test(@RequestParam(name = "name", required = true) String name,@RequestParam(name = "sex", required = true) String sex) {
        System.out.println(name + "," + sex);
    }
}

In this case, the parameters needed for verification, require the use of annotations on @Validated where Controller to verify that the effect.

package com.test.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping(value = "/test/v1.0")
@Validated
public class TestController {

    private static final ObjectMapper jackson = new ObjectMapper();

    private static Logger logger = LoggerFactory.getLogger(TestController.class);

    TestService testService;

    @Autowired
    public TestController(TestService testService) {
        this.testService = testService;
    }
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    或者
    @GetMapping(value = "/test")
    public void test( @Range(min = 0, max = 99, message = "年龄只能从0-99")
                      @RequestParam(name = "age", required = true)
                      int age,
                      @Min(value = 160, message = "身高最小只能160")
                      @Max(value = 200, message = "身高最大只能200")
                      @RequestParam(name = "height", required = true)
                      int height) {
        System.out.println(age + "," + height);
    }
}

 

Published 22 original articles · won praise 5 · Views 2200

Guess you like

Origin blog.csdn.net/calm_encode/article/details/103815219