1

My Spring REST API has trouble (=> 406) when an endpoint ends with a file name, e.g. /file/example.xml because it assumes the result should be XML but thats wrong (it should be JSON).

Written [{timestamp=Thu Oct 20 11:11:14 CEST 2016, status=406, error=Not Acceptable, exception=org.springframework.web.HttpMediaTypeNotAcceptableException, message=Could not find acceptable representation, path=/file/foobar.xml}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@7015ebef]

I read something about a Spring 4 feature detecting the file extensions and overwritting the response type, so I tried to enforce the response type but I did not find a solution.

Here is my REST controller:

@CompileStatic
@RestController
class ImportFileController {
    @RequestMapping(
            value = "/file/{fileName:.+}",
            method = RequestMethod.PUT,
            produces = "application/json"
    )
    @ResponseBody
    public ImportFile update(
            @PathVariable("fileName") String fileName,
            @RequestBody ImportFile importFile) {
        // ..
        return importFile
    }
}

This is the request/response:

Request PUT /file/foobar.xml {"reader_name":"something"}
Response 406 {
  "timestamp" : "2016-10-20 08:56:35",
  "status" : 406,
  "error" : "Not Acceptable",
  "exception" : "org.springframework.web.HttpMediaTypeNotAcceptableException",
  "message" : "Could not find acceptable representation",
  "path" : "/file/foobar.xml"
}

What I tried:

  • Using {filenName:.+} instead of {fileName}
  • Using produces in my @RequestMapping
  • Sending a custom Accept header (application/json)
  • Setting spring.mvc.path-matching.suffix-pattern to true or false but that was just a wild guess

What worked:

  • Changing endpoint from /file/{fileName:.+} to /file/{fileName:.+}/update But that's just a workaround, not a solution.

Important: I'm using Groovy and I'm using YML configuration.

tim_yates
  • 167,322
  • 27
  • 342
  • 338
MonkeyMonkey
  • 826
  • 1
  • 6
  • 19
  • Have a look at http://stackoverflow.com/a/20743941/1496158. This post describes how to either disable the handler mapping or only enable the handler mapping for specific extensions. – dudel Oct 20 '16 at 09:35
  • Correct me if I'm wrong but it's for Java/XML config only – MonkeyMonkey Oct 20 '16 at 09:40
  • But there surely must be a way to configure Spring beans? This was meant as a pointer to what to configure. – dudel Oct 20 '16 at 09:49
  • Ah yes I have a beans.xml, thought in wrong mindset. When adding the `handlerMapping` bean I can't compile anymore, `No bean named 'contentNegotiationManager' is defined`, when using the second code snippet I got `Method viewResolver in org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter required a single bean, but 2 were found:` `contentNegotiationManager: defined in class path resource [beans.xml]` `mvcContentNegotiationManager: defined by method 'mvcContentNegotiationManager' ...` – MonkeyMonkey Oct 20 '16 at 10:01
  • The problem is I'm also using the Rest stuff, not the Mvc stuff directly, so I can't set or overwrite any handlers, right? At least I can't build successfully with those solutions. I'll take the workaround, adding a slash to the endpoint's URL :( – MonkeyMonkey Oct 20 '16 at 10:09
  • Couldn't you for the first code snippet try to use mvcContentNegotiationManager: ``? – dudel Oct 20 '16 at 10:14
  • Alternatively you should be able to override the mvcContentNegotiationManager in the configuration by setting the id to mvcContentNegotiationManager instead of contentNegotiationManager in the second snippet. – dudel Oct 20 '16 at 10:23

1 Answers1

1

One option is to define, that your method consumes json as well, using @RequestMapping options:

@RequestMapping(
            value = "/file/{fileName:.+}",
            method = RequestMethod.PUT,
            produces = "application/json",
            consumes = "application/json",
    )

This should prevent your application from trying to convert the data into XML.

Also make sure that Client is setting the "Content-Type" header properly

jderda
  • 890
  • 6
  • 18