Java Spring中的自定义验证



我是Java新手,我刚刚创建了一个spring引导应用程序来练习一下。

我创建了一个控制器来接收一个POST请求json:

{
"team1": {
"score": 10,
"colour": "RED"
},
"team2": {
"score": 3,
"colour": "BLUE"
}
}

控制器:

public @ResponseBody
ResponseEntity<Response<Game>> saveGame(
@Valid @RequestBody PostedGameRequest postedGameRequest
) {
// ...
}

PostedGameRequest得到验证,并且工作得很好,但是有两个属性:PostedGameRequestTeam类型的team1和team2,并且它们没有得到验证。我在那里添加了一些@NotEmpty属性,但这不起作用。

所以现在我创建了一个自定义的TeamValidator,它验证Team中的字段,但是当它失败时,它将只显示我在@Team属性类中指定的消息。如果我能单独验证每个字段就好了。

@Builder
public class PostedGameRequest {
@Team()
private final PostedGameRequestTeam team1;
@Team()
private final PostedGameRequestTeam team2;
public PostedGameRequestTeam getTeam1() {
return team1;
}
public PostedGameRequestTeam getTeam2() {
return team2;
}
}
public class TeamValidator implements ConstraintValidator<Team, PostedGameRequestTeam> {
List<String> colours = Arrays.asList("RED","BLUE");
@Override
public boolean isValid(@Valid PostedGameRequestTeam team, ConstraintValidatorContext context) {
if (team == null || team.getColour() == null || team.getScore() == null) {
return false;
}
if (team.getScore() < 0 || team.getScore() > 11) {
// This will only lead to an invalid team message, should get a message about the score in this case
return false;
}
if (!colours.contains(team.getColour())) {
// This will only lead to an invalid team message, should get a message about the colour in this case
return false;
}
return (team.getId() != null || team.getName() != null);
}
}

我有一种感觉,我没有按照我应该做的去做。为什么我的第一个方法不起作用?是否需要添加什么来使验证器同时运行team1和team2属性而不添加自定义Validator@Team?

代替@NotEmptytry with

@NotNull

这将确保team1和team2总是包含一个不为空的对象

如果您想对team1和team2的每个属性进行更多验证,请在java中进入该对象并向这些字段添加更多注释。对于string属性,您可以添加

@NotNull
@Size (min = 1)

确保它总是包含一个值

也可以在验证中添加@Valid这样你的对象就变成了

public class PostedGameRequest {
@NotNull
@Valid
private final PostedGameRequestTeam team1;
@NotNull
@Valid
private final PostedGameRequestTeam team2;

然后在

里面
public class PostedGameRequestTeam {
@Min(0)
integer score;
@NotNull
@Size (min=1)
String color;
}

编辑:@Size只适用于字符串字段,不适用自定义对象

不要使用处理所有验证逻辑的@Team自定义验证器(我认为这在这种情况下不是很有用),您应该在每个PostedGameRequestTeam对象中单独声明验证注释。

public class PostedGameRequestTeam {
@NotBlank(message = "The team colour value must not be null, empty or blank!")
@TeamColour(message = "The team colour must be RED or BLUE")
private String colour;
@Min(value = 0, message = "The score value must be higher than 0!")
@Max(value = 11, message = "The score value must be lesser than 11!")
private Integer score;
// Getters and Setters
}

请注意,我使用了@Min@Max注释,这是因为javax.validation.constraints.Size只验证字符串的长度。

现在您可以添加@TeamColour的自定义约束验证。

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Constraint(validatedBy = { StatusNotaFiscalValidator.class })
public @interface TeamColour {

String message() default "The team colour must be RED or BLUE!";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
public class TeamColourValidator implements ConstraintValidator<TeamColour, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
boolean valid = true;

if (value != null) {
if (!value.equals("BLUE") && !value.equals("RED")) {
valid = false;
}
}

return valid;
}

}

然后,你应该在你的父对象上添加@NotNull属性,这样你就可以验证具有team对象的JSON主体。

@Builder
public class PostedGameRequest {

@NotNull
@Valid
private final PostedGameRequestTeam team1;
@NotNull
@Valid
private final PostedGameRequestTeam team2;
public PostedGameRequestTeam getTeam1() {
return team1;
}
public PostedGameRequestTeam getTeam2() {
return team2;
}
}
public @ResponseBody
ResponseEntity<Response<Game>> saveGame(
@Valid @RequestBody PostedGameRequest postedGameRequest
) {
// ...
}

这个逻辑处理所有你想使用的级联验证。

相关内容

  • 没有找到相关文章

最新更新