JAVA

error serializer

응디 2022. 7. 11. 17:45
json → object로 변환하는과정 (deserialization)
object → json로 변환하는과정 (serialization)

객체는 javaBean 스펙을 준수하고 있어서 BeanSerializer로 json으로 변환이 가능하다.

but, errors는 그 스펙을 준수하고 있지 않아 json으로 변환하려면 직접 serializer를 생성해줘야한다.

 

 

만약 아래처럼 테스트 코드 작성 시 jsonPath에 지정해준 필드를 응답값으로 받고싶다는 것이다.(Errors에서)

하지만 Errors는 json으로 변환이 불가하기 때문에 ErrorSerializer를 생성해준다.

this.mockMvc.perform(post("/api/events")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(this.objectMapper.writeValueAsString(eventDto)))
                .andDo(print())
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$[0].objectName").exists())    // 여기서 부터는 응답관련 -> objectName, field... 등등이 응답에 존재했으면 좋겠다는 의미
                .andExpect(jsonPath("$[0].field").exists())
                .andExpect(jsonPath("$[0].defaultMessage").exists())
                .andExpect(jsonPath("$[0].code").exists())
                .andExpect(jsonPath("$[0].rejectValue").exists())
                ;

 

 

ErrorSerializer.java

package me.whiteship.restapi.common;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.validation.Errors;

import java.io.IOException;

// objectMapper가 이 클래스를 사용하려면 등록을 시켜줘야하는데 그 등록을 spring boot가 제공하는 @JsonComponent를 사용해서 해준다.
@JsonComponent  
public class ErrorsSerializer extends JsonSerializer<Errors> {
    @Override
    public void serialize(Errors errors, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
        gen.writeStartArray();
        errors.getFieldErrors().forEach(e ->{
            try {
                gen.writeStartObject();
                gen.writeStringField("field", e.getField());
                gen.writeStringField("objectName", e.getObjectName());
                gen.writeStringField("code", e.getCode());
                gen.writeStringField("defaultMessage", e.getDefaultMessage());
                Object rejectedValue = e.getRejectedValue();
                if (rejectedValue != null) {
                    gen.writeStringField("rejectValue", rejectedValue.toString());
                }

                gen.writeEndObject();

            } catch (IOException e1) {
                e1.printStackTrace();
            }
        });

        errors.getGlobalErrors().forEach(e ->{
            try {
                gen.writeStartObject();
                gen.writeStringField("objectName", e.getObjectName());
                gen.writeStringField("code", e.getCode());
                gen.writeStringField("defaultMessage", e.getDefaultMessage());
                gen.writeEndObject();
            }catch (IOException e1){
                e1.printStackTrace();
            }
        });
        gen.writeEndArray();
    }
}

 

이렇게 objectMapper에 등록(@JsonComponent가 해줌)하면 자동으로 objectMapper가 사용한다.

아래는 테스트 코드 실행 시 결과 예시 이다.

 

'JAVA' 카테고리의 다른 글

spring restdocs 참고  (0) 2022.07.28
parameter를 이용한 test code  (0) 2022.07.26
testcode 작성 시 description  (0) 2022.07.11
spring boot build 와 실행  (0) 2022.07.06
String vs StringBuffer vs StringBuilder  (0) 2022.07.05