【问题标题】:How to validate data in service layer in spring boot如何在 Spring Boot 中验证服务层中的数据
【发布时间】:2021-06-20 12:56:53
【问题描述】:

控制器:

@RestController
@RequestMapping(path = "api/v1/users")
public class UserController {
    @Autowired
    UserService userService;

    @PostMapping("/register")
    public ResponseEntity<Map<String, String>> registerUser(@RequestBody Map<String, Object> userMap){
        Map<String, String> map = new HashMap<>();

        try {
            String first_name = (String) userMap.get("first_name");
            String last_name = (String) userMap.get("last_name");
            Users user = userService.registerUser(first_name, last_name);

            map.put("message:","User registered successfully");
        }catch(Exception e) {
            map.put("message:",e.getMessage());
            return new ResponseEntity<>(map, HttpStatus.UNAUTHORIZED);
        }

        return new ResponseEntity<>(map, HttpStatus.OK);
    }

}

服务层:

@Service
@Transactional
public class UserServicesImpl implements UserService{
    @Autowired
    UserRepository userRepository;

    @Override
    public Users registerUser(String first_name, String last_name) throws EtAuthException {

        String username = first_name+99;
        Integer userId = userRepository.create(first_namea, last_name);
        return userRepository.findById(userId);
    }
}

存储库:

@Repository
public class UserRepositoryImpl implements UserRepository {

    private final UserRepositoryBasic userRepositoryBasic;

    public UserRepositoryImpl(UserRepositoryBasic userRepositoryBasic) {
        this.userRepositoryBasic = userRepositoryBasic;
    }


    @Override
    public Integer create(String first_name, String last_name) throws EtAuthException {
        try{
            
            Users insertData = userRepositoryBasic.save(new Users(first_name, last_name));
            return insertData.getId();
        }catch (Exception e){
            throw new EtAuthException(e.getMessage());
        }
    }
}

模型/实体:

@Entity
@Table(name="users")
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Integer id;

    @NotBlank(message="First name can not be empty")
    @Column(nullable = false, length = 40)
    private String first_name;

    @NotBlank(message="Last name can not be empty")
    @Column(nullable = false, length = 40)
    private String last_name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirst_name() {
        return first_name;
    }

    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }

    public String getLast_name() {
        return last_name;
    }

    public void setLast_name(String last_name) {
        this.last_name = last_name;
    }

    public Users(String first_name, String last_name) {
        this.first_name = first_name;
        this.last_name = last_name;
    }

    public Users() {
    }
}

我得到的回应是:

我想在服务层进行验证,但无法这样做。验证适用于我的代码实现,但问题是验证消息与我不想显示的包和类名一起显示。如果验证失败,我试图只获取验证错误消息。

我尝试添加 @Valid 注释,但无法获得我正在寻找的响应。

如果验证失败,我正在下方寻找回复。

"message": ["名字不能为空","姓氏不能为空"]

谁能帮我解决这个问题。提前谢谢你。

【问题讨论】:

  • 我不会在控制器的 try/catch 中发送e.getMessage(),而是使用e.getStackTrace()。我知道这是错误的形式(一旦您解决了问题,就恢复该更改),但您只保存了消息 - 我相信完整的堆栈跟踪可能包含您当前缺少的一些重要信息。请在编辑代码时通知我们。

标签: java spring-boot validation


【解决方案1】:

添加一个全局异常处理程序来解析您的错误并以您需要的格式返回错误消息。

    @ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<Object> handleConstraintViolation(
  ConstraintViolationException ex, WebRequest request) {
    List<String> errors = new ArrayList<String>();
    for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
        errors.add(violation.getRootBeanClass().getName() + " " + 
          violation.getPropertyPath() + ": " + violation.getMessage());
    }

    ApiError apiError = 
      new ApiError(HttpStatus.BAD_REQUEST, ex.getLocalizedMessage(), errors);
    return new ResponseEntity<Object>(
      apiError, new HttpHeaders(), apiError.getStatus());
}

Source

【讨论】:

    【解决方案2】:

    您必须为您的控制器中已验证的用户类更改您的 userMap 对象:

    public ResponseEntity<Users> registerUser(@RequestBody @Valid Users){
    Users createdUser = userService.registerUser(user.firstName, user.lastName);
    return ResponseEntity.ok().body(createdUser).build();
    }
    

    这应该只返回 JSON 结构中无效字段的错误消息。

    一个好的做法是使用 DTO 而不是实体类来处理控制器的请求和响应,您可以在此处阅读更多相关信息:

    https://www.amitph.com/spring-entity-to-dto/

    通过这种方式,您可以从实体中选择要显示的字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-26
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 2020-08-15
      • 1970-01-01
      • 2014-02-19
      相关资源
      最近更新 更多