Spring/Spring Boot

JSR-303 Errors들을 Json으로 Serialization 해보자

100win10 2020. 6. 25. 02:22

 

  • JSR-303 bean validation이 끝나게 되면 Errors에 error들이 담기게 된다.
  • 기본적인 도메인들은 자바 빈 스펙을 따르기 때문에
  • BeanSerializer에 의해서  Serialization/Deserialization 이 가능하다. ( 스프링의 경우 ObjectMapper 이용 )
  • 하지만 Errors들은 불가능하다.

 

 

다음의 예를 봐보자.

 

  • 해당 Person에 name과 age가 담기지 않았다면 errors가 담기게 될 것이다.
  • 해당 errors들을 클라이언트들을 위해 Json 형태로 담고 싶다면 
  • @JsonComponent와 JsonSerializer에 serialize 메서드를 오버 라이딩해서 구현 가능하다.

 

 

 

 

 

  • 그렇다면 우선 person에 name과 age를 입력하지 않고 보내서
  • errors에 담게 하고 해당 모습을 디버깅해서 살펴보자.
  • 그리고 이 담긴 모습을 참고해서 ErrorsSerializaer을 만들어보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@JsonComponent
public class ErrorsSerializer extends JsonSerializer<Errors> {
 
    @Override
    public void serialize(Errors errors, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeStartArray();
        errors.getFieldErrors().stream().forEach(e -> {
            try {
                jsonGenerator.writeStartObject();
                jsonGenerator.writeStringField("field", e.getField());
                jsonGenerator.writeStringField("objectName", e.getObjectName());
                jsonGenerator.writeStringField("code", e.getCode());
                jsonGenerator.writeStringField("defaultMessage", e.getDefaultMessage());
                Object rejectedValue = e.getRejectedValue();
                if(rejectedValue != null) {
                    jsonGenerator.writeStringField("rejectedValue", rejectedValue.toString());
                }
                jsonGenerator.writeEndObject();
            } catch(IOException e1) {
                e1.printStackTrace();
            }
        });
        errors.getGlobalErrors().stream().forEach(e -> {
            try {
                jsonGenerator.writeStartObject();
                jsonGenerator.writeStringField("objectName", e.getObjectName());
                jsonGenerator.writeStringField("code", e.getCode());
                jsonGenerator.writeStringField("defaultMessage", e.getDefaultMessage());
                jsonGenerator.writeEndObject();
            } catch(IOException e1) {
                e1.printStackTrace();
            }
        });
        jsonGenerator.writeEndArray();
    }
}
 
cs

 

  • 다음과 같이 JsonSerializer에 serialize 메서드를 오버 라이딩 해주자.
  • 차례로 필드 에러(rejectedValue)를 담고 전역 에러(rejected)를 담을 수 있다.
  • 에러가 여러 개 일 수 있으니 writeArray 배열로 감싸주었다.
  • 마지막으로 ObjectMapper에 등록은 스프링 부트가 제공하는 @JsonComponent를 통해 간단히 해결 가능하다.

 

자세한 내용 참조 : https://www.baeldung.com/spring-boot-jsoncomponent

 

 

 

 

  • 다음에 Test는 age와 name에 @NotEmpty가 있지만 넣지 않았고 errors에 담기게 된다.
  • errors는 Json 형태로 다시 담기게 되고 따라서 리턴 값에는
  • BadRequest 응답, errors에 필드인 objectName 등이 들어있게 된다.