SpringBoot学习笔记——校验

JSR-303提供了一些注解,将其放到属性上,可以限制这些属性的值。

参考:Spring MVC学习笔记——JSR303介绍及最佳实践

校验放在DTO层上,不要和数据库交互的model层混用

关于model,VO等的区别,参考:Spring MVC学习笔记——POJO和DispatcherServlet

如何赋值,参考:优雅的使用BeanUtils对List集合的操作

DTO和DO的转换,可以使用BeanUtils,参考:设计之道-controller层的设计

也可以使用ModelMapper,参考:Spring Boot DTO示例:实体到DTO的转换

如果使用的springboot版本大于2.3.x,需要额外引用依赖

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.1.Final</version>
</dependency>

参考:使用SpringBoot进行优雅的数据验证

定义dto层或者vo层,添加 @NotEmpty注解 和 @Size注解,并设置分组校验,即在Post请求或者Put请求的时候进行校验

import com.example.demo.core.valid.Post;
import com.example.demo.core.valid.Put;
import com.example.demo.model.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO {

    @NotEmpty(groups = Post.class, message = "注册时username字段不能为空")
    @Size(groups = {Post.class, Put.class}, min = 3, max = 120)
    private String username;

    private String password;

    public static User convert(UserDTO dto) {
        User user = new User();
        BeanUtils.copyProperties(dto, user);
        return user;
    }

    public static UserDTO convertDTO(User user) {
        UserDTO dto = new UserDTO();
        BeanUtils.copyProperties(user, dto);
        return dto;
    }

}

定义Post分组接口

package com.example.demo.core.valid;

public interface Post {
}

定义Put分组接口

package com.example.demo.core.valid;

public interface Put {
}

设置全局异常处理

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ControllerResponseT methodArgumentNotValidException(MethodArgumentNotValidException e) {
        String message = ResultCode.METHOD_ARGUMENT_NOT_VALID.getMessage();
        log.error("参数验证失败 => {}", e.getMessage());
        BindingResult bindingResult = e.getBindingResult();
        List<ObjectError> allErrors = bindingResult.getAllErrors();
        return new ControllerResponseT<>(ResultCode.METHOD_ARGUMENT_NOT_VALID.getCode(), message, allErrors);
    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler({SQLException.class, DataAccessException.class})
    public ControllerResponseT databaseException(final Throwable e) {
        String message = ResultCode.DATABASE_ERROR.getMessage();
        log.error("数据库错误 => {}", e.getMessage());
        return ControllerResponseT.ofFail(ResultCode.DATABASE_ERROR.getCode(), message, e.getMessage());
    }

controller层

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "UserDTO", name = "userDTO", value = "用户", required = true)
    })
    @RequestMapping(path = "/user", method = RequestMethod.POST)
    public ControllerResponseT create(@Validated({Post.class}) @RequestBody UserDTO userDTO) {
        int result = userService.save(UserDTO.convert(userDTO));
        return ControllerResponseT.ofSuccess("success");
    }

如果参数验证错误,则接口返回结果如下

 

posted @ 2016-03-07 17:33  tonglin0325  阅读(212)  评论(0编辑  收藏  举报