HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/
Spring
Spring
/
🥾
Message Converter
🥾

Message Converter

MessageConverterByteArrayHttpMessageConverterAbstractJackson2HttpMessageConverter 의 request response cycle에서의 역할xml MessageConverter추가하기xStream에서 ConversionError 이슈 — No converter available

MessageConverter

notion image
  • Spring MVC에서는 HttpMessageConverter interface를 이용하여 Http request 와 response를 변환시켜줌. 예를 들어 java object 가 json(by using the Jackson Library)으로 변환되거나 xml( jackson xml extension)으로 변환되는 부분을 실행해줌
public interface GenericHttpMessageConverter<T> extends HttpMessageConverter<T> { boolean canRead(Type type, @Nullable Class<?> contextClass, @Nullable MediaType mediaType); T read(Type type, @Nullable Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; boolean canWrite(@Nullable Type type, Class<?> clazz, @Nullable MediaType mediaType); void write(T t, @Nullable Type type, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
  • 하나의 MessageConverter가 읽는것과 쓰는 것을 다 함. Content negotiation을 해서 header에 전달하는 accept, Content-type을 보고 해당 MessageConverter가 동작할 지 말지를 결정하는 것

ByteArrayHttpMessageConverter

@PostMapping("/upload") public ApiResponse<AssetUploadResponse> uploadFile(@RequestParam String path, @RequestBody byte[] data) { assetService.upload(path, data); return ApiResponse.ok(List.of(new AssetUploadResponse(path))); }
curl http://localhost:8080/assets/upload\?path\=testfolder1/testfolder2/ohho.pdf --request POST --data-binary "@test.pdf" -H "Content-Type:application/octet-stream" -i
  • 위와 같은 상황에서 @RequestBody byte[] 의 타입으로 변환할 때, content negotation을 진행하여, 데이터가 바이트 배열이면 ByteArrayHttpMessageConverter가 동작하여 message convert를 진행하게 됨
  • Content-Type을 임의로 다른 값을 넣어서 POST 날려봤는데도 ByteArrayHttpMessageConverter 클래스가 동작함

AbstractJackson2HttpMessageConverter 의 request response cycle에서의 역할

@RequestBody에서는 setter가 필요없다? → @RequestBody(json → object)에서는 내부적으로 objectMapper.readValue를 이용하기 때문에 default 생성자가 필요함. setter는 필요없음
@PostMapping("/test") public CreateOrderRequest test(@RequestBody CreateOrderRequest createOrderRequest){ System.out.println(createOrderRequest.getName() + " " + createOrderRequest.getEmail()); return createOrderRequest; }
  • request
  • DispatcherServlet — doDispatch( )
  • AbstractHandlerMethodAdapter — handle( ) . . . . (내부 호출 스택 . . )
 
🧑‍🤝‍🧑
Object Mapper
  • AbstractJackson2HttpMessageConverter — read( ) 메서드 호출
    • JSON데이터를 objectMapper를 이용하여 Java Object로 매핑 (deserialize)
  • AbstractJackson2HttpMessageConverter — writeInternal( ) 메서드 호출
    • objectMapper에서 serialize할 클래스의 getter를 이용함 (serialize)
 
  • response
 

xml MessageConverter추가하기

  • WebMvcConfigurer 클래스를 extend 하며 extendMessageConverters() 함수를 오버라이드 하면 됨
@Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { MarshallingHttpMessageConverter messageConverter = new MarshallingHttpMessageConverter(); XStreamMarshaller xStreamMarshaller = new XStreamMarshaller(); messageConverter.setMarshaller(xStreamMarshaller); messageConverter.setUnmarshaller(xStreamMarshaller); converters.add(0, messageConverter); // 이 부분은 json object mapper에서 serializer의 내용을 추가하는 부분임 var javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME)); var modules = Jackson2ObjectMapperBuilder.json().modules(javaTimeModule); converters.add(1, new MappingJackson2HttpMessageConverter(modules.build())); }

xStream에서 ConversionError 이슈 — No converter available

  • List.of 로 생성한 ImmutableCollections 클래스와 Arrays.asList(..) 으로 생성한 List에 대해 conversion이 지원이 잘 안됨 → Fails on Java 16 for java.util.Arrays$ArrayList and java.util.Collections$EmptyList