Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-9980

Make @RequestMapping inject the negotiated MediaType

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: 3.1.3
    • Fix Version/s: None
    • Component/s: Web

      Description

      I have a use caes where I do return a suitable object according for the negotiated content type.
      In my case I accept JSON and XML. When JSON is returned to the client I produce a Map, when XML is returned I produce a custom object.

      There is no way to determine easily which content type will be written out to the client. With examining the Accept header and iterating over registered message converters.

      I have a work around which looks like this:

      @RequestMapping(value = "/{project:[A-Z0-9_+\\.\\(\\)=\\-]+}", method = RequestMethod.GET, 
        produces = { MediaType.APPLICATION_XML_VALUE })
        public ResponseEntity<Object> lookupProjectAsXml(@PathVariable String project,
            @RequestParam(value = "fields", required = false) String fields) {
      
          String[] fieldsArray = StringUtils.split(fields, ',');
      
          return lookup(project, fieldsArray, false, MediaType.APPLICATION_XML);
        }
      

      and

      @RequestMapping(value = "/{project:[A-Z0-9_+\\.\\(\\)=\\-]+}", method = RequestMethod.GET, 
        produces = { MediaType.APPLICATION_JSON_VALUE })
        public ResponseEntity<Object> lookupProjectAsJson(@PathVariable String project,
            @RequestParam(value = "fields", required = false) String fields,
            @RequestParam(value = "asList", required = false, defaultValue = "false") boolean asList) {
      
          String[] fieldsArray = StringUtils.split(fields, ',');
      
          return lookup(project, fieldsArray, asList, MediaType.APPLICATION_JSON);
        }
      

      I would rather have:

      @RequestMapping(value = "/{project:[A-Z0-9_+\\.\\(\\)=\\-]+}", method = RequestMethod.GET, 
        produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
        public ResponseEntity<Object> lookupProject(@PathVariable String project,
            @RequestParam(value = "fields", required = false) String fields,
            @RequestParam(value = "asList", required = false, defaultValue = "false") boolean asList,
            MediaType mediaType) {
      
          // Process request...
          
          Object body;
          if (mediaType.equals(MediaType.APPLICATION_JSON)) {
            body = projectValues;
          } else if (mediaType.equals(MediaType.APPLICATION_XML)) {
            body = new Project(projectValues);
          } else {
            throw new NotImplementedException("Project lookup is not implemented for media type '" + mediaType + "'");
          }
        
          return new ResponseEntity<Object>(body, HttpStatus.OK);
        }
      

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                rstoya05-aop Rossen Stoyanchev
                Reporter:
                michael-o Michael Osipov
                Last updater:
                Rossen Stoyanchev
              • Votes:
                0 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Days since last comment:
                  4 years, 39 weeks, 1 day ago