Could not find acceptable representation

57,341

Solution 1

The POST request doesn't work because Spring doesn't know what kind of data it's expecting. So you will need to tell spring that you're expecting APPLICATION_JSON_VALUE so it knows how to process. consumes= will, as you probably guessed, tell Spring what the incoming POST body context type.

@RequestMapping(value = "xyz", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody AbcDTO registerHotel(@RequestBody AbcDTO aaa) {

    System.out.println(aaa.toString());
    return aaa; 
    // I'm not able to map JSON into this Object
}

With PostMapping

@PostMapping(value = "xyz", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody AbcDTO registerHotel(@RequestBody AbcDTO aaa) {

   System.out.println(aaa.toString());
   return aaa; 
   // I'm not able to map JSON into this Object
}

As you can see I have also added something else called, produces= this will instruct Spring how to format the response body of that request. So frontend receives JSON formatted body, not just random text.

Solution 2

In my case helped this in pom

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Solution 3

I just spent half a day on this error, and finally discovered that Spring's ContentNegotiationConfigurer by default favours the path extension if it's present. I had this particular mapping:

@PostMapping(value="/convert/{fileName:.+}",produces=MediaType.APPLICATION_JSON_VALUE)
public Map<String, String> convert(@PathVariable String fileName, @RequestBody String data) {
   // Do conversion
}

Now when I posted to this controller with a filename "outputfile.pdf", Spring would simply assume the response had to be PDF, completely ignoring the "produces" parameter for the PostMapping.

The problem can be fixed fixed with ContentNegotiationConfigurer.favorPathExtension(false). As of Spring web 5.3 this should be the default, but still isn't.

Solution 4

In my case the problem was that I didn't specify public getters in response class (analog of your AbcDTO class). So there were nothing to get to serialize and return to client.

Share:
57,341
Mayur
Author by

Mayur

Expertises in JAVA, AWS, Python with 4+ years of development experience

Updated on July 22, 2022

Comments

  • Mayur
    Mayur almost 2 years

    I'm new to Spring Boot and I might be doing some silly mistake so Appologies in advance for such question. I'm trying to write POST API which accept following JSON :

    {
      "id" : null,
      "a": 1.3,
      "b": "somestring",
       "mapJson" : 
        { 
            "monday" : "10:00-12:00/n14:00-18:00", 
            "tuesday" : "10:00-12:00/n14:00-18:00",
            "wednesday" : "10:00-12:00/n14:00-18:00",
            "thursday" : "10:00-12:00/n14:00-18:00",
            "friday" : "10:00-12:00/n14:00-18:00",
            "saturday" : "10:00-12:00/n14:00-18:00",
            "sunday" : "10:00-12:00/n14:00-18:00"
        },
        "list" : ["cc","paytm","debit"]
    }
    

    Consider following DTO class , AbcDTO :

    package com.abb.dto;
    import java.util.List;
    import com.abb.entities.OpeningHrs;
    import lombok.Data;
    
    @SuppressWarnings("unused")
    @Data
    public class AbcDTO {
    
        private Long id;
        private Double a;
        private String b;
        private MapJson mapJson;
        private List<String> list;
    
    }
    

    OpeningHrs is Class for mapping Json Map structure,

    package com.abb.entities;
    import lombok.Data;
    @SuppressWarnings("unused")
    @Data
    public class MapJson {
    
        private String monday;
        private String tuesday;
        private String wednesday;
        private String thursday;
        private String friday;
        private String saturday;
        private String sunday;
    
    }
    

    AbcController which have Post API :

    package com.abb.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.abb.dto.AbcDTO;
    
    @RestController
    @EnableAutoConfiguration
    @RequestMapping("/abc")
    @GetMapping(value="/{id}",produces={MediaType.APPLICATION_JSON_VALUE})
    public class HotelController {
    
       @RequestMapping(value = "/xyz", method = RequestMethod.POST)
        public @ResponseBody AbcDTO registerHotel(@RequestBody AbcDTO aaa) {
    
           System.out.println(aaa.toString());
           return aaa; 
       // I'm not able to map JSON into this Object
        }
    
    }
    

    Please find following Responce I'm getting is :

    {
        "timestamp": 1509193409948,
        "status": 406,
        "error": "Not Acceptable",
        "exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
        "message": "Could not find acceptable representation",
        "path": "/abc/xyz"
    }
    
  • Mayur
    Mayur over 6 years
    Thanks , I missed that consumes parameter. but after adding it, it still not working
  • Praveen Premaratne
    Praveen Premaratne over 6 years
    I've added PostMapping, could you see if that works? Could toy also try removing the GetMapping of the Class as well, that might be blocking the entire Class as the request is Post.
  • Praveen Premaratne
    Praveen Premaratne over 6 years
    Assuming you've also removed the GetMapping from the Class as well. Has the error changed at all? And what tool are you using to send request?
  • Mayur
    Mayur over 6 years
    Yes, I have removed GetMapping from the Class and I'm using ARC and PostMan Both to send request, while Content-Type is set as Application/Json and request JSON is in Body.
  • Praveen Premaratne
    Praveen Premaratne over 6 years
    @Mayur Could you try removing the / of /xyz, that is the only thing I can think of now. Other than, the only thing I can think of is the use of Get method on PostMan` instead Post; but I highly doubt that's the case.
  • Andreas Sandberg
    Andreas Sandberg over 2 years
    In your case I guess that your service produce XML? That was also the case for me but I also had to configure a message converter: @Override public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) { converters.add(new MappingJackson2XmlHttpMessageConverter()); }