How to Build and Register a Custom HttpMessageConverter in Spring Boot
This guide explains why and how to create a custom HttpMessageConverter in Spring Boot 2.7.12, covering the implementation of the converter, its registration in the MVC configuration, testing with Postman, and the underlying request‑response processing mechanism.
1. Introduction
In Spring MVC, HttpMessageConverter converts HTTP request bodies to Java objects and Java objects to HTTP responses. Spring provides default converters for JSON, XML, text, etc., and supports custom converters for special formats. The annotations @RequestBody and @ResponseBody rely on these converters.
2. Requirement
The API expects request data in a pipe‑separated format like xxx|yyy|zzz|... and returns JSON. While this can be handled without a custom converter, the example demonstrates how to implement one for special needs.
3. Custom HttpMessageConverter Implementation
<code>public class PackHttpMessageConverter implements HttpMessageConverter<Object> {
// Define custom Content‑Type "application/pack"
private static final MediaType PACK = new MediaType("application", "pack", StandardCharsets.UTF_8);
@Override
public boolean canRead(Class<?> clazz, MediaType mediaType) {
return PACK.equals(mediaType);
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return true;
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return Arrays.asList(PACK);
}
@Override
public Object read(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
InputStream is = inputMessage.getBody();
String res = IOUtils.toString(is, StandardCharsets.UTF_8);
if (clazz == Users.class) {
try {
Users target = (Users) clazz.newInstance();
String[] s = res.split("\\|");
target.setId(Long.valueOf(s[0]));
target.setName(s[1]);
target.setAge(Integer.valueOf(s[2]));
target.setIdNo(s[3]);
return target;
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
outputMessage.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
OutputStream os = outputMessage.getBody();
os.write(mapper.writeValueAsString(t).getBytes(StandardCharsets.UTF_8));
os.flush();
}
}
</code>4. Registering the Converter
<code>@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// Add at the first position to give it highest priority
converters.add(0, new PackHttpMessageConverter());
}
}
</code>5. Testing the API
Define a simple controller method:
<code>@PostMapping("/i")
public Object i(@RequestBody Users user) {
System.out.println(handlerAdapter);
return user;
}
</code>Use Postman to send a request with header Content-Type: application/pack . The custom converter reads the pipe‑separated body, creates a Users object, and the write method returns JSON.
6. Underlying Mechanism
When @RequestBody is present, Spring uses RequestResponseBodyMethodProcessor , which extends AbstractMessageConverterMethodProcessor . It iterates over all registered HttpMessageConverter instances, invoking canRead and read for the request, and canWrite and write for the response.
<code>public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter, Type paramType) {
// ... iterate converters, call canRead and read ...
}
}
</code>The same logic applies to response conversion via AbstractMessageConverterMethodArgumentResolver .
7. Conclusion
Custom HttpMessageConverter is a powerful tool in Spring MVC that allows developers to control data transformation flexibly, handling special formats and custom processing requirements.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.