Spring MVC 415 Unsupported Media Type
Asked Answered
N

8

15

I am using Spring 3.2 and try to use an ajax post request to submit an array of json objects. If this is relevant, I escaped all special characters.

I am getting an HTTP Status of 415.

My controller is:

@RequestMapping(value = "/save-profile", method = RequestMethod.POST,consumes="application/json")
    public @ResponseBody String saveProfileJson(@RequestBody String[] profileCheckedValues){
        System.out.println(profileCheckedValues.length);
        return "success";
    }

jquery is:

jQuery("#save").click(function () {
        var profileCheckedValues = [];
        jQuery.each(jQuery(".jsonCheck:checked"), function () {
            profileCheckedValues.push($(this).val());
        });
        if (profileCheckedValues.length != 0) {
            jQuery("body").addClass("loading");
            jQuery.ajax({
                type: "POST",
                contentType: "application/json",
                url: contextPath + "/sample/save-profile",
                data: "profileCheckedValues="+escape(profileCheckedValues),
                dataType: 'json',
                timeout: 600000,
                success: function (data) {
                    jQuery('body').removeClass("loading");
                },
                error: function (e) {
                    console.log("ERROR: ", e);
                    jQuery('body').removeClass("loading");
                }
            });
        }
    });

and an example of one of the objects from the array I am posting is the following json:

{
  "id": "534213341",
  "name": "Jack Lindamood",
  "first_name": "Jack",
  "last_name": "Lindamood",
  "link": "https://www.facebook.com/jack",
  "username": "jack",
  "gender": "male",
  "locale": "en_US",
  "updated_time": "2013-07-23T21:13:23+0000"
}

The error is:

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method

Why is this error happening - does anyone know?

Nicollenicolson answered 7/8, 2013 at 11:40 Comment(13)
Do you have jackson in the classpath?Weirdie
yes i have included jackson-core 2.0.6Nicollenicolson
This not an array of values, but a map of values.Belonging
this is a single element.Nicollenicolson
What do you mean with that? Do you expect an array of the above JSON? Like profiles for multiple users? Where is the name "profileCheckedValues" in your HTTP request? Ah, there's your error: you're not sending application/json even though you set contentType to that. You're sending a parameter named "profileCheckedValues" which content is JSON (I guess). But then the HTTP request itself is not JSON; remove that line to make jQuery use the default "application/x-www-form-urlencoded". This way your controller will get JSON though, without is being converted by Spring.Belonging
Ah I missed the paragraph below your JSON. My bad. Still then the above applies. Do you know how to see the HTTP traffic in Chrome or Firebug? Am I right that the above jQuery gets you a parameter named "profileCheckedValues"?Belonging
And then @RequestParam might do the trick.Belonging
@Belonging yes this is a profile of multiple users. Could you show me a sample for this? profileCheckedValues in param when i saw through firebugNicollenicolson
Did you try @RequestParam then, or muthu's HttpServletRequest? Be sure to peek into the HTTP request to understand what your browser is sending. And remove the contentType like I wrote above.Belonging
I tried muthu's HttpServletRequest that is not working for arrays of values but working for single elementNicollenicolson
@Belonging I tried with muthu's. it is working fine for each object instead of arrayNicollenicolson
See my comment to that answer. Also @RequestParam should work with arrays.Belonging
(Also, what does "is not working" mean? Be precise, please. And comment on muthu's answer -- this is getting to be a very messy question.)Belonging
R
7

You may try with HttpServletRequest. it does not have any problem

  @RequestMapping(value = "/save-profile", method = RequestMethod.POST,consumes="application/json",headers = "content-type=application/x-www-form-urlencoded")
    public @ResponseBody String saveProfileJson(HttpServletRequest request){
       System.out.println(request.getParameter("profileCheckedValues"));
        return "success";
    }
Ramburt answered 8/8, 2013 at 6:37 Comment(6)
@RequestParam might work as well. And also in the jQuery call, remove setting the contentType: sending an array with name profileCheckedValues (which happens to hold JSON strings, but could have been anything) is not application/json but simply the default application/x-www-form-urlencoded.Belonging
And for arrays, use getParameterValues.Belonging
Again, @jackyesind, what does "it does not works" mean? (What do you see? You need to be specific; you need to be much more detailed.) Also, did you try getParameterValues? And @RequestParam? Please read Help Vampires: A Spotter’s Guide. I'm no longer responding to your requests, but: success.Belonging
@Arjan. Sorry. If i use getParameterValues means it returns null onlyRamburt
How did you test, muthu? getParameterValues should return the same as getParameter, if there's just one value. But indeed it depends on how jQuery creates the request. That jQuery Ajax request in @jackyesind's question has bugs too.Belonging
Awesome...But why did you use HttpServletRequest ? I tried @ResponseBody final MyObject obj with the same settings for consumes and headers but it failed....Xenogamy
K
6

1) Add the following dependencies

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${jackson-version}</version> // 2.4.3
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson-version}</version> // 2.4.3
</dependency>

2) If you are using @RequestBody annotation in controller method make sure you have added following in xml file

<mvc:annotation-driven />

This should resolve the 415 status code issue.

Karbala answered 11/8, 2016 at 10:51 Comment(1)
I had 415 problem because of using codehaus dependency instead of fasterxml. Thanks! Worked like a charmSwigart
W
3

You will need to add jackson and jackson-databind to the classpath. Spring will pick it up using it's MappingJacksonHttpMessageConverter

MappingJacksonHttpMessageConverter

An HttpMessageConverter implementation that can read and write JSON using Jackson's ObjectMapper. JSON mapping can be customized as needed through the use of Jackson's provided annotations. When further control is needed, a custom ObjectMapper can be injected through the ObjectMapper property for cases where custom JSON serializers/deserializers need to be provided for specific types. By default this converter supports (application/json).

Weirdie answered 7/8, 2013 at 12:53 Comment(2)
I already included jackson-core-2.0.6.jar. public @ResponseBody String saveProfileJson(@RequestBody String[] profileCheckedValues) instead of string what would i give i don't have objects for that jsonNicollenicolson
You probably need to add the jackson-databind package as wellWeirdie
L
2

I had consume="application/json" in my request mapping configuration which expects a json input. When I sent a request which is not a JSON input Spring complained about the 415 Unsupported Media Type. So removing the consume="application/json" worked for me. So look into the request input and the accept media type in your Spring controller method signature. A mismatch would throw the 415 error. This will be most likely the reason for the issue.

Leastways answered 21/3, 2016 at 11:25 Comment(0)
W
0

try changing json to application/json for datatype. And what does your json look like is it valid ? I have never seen json converted to a String[] before, so this coul dalso be the problem.

Writhe answered 7/8, 2013 at 11:42 Comment(3)
Is there any possible to send array of json to spring controllerNicollenicolson
when i checked in firebug the param has valid json. In java side how would i getNicollenicolson
datatype is what the server sends back. Also, it's not formatted as a MIME type, but defined by jQuery.Belonging
E
0

I had the same problem. I had to follow these steps to resolve the issue:

1. Make sure you have the following dependencies:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>

2. Create the following filter:

    public class CORSFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {

            String origin = request.getHeader("origin");
            origin = (origin == null || origin.equals("")) ? "null" : origin;
            response.addHeader("Access-Control-Allow-Origin", origin);
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, DELETE, OPTIONS");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Headers",
                    "Authorization, origin, content-type, accept, x-requested-with");

            filterChain.doFilter(request, response);
        }
    }

3. Apply the above filter for the requests in web.xml

    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.your.package.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

I hope this is useful to somebody.

Egis answered 16/3, 2016 at 4:16 Comment(0)
U
0

I had the same problem, I just brought up the below line of code in the spring-servlet.xml, it was at the almost end of this xml file. It worked. <mvc:annotation-driven />

Unregenerate answered 17/5, 2017 at 10:34 Comment(0)
A
0

I had the same issue and everything looked ok. Other requests working like a charm in the same project. Finally it turned out out that my request object had a duplicate the:

@JsonProperty("duplicatePropertyName")

entry. The error message:

415 Unsupported Media Type

Is really confusing in this case. Hope this helps to people with bad eyes like me ;-)

Applewhite answered 29/12, 2022 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.