在没有控制器的情况下使用杰克逊创建对象时@Valid

我有一个模型,当从前端发送请求时,我在我的控制器中用@Valid验证了该模型:


@NotNull

@Size(min=1, message="Name should be at least 1 character.")

private String name;


@NotNull

@Pattern(regexp = "^https://github.com/.+/.+$", message = "Link to github should match https://github.com/USER/REPOSITORY")

private String github;

但现在我也在用杰克逊的对象映射器创建一个没有控制器的对象。有没有办法在对象映射器中注册此验证,或者我是否应该只检查设置器中的变量?


慕后森
浏览 82回答 2
2回答

智慧大石

您可以在反序列化后扩展和验证对象。要注册此豆,请使用 。BeanDeserializerSimpleModule简单的豆子去蛭蛭验证器:class BeanValidationDeserializer extends BeanDeserializer {&nbsp; &nbsp; private final static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();&nbsp; &nbsp; private final Validator validator = factory.getValidator();&nbsp; &nbsp; public BeanValidationDeserializer(BeanDeserializerBase src) {&nbsp; &nbsp; &nbsp; &nbsp; super(src);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; Object instance = super.deserialize(p, ctxt);&nbsp; &nbsp; &nbsp; &nbsp; validate(instance);&nbsp; &nbsp; &nbsp; &nbsp; return instance;&nbsp; &nbsp; }&nbsp; &nbsp; private void validate(Object instance) {&nbsp; &nbsp; &nbsp; &nbsp; Set<ConstraintViolation<Object>> violations = validator.validate(instance);&nbsp; &nbsp; &nbsp; &nbsp; if (violations.size() > 0) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringBuilder msg = new StringBuilder();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.append("JSON object is not valid. Reasons (").append(violations.size()).append("): ");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (ConstraintViolation<Object> violation : violations) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.append(violation.getMessage()).append(", ");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ConstraintViolationException(msg.toString(), violations);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}我们可以按如下方式使用它:import com.fasterxml.jackson.core.JsonParser;import com.fasterxml.jackson.databind.BeanDescription;import com.fasterxml.jackson.databind.DeserializationConfig;import com.fasterxml.jackson.databind.DeserializationContext;import com.fasterxml.jackson.databind.JsonDeserializer;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.deser.BeanDeserializer;import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;import com.fasterxml.jackson.databind.module.SimpleModule;import javax.validation.ConstraintViolation;import javax.validation.ConstraintViolationException;import javax.validation.Validation;import javax.validation.Validator;import javax.validation.ValidatorFactory;import javax.validation.constraints.NotNull;import javax.validation.constraints.Pattern;import javax.validation.constraints.Size;import java.io.File;import java.io.IOException;import java.util.Set;public class JsonApp {&nbsp; &nbsp; public static void main(String[] args) throws Exception {&nbsp; &nbsp; &nbsp; &nbsp; File jsonFile = new File("./resource/test.json").getAbsoluteFile();&nbsp; &nbsp; &nbsp; &nbsp; SimpleModule validationModule = new SimpleModule();&nbsp; &nbsp; &nbsp; &nbsp; validationModule.setDeserializerModifier(new BeanDeserializerModifier() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (deserializer instanceof BeanDeserializer) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new BeanValidationDeserializer((BeanDeserializer) deserializer);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return deserializer;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; ObjectMapper mapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; mapper.registerModule(validationModule);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(mapper.readValue(jsonFile, Pojo.class));&nbsp; &nbsp; }}class Pojo {&nbsp; &nbsp; @NotNull&nbsp; &nbsp; @Size(min = 1, message = "Name should be at least 1 character.")&nbsp; &nbsp; private String name;&nbsp; &nbsp; @NotNull&nbsp; &nbsp; @Pattern(regexp = "^https://github.com/.+/.+$", message = "Link to github should match https://github.com/USER/REPOSITORY")&nbsp; &nbsp; private String github;&nbsp; &nbsp; // getters, setters, toString()}对于有效有效负载:JSON{&nbsp; "name": "Jackson",&nbsp; "github": "https://github.com/FasterXML/jackson-databind"}指纹:Pojo{name='Jackson', github='https://github.com/FasterXML/jackson-databind'}对于无效的有效负载:JSON{&nbsp; "name": "",&nbsp; "github": "https://git-hub.com/FasterXML/jackson-databind"}指纹:Exception in thread "main" javax.validation.ConstraintViolationException: JSON object is not valid. Reasons (2): Name should be at least 1 character., Link to github should match https://github.com/USER/REPOSITORY,&nbsp;&nbsp; &nbsp; at BeanValidationDeserializer.validate(JsonApp.java:110)&nbsp; &nbsp; at BeanValidationDeserializer.deserialize(JsonApp.java:97)

喵喔喔

我还将发布我如何设法做到这一点。创建实现验证程序的类:public class UserValidator implements Validator {&nbsp; &nbsp; private static final int MINIMUM_NAME_LENGTH = 6;&nbsp; &nbsp; @Override&nbsp; &nbsp; public boolean supports(Class<?> clazz) {&nbsp; &nbsp; &nbsp; &nbsp; return User.class.isAssignableFrom(clazz);&nbsp; &nbsp; }&nbsp; &nbsp; public void validate(Object target, Errors errors) {&nbsp; &nbsp; &nbsp; &nbsp; ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "Name must be at least 7 characters long.");&nbsp; &nbsp; &nbsp; &nbsp; User foo = (User) target;&nbsp; &nbsp; &nbsp; &nbsp; if(foo.getGithub().length() > 0 && !extensionSpec.getGithub().matches("^(www|http:|https:)+//github.com/.+/.+$")){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errors.rejectValue("github", "Github must match http://github.com/:user/:repo");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (errors.getFieldErrorCount("name") == 0 && foo.getName().trim().length() < MINIMUM_NAME_LENGTH) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; errors.rejectValue("name", "Name must be at least 7 characters");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}然后使用反序列化对象创建数据明细器,获取绑定结果,然后验证该对象:ObjectMapper mapper = new ObjectMapper();User foo = mapper.readValue(FooJson, User.class);Validator validator = new ObjectValidator();BindingResult bindingResult = new DataBinder(foo).getBindingResult();validator.validate(foo, bindingResult);if(bindingResult.hasErrors()){&nbsp; &nbsp; throw new BindException(bindingResult);}另外,如果要在响应的正文中获取错误代码:@ExceptionHandlerResponseEntity handleBindException(BindException e){&nbsp; &nbsp; return ResponseEntity&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .status(HttpStatus.BAD_REQUEST)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .body(e.getBindingResult().getAllErrors()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(DefaultMessageSourceResolvable::getCode)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .toArray());}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java