[Spring Boot] Return byte array by Jackson

Spring Boot에서 Jackson을 이용하여 byte Array 반환하는 방법에 대해서 소개합니다.

스프링을 이용하여 개발을 하던 중, 이미지를 가공하여 클라이언트에 내려줘야 하는 요구사항이 생겼습니다. 이미지는 Java Application 내에서는 Byte Array로, DB에서는 Binary 형태로 데이터를 핸들링하거나 저장하고 있습니다. DB와 Java 사이에서 데이터가 깨지거나 하는 등의 문제는 없었지만, 데이터를 API로 제공하려고 할 때 문제가 발생했습니다.

문제는 Server to Server로 Byte Array를 전달하려고 할 때, 바이트 배열 형태가 아닌 String 형태로 반환이 되었고, 이를 해결하기 위해 다음과 같은 방법을 사용했습니다.

Json Serialize in Jackson

스프링 부트를 사용하게 되면 디폴트 data serializer로 Jackson이 설정 되어있습니다. 문제가 발생한 원인은 이 Jackson의 디폴트 설정 때문입니다. Jackson의 디폴트 설정에서는 Byte Array에 대한 Json Serialize 설정이 되어 있지 않기 때문에 JsonSerialzer 클래스를 상속받아 구현을 해주어야합니다.

public class ByteArraySerializer extends JsonSerializer<byte[]> {

    @Override
    public void serialize(byte[] bytes, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
        jsonGenerator.writeStartArray();

        for (byte b : bytes) {
            jsonGenerator.writeNumber(unsignedToBytes(b));
        }

        jsonGenerator.writeEndArray();
    }

    private static int unsignedToBytes(byte b) {
        return b & 0xFF;
    }

}

위와 같이 구현해주시면, spring boot가 구동될 때, Json Serializer > Byte Array 타입에 대한 설정이 세팅됩니다.

class Something {
  private String name;
  private byte[] binary;

  @JsonSerialize(using= ByteArraySerializer.class)
  public byte[] getBinary() {
    return binary;
  }
}

그리고 해당 byte[] 타입의 getter에 위와 같이 어노테이션을 붙여주시면 됩니다. 참고로 Jackson serializer standard 패키지에도 ByteArraySerializer(com.fasterxml.jackson.databind.ser.std.ByteArraySerializer) 클래스가 존재하지만, 제가 해당 클래스로 설정을 했을 때는 제대로 동작을 하지 않았습니다.

자신의 상황에 맞게 구현하시면 될 것 같습니다.

맺음

Spring Boot에서 Jackson을 이용하여 byte Array 반환하는 방법에 대해서 알아보았습니다. 궁금하신 점이나 이상한 점은 댓글로 부탁드리겠습니다.

감사합니다.