@Valid没有使用Spring Boot使用JAX-RS

问题描述 投票:9回答:5

我无法获得验证工作。我有这个简单的端点,它是Spring Boot应用程序的一部分:

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(@Valid UserDTO userDTO, @Context UriInfo uriInfo) {
    User user = UserParser.parse(userDTO);
    userService.save(user);
    final URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build();
    return Response.created(uri).build();
}

然后,UserDTO验证:

@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserDTO {

    private Long id;

    // redundant validations, for testing
    @NotNull
    @Size(min = 5, max = 80, message = "First name too short")
    @NotBlank(message = "First name blank")
    @NotEmpty(message = "First name empty")
    private String firstName;

    @NotNull
    @Size(min = 2, max = 80, message = "Last name too short")
    private String lastName;

    @NotNull
    private String email;

}

它总是处理任何请求,即使是空字段。我甚至创建了一个测试端点,以查看问题是否在DTO内部进行了验证

@Path("/validator/{testInt}")
@GET
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String validator(@Valid @Min(value = 30, message = "testInt too small") @PathParam("testInt") Integer testInt) {
    return String.valueOf(testInt);
}

但这也不起作用,它很乐意返回它收到的任何int。如果重要,我的端点是@Service,这是我的maven依赖树的相关部分:

[INFO] +- org.glassfish.jersey.ext:jersey-bean-validation:jar:2.22.1:compile
[INFO] |  +- org.glassfish.hk2.external:javax.inject:jar:2.4.0-b31:compile
[INFO] |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  +- org.hibernate:hibernate-validator:jar:5.2.2.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.1.0:compile
[INFO] |  +- javax.el:javax.el-api:jar:2.2.4:compile
[INFO] |  \- org.glassfish.web:javax.el:jar:2.2.4:compile

我还在HibernateValidator中设置了断点,并看到它的两个方法被调用,所以看起来它正在运行。只是没有验证。

编辑:我的球衣配置

public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(RequestContextFilter.class);
        register(LoggingFilter.class);
        register(JacksonFeature.class);
        packages("com");
    }
}
java validation jersey spring-boot hibernate-validator
5个回答
1
投票

这个问题是在几年前提出的,但是对于所有使用Stack Overflow作为知识数据库的人来说,我想记录一个适合我的其他解决方案。

尽管有相反的文档,我不得不用@Validated注释控制器类,并在Spring Boot(v2.1.3.RELEASE)中使用Hibernate(5.3.7.Final)和Hibernate Validator(6.0.14.Final)上下文在方法级别使用@Valid。如果两个注释中的一个丢失,我也得到了上面提到的错误场景。

@RestController
@RequestMapping("/users")
@Validated
public class UserController {

  @RequestMapping(value = "/create", method = RequestMethod.POST)
  public User saveUser(@RequestBody @Valid UserDto user) {
    <your service call>
  }
}

0
投票

如果重要,我的端点是@Service

尝试将构造型设置为@Controller

检查是否在Web配置中定义了此bean。

@Bean
    public javax.validation.Validator validator() {
        return new org.springframework.validation.beanvalidation.LocalValidatorFactoryBean();
    }

还要检查你的配置是否有@EnableWebMvc注释


0
投票

ValidationFeature可根据泽西2.0自动发现。您不必明确注册它。

在jersey资源配置中包含标志property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true),以便在响应中发送验证消息。

确保Jersey-bean-validation.jar在类路径上(在你的情况下它已经是)。

简单的例子,

//Web Resource
@Path("/accounts")
public Object getaccount(@Valid @BeanParam AccountRequest);

public class AccountRequest {
@NotNull
private String accountId;
} 

参考,https://jersey.java.net/documentation/latest/bean-validation.html


0
投票

将以下配置添加到JerseyConfig方法中

public JerseyConfig()
{
    register(YourEndpoint.class);
    property(org.glassfish.jersey.server.ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
}

-1
投票

@Funtik关于使它成为@Controller的建议值得一试,但我怀疑你的问题是你没有处理控制器中的错误。

我不是这方面的专家,所以建议你做一些进一步阅读,但我认为你需要添加一个BindingResult,它将在验证错误的情况下填充。然后测试它,并做出适当的响应。所以,我将你的控制器更改为:

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(@Valid UserDTO userDTO, BindingResult bindingResult, @Context UriInfo uriInfo) {
  if (bindingResult.hasErrors()) {
    return Response... // some error code, or however you want to handle validation errors
  }

  User user = UserParser.parse(userDTO);
  userService.save(user);
  final URI uri = uriInfo.getAbsolutePathBuilder().path(String.valueOf(user.getId())).build();
  return Response.created(uri).build();
}

它现在可能不是一个问题,但如果你在方法中添加一个@ModelAttribute注释参数,请记住BindingResult参数需要在它之后立即出现,否则事情不起作用。如果你不这样做,我不记得你看到的确切问题,但如果你不知道上述内容,那就很难找到。我肯定已经在Spring文档中看到过它,但是现在找不到this forum post以外的任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.