如何在持久之前启用Spring Bean验证,但忽略HTTP请求

时间:2019-06-23 22:07:11

标签: java spring-boot bean-validation

这是我的情况

class B {
   @NotNull 
   String x;
}

class A {
    @Valid
    B b;

    @NotNull
    String y;
} 

现在我的Http POST请求获得一个class A对象作为有效负载。 String y应该在传入的HTTP请求中进行验证(并且在持久化到数据库之前也应进行验证)。但是,String x不应在传入的HTTP请求中进行验证(并且仅在持久化到DB之前进行验证),因为String x在请求中将为null,并且其值将由完整{之前的业务逻辑来设置{1}}对象被保留。

有什么办法可以做到这一点?

3 个答案:

答案 0 :(得分:1)

我认为您缺少在参数上添加@Vaild注释的信息,该注释将在控制器层中进行验证。

@RestController
public class AController {

    @PostMapping("/a")
    ResponseEntity<String> addA(@Valid @RequestBody A a) {
        // persisting the a entity 
        return ResponseEntity.ok("A is valid");
    }
}

答案 1 :(得分:1)

如果可以编辑这些对象,则可以利用验证组;

class B {
    @NotNull(groups = Ignored.class)
    String x;
}

class A {
    @Valid
    B b;

    @NotNull
    String y;
} 

Ignored在哪里;

import javax.validation.groups.Default;

public interface Ignored extends Default {
}

如果您的控制器未定义该组,则其下的任何注释都将被忽略,因此您的要求将得到满足,请求中将忽略B.x的验证,但A的其他字段将被验证。但是我不是100%确定验证将在db端应用,您可以尝试吗?

否则,您可以尝试做;

@RestController
public class Controller {

    @PostMapping("/etc")
    ResponseEntity<String> addA(@RequestBody A a) { //disabled validation here
        B tempB = a.getB();
        a.setB(null);
        validateA(a);
        a.setB(tempB);
        // continue logic
    }
}

validateA()在哪里;

import org.springframework.validation.annotation.Validated;

@Validated
public class Validator {

    public void validateA(@Valid A a) {
        // nothing here
    }
}

这是一个丑陋的解决方案,但是仍然有解决方案...

答案 2 :(得分:1)

@Jonathan解释说,实际上,如果“ @Valid”注释未在参数前面加上前缀,则不会造成影响。

要在持久之前启用验证,其工作方式如下:

@Repository
@Validated
public MyDao {
    public void insertA(@Valid A a){
        //logic here
    }

}

@Validated(org.springframework.validation.annotation.Validated)是启用参数验证的关键。它对我有用。