October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk9 min

Content Negotiation and Message Converters in Spring MVC: Content-Type, Accept, and Jackson

A practical guide to Spring MVC content negotiation: how Content-Type and Accept differ, how consumes and produces filter handlers, where Jackson's message converter fits, and how to troubleshoot 406 and 415 responses.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Spring MVC handles a JSON endpoint in two stages. First, request headers and handler mapping decide whether a handler is eligible and which response media types are acceptable. Second, a message converter reads the request body into a Java type or writes a returned Java value to the response body. Jackson’s converter does the JSON work in the second stage. It does not perform HTTP content negotiation. When a request returns 406 Not Acceptable or 415 Unsupported Media Type, the cause is usually in the first stage, or in whether a converter can handle the Java type and media type in the second.

Two headers, two jobs

Most confusion about Spring content negotiation comes from treating Content-Type and Accept as two versions of the same thing. They describe different messages and are checked by different parts of Spring MVC.

As an Amazon Associate I earn from qualifying purchases.

Header Sent by Describes Checked against in Spring MVC
Content-Type Whoever sends a body (usually the client on a POST, PUT, or PATCH) The media type of the body actually being sent The handler’s consumes condition, then whether a converter can read the body into the target Java type
Accept The client, as a preference Response media types the client is willing to receive The handler’s produces condition, the requested-media-type strategy, then whether a converter can write the returned value as the selected media type

RFC 9110 (HTTP Semantics, 2022) describes Accept as a request preference used in proactive negotiation, where the server chooses a response representation based on the client’s stated preferences. Content-Type labels the representation carried in a message. For an incoming JSON request, it tells Spring which kind of body it is being asked to read.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How handler mapping constrains a request

Before any body is converted, the handler mapping step filters candidate handlers using the media-type conditions declared on the mapping. These conditions do not convert anything. They decide whether a method is a match at all.

consumes: the request body

consumes is matched against the request’s Content-Type. In the following controller, a request whose body is text/plain does not reach the method:

@PostMapping(value = "/orders", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Order> create(@RequestBody OrderRequest request) {
    // ...
}

If no handler on the path accepts the body’s media type, Spring rejects the request with 415. This happens before any converter attempts to read the body.

produces: the response

produces constrains what the handler can return. It is matched against the acceptable media types derived from the request, which normally means the Accept header. A method declared with produces = "application/json" is a poor fit for a client that sends Accept: application/xml, and Spring can answer 406 when no candidate matches.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A produces value also narrows what a converter must be able to write. Declaring produces does not make a converter exist. It only tells Spring which media type the converter has to produce.

Where the response format comes from

Spring MVC resolves the requested media types through a content negotiation strategy. In the current Spring Framework reference, the Accept header is the default strategy. If URL-based selection is needed, the reference recommends a query parameter strategy over path extensions. Path extensions still exist as an option, but Spring advises against preferring them.

Strategy How the format is expressed Trade-offs
Accept header (default) Client sends Accept: application/json One URI can serve several representations, so shared caches must vary on Accept (origin servers signal this with a Vary response header). Clients that do not set Accept get whatever default Spring selects, so setting it explicitly matters for API consumers.
Query parameter (Spring’s recommended URL-based option) For example, /orders/42?format=json Easy to test in a browser and to bookmark. Each format has its own URI, which suits caching. Its parameter name is part of your public API, so changing it breaks clients.
Path extension (an option Spring advises against preferring) For example, /orders/42.json Visible in the URL, but it complicates URI templates and can collide with paths that contain dots. It is less preferred in current Spring guidance, so new APIs should have a specific reason to choose it.

Whichever strategy you choose, check it with an explicit request. Sending Accept and watching the status and Content-Type of the response is the quickest way to see what Spring selected.

What HttpMessageConverter does

The Spring Framework Reference, in its section on HTTP message conversion, describes the module this way: “The spring-web module contains the HttpMessageConverter interface for reading and writing the body of HTTP requests and responses through InputStream and OutputStream.”

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A converter answers two questions. Can it read this Java type from this media type? Can it write this Java type as this media type? Spring asks each registered converter in order and uses the first one that can handle the case. That is why converter order and the list’s contents can change the result. A custom converter placed early can intercept types that Jackson would otherwise handle.

Jackson’s converter is one entry in that list. When Jackson is on the classpath, Spring registers a converter that uses a Jackson ObjectMapper to map between JSON and Java objects. Its default supported media type is application/json. It handles JSON bodies; it does not handle other formats such as XML or form data, which other converters cover.

Configuring MappingJackson2HttpMessageConverter in Spring Framework 6.2

The Spring Framework 6.2 reference documents MappingJackson2HttpMessageConverter as a Jackson 2 converter backed by an ObjectMapper. It requires com.fasterxml.jackson.core:jackson-databind on the classpath. Manage the version through your Spring Boot parent or your Jackson BOM, and confirm that it matches the Jackson line your Framework release expects.

Two extension points exist in Framework 6.2, and they behave differently:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Method on WebMvcConfigurer Default converters Use it when
configureMessageConverters(List<HttpMessageConverter<?>> converters) Replaced. Any converter you do not add is gone. You need full control and are willing to register every converter your application uses.
extendMessageConverters(List<HttpMessageConverter<?>> converters) Retained. The list already contains the defaults, and you add to or modify it. You want to tune one converter, such as the Jackson converter’s mapper, or add a converter while keeping the defaults.

For most applications the second method is the one to use. This example enables indented output on the Jackson converter that Spring already registered:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter jackson) {
                jackson.getObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true);
            }
        }
    }
}

This change applies to every JSON response, so it suits development diagnostics more than production APIs. For production, prefer configuring the mapper’s features and modules deliberately, and test serialization output against your clients.

Spring Boot

Spring Boot’s documentation for 6.2-based applications says that any detected HttpMessageConverter beans are added in addition to the default converters. Boot therefore does not replace the defaults when you declare a converter bean. It recommends its HttpMessageConverters mechanism for registering converters, or extending the list with extendMessageConverters().

In a Boot application, avoid copying a bare configureMessageConverters() override from an older example. It replaces the converter list that Boot’s auto-configuration has built, so JSON, string, and other defaults can disappear and the failure may show up later as a 406 or 415 in an unrelated endpoint. Check Boot’s Jackson and converter documentation for your release before changing the list. Mapper customization in Boot is typically done through configuration properties or a Jackson customization bean, not by building a new mapper.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Spring Framework 7 and the Jackson 3 converter

Spring Framework 7.0 changes the Jackson story. In the 7.0.9 API documentation, MappingJackson2HttpMessageConverter is marked deprecated since 7.0, for removal, in favor of JacksonJsonHttpMessageConverter. The replacement uses Jackson 3, whose mapper type is JsonMapper. Those 7.0.9 pages were the current stable reference when this article was prepared, so check the latest 7.0.x patch before you upgrade.

Element Spring Framework 6.2 (Jackson 2) Spring Framework 7.0 (Jackson 3)
Converter class MappingJackson2HttpMessageConverter JacksonJsonHttpMessageConverter
Mapper type ObjectMapper (Jackson 2 databind) JsonMapper (Jackson 3)
Status Current in the 6.2 line Jackson 2 class deprecated since 7.0 for removal; the Jackson 3 class is the replacement
Dependency com.fasterxml.jackson.core:jackson-databind Jackson 3 artifacts; take the exact coordinates from the Jackson 3 documentation for your version

Keep the Jackson generation consistent within one application. Do not mix a Jackson 2 converter example with Jackson 3 imports, and do not register both converters for the same JSON media type unless you have a reason and have checked which one wins. Expect a compiler or IDE deprecation warning wherever source still references the Jackson 2 converter on Framework 7.0; the warning is the signal to plan the move, and it is not itself a runtime failure.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting

406 Not Acceptable

Spring returns 406 when the request’s acceptable media types do not match anything the handler can produce, or when no converter can write the returned value in a selected type. RFC 9110 permits a server to respond 406 when no available representation is acceptable, but it also permits the server to disregard the Accept preference. Spring’s behavior follows its own configuration, so diagnose the mapping and converter rather than assuming the standard requires a particular result.

  1. Send the exact request and note the Accept value: curl -i -H "Accept: application/xml" http://localhost:8080/orders/42. Replace the host, port, and path with your own.
  2. Compare that value with the endpoint’s produces attribute. If the method declares only application/json, an application/xml request cannot match it.
  3. Repeat the request with Accept: application/json. If this succeeds, the mismatch is in the client’s preference or the endpoint’s declared types, not in the converter.
  4. If the request is correct and the response is still 406, check that a converter can write the returned Java type as the selected media type. A returned type that Jackson cannot serialize, or a type with no matching converter, produces this outcome too.
  5. If the endpoint is a Boot application, check whether custom converter configuration removed the defaults, as described above.

415 Unsupported Media Type

Spring returns 415 when the request body’s Content-Type does not satisfy any consumes condition on the matching handler, or when no converter can read the body into the target parameter type.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Check the request’s actual Content-Type. A common cause is a missing header, so the body is treated as an unsupported type, or a client sends text/plain where JSON was intended.
  • Check the consumes value on the handler. If it is application/json, a request with Content-Type: text/plain should receive 415 from the mapping stage. That is the expected behavior of the condition, not a Jackson error.
  • If the Content-Type is correct and the handler matches, check whether the converter can read the target type. An unsupported target type, or a JSON structure that does not bind to the Java class, can surface as a different error depending on configuration, so read the full exception chain before concluding.

Unexpected JSON, XML, or converter selection

When a response comes back in a format you did not expect, the converter list is the first thing to inspect. Converters are consulted in order, and the first capable converter wins. A short diagnostic in extendMessageConverters() that logs the class name and supported media types of each entry will show the effective list at startup. Remove the diagnostic once the cause is found.

Spring 7 deprecation warning

  • Search the codebase for MappingJackson2HttpMessageConverter and for Jackson 2 imports such as com.fasterxml.jackson.databind.ObjectMapper used in converter configuration.
  • On Framework 7.0, plan the migration to JacksonJsonHttpMessageConverter. Verify the Spring Boot, Jackson, and Framework version compatibility in each project’s release documentation before changing the dependencies.
  • Test serialization of dates, null handling, and custom serializers after the move, since mapper defaults and module setup are where Jackson 2 and 3 differ most in practice.

Exact exception text and status outcomes depend on the Framework version, controller signature, selected handler, converter order, Boot auto-configuration, and client headers. Reproduce the case with the same versions before trusting a fix.

Which setup to use

Situation Recommended approach
Spring Framework 6.2 with Spring Boot Rely on Boot’s converter detection and mapper configuration. Add converters as beans, or use extendMessageConverters(). Avoid configureMessageConverters() unless you are replacing the whole list on purpose.
Spring Framework 6.2 without Boot Use extendMessageConverters() to adjust the Jackson 2 converter while keeping the defaults.
New code on Spring Framework 7.0 Use JacksonJsonHttpMessageConverter and Jackson 3 types. Do not start new code on MappingJackson2HttpMessageConverter.
Existing 7.0 code that uses the Jackson 2 converter Keep it working for now, record the deprecation, and migrate the converter and mapper types together as one change.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.