125

I am trying to use spring-boot-starter-web to create a rest service serving up JSON representations of Java objects. From what I understand this boot-starter-web jar is supposed to handle the conversion to JSON through Jackson automatically but I am instead getting this error.

{ 
  "timestamp": 1423693929568,
  "status": 406,
  "error": "Not Acceptable",
  "exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
  "message": "Could not find acceptable representation"
}

My Controller is this...

@RestController
@RequestMapping(value = "/media")
public class MediaController {
    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public @ResponseBody UploadResult test(@RequestParam(value="data") final String data) {
      String value = "hello, test with data [" + data + "]"; 
      return new UploadResult(value);
    }

    @RequestMapping(value = "/test2", method = RequestMethod.POST)
    public int test2() {
        return 42;
    }

    @RequestMapping(value = "/test3", method = RequestMethod.POST)
    public String test3(@RequestParam(value="data") final String data) {
        String value = "hello, test with data [" + data + "]"; 
        UploadResult upload = new UploadResult(value);
        return upload.value;
    }


    public static class UploadResult {
        private String value;
        public UploadResult(final String value)
        {
            this.value = value;
        }
    }
}

My pom.xml has...

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.2.1.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>1.2.1.RELEASE</version>
    <scope>provided</scope>
</dependency>

mvn dependency:tree shows that spring-boot-starter-web does indeed depend on the jackson2.4 databind and thus should be on the classpath...

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.2.1.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.2.1.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.2.1.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.2.1.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.2.1.RELEASE:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.8:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.8:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.14:runtime
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.4.4:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.4.0:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.4.4:compile
[INFO] |  +- org.hibernate:hibernate-validator:jar:5.1.3.Final:compile
[INFO] |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.0.0:compile
[INFO] |  +- org.springframework:spring-web:jar:4.1.4.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:4.1.4.RELEASE:compile
[INFO] |  |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  |  +- org.springframework:spring-beans:jar:4.1.4.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-context:jar:4.1.4.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:4.1.4.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:4.1.4.RELEASE:compile

... yet calling the test service gives the error mentioned above. test2 and test3 work fine proving that it must just be the attempted conversion to JSON that is failing? Am I missing some configuration problem or annotations? From all the examples I can find, annotating the class for basic Jackson JSON conversion is no longer necessary.

Any help greatly appreciated.

djm.im
  • 3,295
  • 4
  • 30
  • 45
crowmagnumb
  • 6,621
  • 9
  • 33
  • 42
  • 1
    By the way the latest spring (not sure when this was added) does a much better job. Last year sometime I accidentally made this mistake again and instead of the cryptic error above I got an error that told me pretty much exactly what I did wrong (don't remember the text but...). So kudos for the team on improving this. – crowmagnumb Nov 10 '20 at 17:44
  • public getters are required for spring boot exception handlers ... – Muahmmad Tayyib Nov 16 '22 at 19:14

24 Answers24

200

You have no public getters for your UpdateResult, for example :

public static class UploadResult {
    private String value;
    public UploadResult(final String value)
    {
        this.value = value;
    }

    public String getValue() {
       return this.value;
    }
}

I believe by default auto discovery is on and will try to discover your getters. You can disable it with @JsonAutoDetect(getterVisibility=Visibility.NONE), and in your example will result in [].

Nomade
  • 1,760
  • 2
  • 18
  • 33
ikumen
  • 11,275
  • 4
  • 41
  • 41
  • 56
    well spring is very "helpful" with HttpMediaTypeNotAcceptableException error message ... – Michal Bernhard Dec 01 '15 at 14:43
  • 3
    I encoutered the same problem, having an empty class (so far) with no fields or getters. I agree the error message is very "helpful", so thanks a lot. – Vlasec Jan 21 '16 at 15:08
  • 3
    I tried to return `List` but said `produces = MediaType.APPLICATION_XML_VALUE` so Spring doesn't know how to represent the list as XML.. :D obviously... – insan-e Jun 13 '18 at 00:38
  • Wonderfule, i was using lombok, added all arg and no arg anotation and forgotten getter setter completely. Thanks! – silentsudo Sep 24 '19 at 15:15
  • Exactly. I forgot the getters and setters. In fact, the request was incoming with all the fields as null – tufac2 Nov 06 '21 at 07:10
  • I would add, that getter should be named according to `getters naming convention`, if you don't use any special `Jackson` annotations or `Lombok`. Otherwise the getters aren't recognized and you still encounter the issue. – HereAndBeyond Jun 23 '23 at 11:52
27

I had a similar error using spring/jhipster RESTful service (via Postman)

The endpoint was something like:

@RequestMapping(value = "/index-entries/{id}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<IndexEntry> getIndexEntry(@PathVariable Long id) {

I was attempting to call the restful endpoint via Postman with header Accept: text/plain but I needed to use Accept: application/json

wired00
  • 13,930
  • 7
  • 70
  • 73
  • 3
    Yeah, I think "Could not find acceptable representation" will show its ugly head in a myriad of ways. :( – crowmagnumb Feb 24 '17 at 17:43
  • 4
    I had a JSON API, but in one route i was returning `produces = MediaType.TEXT_HTML_VALUE` (raw HTML..). But when an exception was thrown (I wanted a JSON error model), Spring probably didn't know how to convert it to string... :/ When I removed the `produces` part it worked.. :D – insan-e Aug 02 '17 at 13:09
17

If you are using Lombok, make sure it have annotations like @Data or @Getter @Setter in your Response Model class.

Abhishek Sengupta
  • 2,938
  • 1
  • 28
  • 35
  • 1
    This opened my eyes. I have used Lombok but forgot to set it up for eclipse. That's why getter and setters were not getting populating for bean even if I have used the @Data annotation. Thanks – Prabhakar Jan 23 '22 at 02:05
  • 1
    this worked for me. I use Lombok and forgot to add annotations. Thank you. – Himanshu Suthar Jun 15 '22 at 07:48
11

I too was facing a similar issue. In my case the request path was accepting mail id as path variable, so the uri looked like /some/api/test@test.com

And based on path, Spring determined the uri is to fetch some file with ".com" extension and was trying to use different media type for response then intended one. After making path variable into request param it worked for me.

Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
Kranthi Kiran
  • 111
  • 1
  • 3
6

If using @FeignClient, add e.g.

produces = "application/json"

to the @RequestMapping annotation

charlb
  • 1,076
  • 9
  • 18
5

Add below dependency to your pom.xml:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.10.2</version>
</dependency>
t0r0X
  • 4,212
  • 1
  • 38
  • 34
  • I show above the correct jackson dependency (not this one) is already there. So this is not a solution to the problem. The solution was already given by @ikumen – crowmagnumb Feb 24 '17 at 17:42
  • 3
    We will get the same error when this dependency is missing. So please don't down vote this answer as this is correct for some cases. – Sastrija Feb 06 '19 at 03:50
  • Well I can't un-downvote it now as it won't let me. But its still not an answer to my original question. I hope it does help some others though. – crowmagnumb Feb 07 '19 at 20:21
  • This is not for the above problem, but if you use `produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }` and ask for `application/xml` it is right solution – Cavva79 Mar 05 '19 at 11:02
4

I had this issue when accessing actuator. Putting following configuration class solved the issue:

@Configuration
@EnableWebMvc
public class MediaConverterConfiguration implements WebMvcConfigurer {
    @Bean
    public MappingJackson2HttpMessageConverter jacksonConverter() {
        MappingJackson2HttpMessageConverter mc =
                new MappingJackson2HttpMessageConverter();
        List<MediaType> supportedMediaTypes =
                new ArrayList<>(mc.getSupportedMediaTypes());
        supportedMediaTypes
                .add(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
        supportedMediaTypes.add(
            MediaType.valueOf("application/vnd.spring-boot.actuator.v2+json"));
        mc.setSupportedMediaTypes(supportedMediaTypes);
        return mc;
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(jacksonConverter());
    }
}
codefreak
  • 6,950
  • 3
  • 42
  • 51
  • I was having a great deal of difficulty getting my REST services to return json without this error on an old Spring application without boot. This did the trick for me, very helpful! – Groucho Nov 18 '21 at 15:59
3

I got the exact same problem. After viewing this reference: https://zetcode.com/springboot/requestparam/

My problem solved by changing

method = RequestMethod.GET, produces = "application/json;charset=UTF-8"

to

method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE

and don't forget to add the library:

import org.springframework.http.MediaType;

it works on both postman or regular browser.

Jan Bodnar
  • 10,969
  • 6
  • 68
  • 77
SuperGuy10
  • 471
  • 5
  • 5
3

Even if you do all of the above, as like in my case I still got the error 406 - Not acceptable when used from postman. Upon careful study, I have noticed that, in the request headers, default header for 'accept' is '/'.

I solved my problem, by adding a preset to the header and switched off default header. Please see below screenshot.

screenshot of postman preset

This solved my problem without any other settings or even adding the spring configurations.

Dharman
  • 30,962
  • 25
  • 85
  • 135
nimodka
  • 143
  • 1
  • 9
2

My return object didn't have @XmlRootElement annotation on the class. Adding the annotation solved my issue.

@XmlRootElement(name = "ReturnObjectClass")
public class ReturnObjectClass {

    @XmlElement(name = "Status", required = true)
    protected StatusType status;
    //...
}
Vasudev
  • 803
  • 1
  • 7
  • 16
1

Had similar issue when one of my controllers was intercepting all requests with empty @GetMapping

Javasick
  • 2,753
  • 1
  • 23
  • 35
1

In my case I was sending in correct object in ResponseEntity<>().

Correct :

@PostMapping(value = "/get-customer-details", produces = { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<?> getCustomerDetails(@RequestBody String requestMessage) throws JSONException {
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("customerId", "123");
    jsonObject.put("mobileNumber", "XXX-XXX-XXXX");
    return new ResponseEntity<>(jsonObject.toString(), HttpStatus.OK);
}

Incorrect :

return new ResponseEntity<>(jsonObject, HttpStatus.OK);

Because, jsonObject's toString() method "Encodes the jsonObject as a compact JSON string". Therefore, Spring returns json string directly without any further serialization.

When we send jsonObject instead, Spring tries to serialize it based on produces method used in RequestMapping and fails due to it "Could not find acceptable representation".

1

The answer is add Getters & Setters.

The technical answer is Jakson API which converts object to JSON works on the getters & setters.

Pratik Gaurav
  • 661
  • 7
  • 8
0

I had to explicitly call out the dependency for my json library in my POM.

Once I added the below dependency, it all worked.

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>
0

In my case I happened to be using lombok and apparently there are conflicts with the get and set

0

I had the same exception. The problem was, that I used the annotation

@RepositoryRestController

instead of

@RestController

Bla Blubb
  • 23
  • 4
  • Thanks! I was trying to do [this](https://stackoverflow.com/a/34693096/1781376) but it didn't work for the same reason. – GuiRitter Oct 28 '19 at 20:43
0

For me, the problem was trying to pass a filename in a url, with a dot. For example

"http://localhost:8080/something/asdf.jpg" //causes error because of '.jpg'

It could be solved by not passing the .jpg extension, or sending it all in a request body.

NobodySomewhere
  • 2,997
  • 1
  • 16
  • 12
0

I was running into the same issue, and what I was missing in my setup was including this in my maven (pom.xml) file.

<dependency>
     <groupId>org.codehaus.jackson</groupId>
     <artifactId>jackson-mapper-asl</artifactId>
     <version>1.9.9</version>
</dependency> 
Shardayyy
  • 97
  • 1
  • 7
0

if you are using postman to test, trying to check out the Header. my mistake was I'm using application/xml instead of application/json in "Accept" row.

0

Spent the whole day on this because none of the suggestions worked for me. Alas, it was the WebConfig implementation; specifically the configurer.ignoreAcceptHeader(true) that was the culprit preventing the .yaml from generating.

Hope this helps someone.

Vince
  • 68
  • 6
0

I encountered same exception: "Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation"]

In analysis I fount that this problem can generate during serialization of a class while calling a @Controller or @RestController.

In serialization, if you are using class, it must have public Setter and Getter.

In the project where it occurs I found that a getter method was private and because of that this problem occurred.

S.P Singh
  • 1,267
  • 3
  • 17
  • 23
0

I also faced similar issue. I just put getter and setter methods for all relevant bean classes. There is some issue with Lombok as it is not able to generate getters and setters on its own in Eclipse. Here I'm using postman for HTTP requests.

-2

accepted answer is not right with Spring 5. try changing your URL of your web service to .json! that is the right fix. great details here http://stick2code.blogspot.com/2014/03/solved-orgspringframeworkwebhttpmediaty.html

tom
  • 2,190
  • 1
  • 23
  • 27
-2

I had the same exception but the cause was different and I couldn't find any info on that so I will post it here. It was just a simple to overlook mistake.

Bad:

@RestController(value = "/api/connection")

Good:

@RestController
@RequestMapping(value = "/api/connection")
Dominik H.
  • 41
  • 2