[SPRING] 컨트롤러없이 잭슨으로 객체를 만들 때 유효합니다.
SPRING컨트롤러없이 잭슨으로 객체를 만들 때 유효합니다.
프런트 엔드에서 요청을 보낼 때 내 컨트롤러에서 @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;
하지만 이제 컨트롤러없이 Jackson의 ObjectMapper를 사용하여 객체를 만듭니다. ObjectMapper에이 유효성 검사를 등록하는 방법이 있습니까? 아니면 설정자의 변수를 확인해야합니까?
해결법
-
==============================
1.비 직렬화를 확장하고 비 직렬화 후에 객체의 유효성을 검사 할 수 있습니다. 이 Bean을 등록하려면 SimpleModule을 사용하십시오.
비 직렬화를 확장하고 비 직렬화 후에 객체의 유효성을 검사 할 수 있습니다. 이 Bean을 등록하려면 SimpleModule을 사용하십시오.
유효성 검증이있는 단순한 콩 디시리얼라이저 :
class BeanValidationDeserializer extends BeanDeserializer { private final static ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); private final Validator validator = factory.getValidator(); public BeanValidationDeserializer(BeanDeserializerBase src) { super(src); } @Override public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { Object instance = super.deserialize(p, ctxt); validate(instance); return instance; } private void validate(Object instance) { Set<ConstraintViolation<Object>> violations = validator.validate(instance); if (violations.size() > 0) { StringBuilder msg = new StringBuilder(); msg.append("JSON object is not valid. Reasons (").append(violations.size()).append("): "); for (ConstraintViolation<Object> violation : violations) { msg.append(violation.getMessage()).append(", "); } throw new ConstraintViolationException(msg.toString(), violations); } } }
다음과 같이 사용할 수 있습니다.
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 { public static void main(String[] args) throws Exception { File jsonFile = new File("./resource/test.json").getAbsoluteFile(); SimpleModule validationModule = new SimpleModule(); validationModule.setDeserializerModifier(new BeanDeserializerModifier() { @Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) { if (deserializer instanceof BeanDeserializer) { return new BeanValidationDeserializer((BeanDeserializer) deserializer); } return deserializer; } }); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(validationModule); System.out.println(mapper.readValue(jsonFile, Pojo.class)); } } class Pojo { @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; // getters, setters, toString() }
유효한 JSON 페이로드 :
{ "name": "Jackson", "github": "https://github.com/FasterXML/jackson-databind" }
인쇄물:
Pojo{name='Jackson', github='https://github.com/FasterXML/jackson-databind'}
잘못된 JSON 페이로드의 경우 :
{ "name": "", "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, at BeanValidationDeserializer.validate(JsonApp.java:110) at BeanValidationDeserializer.deserialize(JsonApp.java:97)
참조 :
-
==============================
2.나는 내가 어떻게 그 일을 할 수 있었는지 게시 할 것이다. validator를 구현 한 클래스 만들기 :
나는 내가 어떻게 그 일을 할 수 있었는지 게시 할 것이다. validator를 구현 한 클래스 만들기 :
public class UserValidator implements Validator { private static final int MINIMUM_NAME_LENGTH = 6; @Override public boolean supports(Class<?> clazz) { return User.class.isAssignableFrom(clazz); } public void validate(Object target, Errors errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "Name must be at least 7 characters long."); User foo = (User) target; if(foo.getGithub().length() > 0 && !extensionSpec.getGithub().matches("^(www|http:|https:)+//github.com/.+/.+$")){ errors.rejectValue("github", "Github must match http://github.com/:user/:repo"); } if (errors.getFieldErrorCount("name") == 0 && foo.getName().trim().length() < MINIMUM_NAME_LENGTH) { errors.rejectValue("name", "Name must be at least 7 characters"); } } }
그런 다음 바인딩 된 결과를 가져온 다음 객체의 유효성을 검사하여 직렬화되지 않은 객체로 databinder를 만듭니다.
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()){ throw new BindException(bindingResult); }
또한 응답 본문에서 errorCodes를 사용하려면 다음을 수행하십시오.
@ExceptionHandler ResponseEntity handleBindException(BindException e){ return ResponseEntity .status(HttpStatus.BAD_REQUEST) .body(e.getBindingResult().getAllErrors() .stream() .map(DefaultMessageSourceResolvable::getCode) .toArray()); }
from https://stackoverflow.com/questions/55457754/valid-when-creating-objects-with-jackson-without-controller by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Boot : @Bean annotated 메소드 내에서 명령 행 인자 가져 오기 (0) | 2019.07.13 |
---|---|
[SPRING] OAuth2.0 - 프론트 엔드와 백엔드가 다른 서버에서 실행되는 GitHub를 사용한 인증. CORS 오류 (0) | 2019.07.13 |
[SPRING] Spring에서 @Async 호출이 완료되었는지 확인하는 방법은 무엇입니까? (0) | 2019.07.13 |
[SPRING] 스프링 부트 내의 전략 (0) | 2019.07.13 |
[SPRING] GSSException : 유효한 자격 증명이 제공되지 않는다 (기구 레벨 : Kerberos tgt를 찾지 못했습니다) (0) | 2019.07.13 |