@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON);
//configurer.defaultContentType(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML);
@RestController
public class ExampleServlet {
@GetMapping(
value = "/both",
produces = {
MediaType.APPLICATION_XML_VALUE,
MediaType.APPLICATION_JSON_VALUE
public Set<String> both() {
return Set.of("both");
@GetMapping(
value = "/xml",
produces = {
MediaType.APPLICATION_XML_VALUE
public Set<String> xml() {
return Set.of("xml");
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>untitled</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.8</version>
</parent>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
</dependencies>
</project>
Both can't produce xml:
curl --location --request GET 'localhost:8080/test' --header 'Accept-Encoding: application/xml'
:
[both]
curl --location --request GET 'localhost:8080/both' --header 'Accept-Encoding: application/xml'
:
2023-01-31 11:45:47.436 WARN 38445 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver :
Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation]
So the issue is still relevant: XML media type in content negotiation is not taken into account!
Also the following properties don't help:
spring.mvc.contentnegotiation.media-types.json=application/json
spring.mvc.contentnegotiation.media-types.xml=application/xml
The following still gives json output:
curl --location --request GET 'localhost:8080/both?format=xml' --header 'Accept-Encoding: application/xml'
untitled.zip
Okay, I think Content-Type from clients perspective is wrong in this issue, I probably ment Accept-Encoding.
I think you meant the Accept
request header instead, as using this header with your sample application behaves as expected.
I'm closing this issue now.
I don't understand. Running your sample application, here's the behavior.
With configurer.defaultContentType(MediaType.APPLICATION_JSON);
$ http :8080/both Accept:"*/*"
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json
Date: Tue, 31 Jan 2023 18:36:36 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
"both"
$ http :8080/both Accept:"application/xml"
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/xml
Date: Tue, 31 Jan 2023 18:37:01 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
<item>both</item>
$ http :8080/both Accept:"application/json"
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json
Date: Tue, 31 Jan 2023 18:37:05 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
"both"
Same behavior applies for configurer.defaultContentType(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML);
, as ordering is taken into account (see javadoc).
For example, changing the order with configurer.defaultContentType(MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON);
result in a single behavior change:
$ http :8080/both Accept:"*/*"
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/xml
Date: Tue, 31 Jan 2023 18:39:41 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
<item>both</item>
Using the following configuration properties (which are mentioned in this issue but missing from the sample:
spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.media-types.json=application/json
spring.mvc.contentnegotiation.media-types.xml=application/xml
We can see the parameter used for content negotiation:
$ http -v :8080/both format==json
GET /both?format=json HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/3.2.1
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/json
Date: Tue, 31 Jan 2023 18:44:59 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
"both"
$ http -v :8080/both format==xml
GET /both?format=xml HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: localhost:8080
User-Agent: HTTPie/3.2.1
HTTP/1.1 200
Connection: keep-alive
Content-Type: application/xml
Date: Tue, 31 Jan 2023 18:45:23 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
<item>both</item>
This is all working as expected from my point of view.
Could you explain precisely what the problem is with this behavior?
Your explanation is exactly what I would have expected, but was not when adding the sample app.
Maybe this is a local machine issue. Will try tomorrow and report back!