Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-1686

Media type negotiation unexpected behavior

    Details

      Description

      Hi,

      Let's consider following resource running into a Resteasy container:

      	@Path("echo")
      	public static class EchoResource {
      
      		@Produces({ "*/xml" })
      		@GET
      		public Response echo(@QueryParam("msg") String msg) {
      			Message message = new Message();
      			message.setStatus(Status.OK.getStatusCode());
      			message.setMessage(String.valueOf(msg));
      			return Response.ok(message).build();
      		}
      
      	}
      
      • 1st case: If calling echo method using any HTTP client with Accept header set to application/*, the resulting response media type will be *application/xml
        According to the JAX-RS Spec, chapter "3.8 Determining the MediaType of Responses" I was expecting the choosen media type to be application/octet-stream (and it will faill with a NoMessageBodyWriterFoundFailure exception because I have not provided any writer for the Message entity type but that's not the point).

      Lets apply the spec step by step for the given case to explain my point:

      1. Not applicable in this case
      
      2. P = {"*/xml"}
      
      3. P is not empty so P = {"*/xml"}
      
      4. A is not empty so A = {"application/*"}
      
      5. MediaType.valueOf("application/*").isComptatible(MediaType.valueOf("*/xml")) returns true so M = {"application/*"} (the most specific).
      
      6. M is not empty so lets jump to step 7
      
      7. M.length = 1 so sort operation returns M = {"application/*"}
      
      8. As M does not contain any concrete type the selected media type can not be determinated here. Go to step 9
      
      9. M contains {"application/*"} so selected media type is Mselected = "application/octet-stream"
      
      • 2nd case: Lets call a non existing method using any HTTP client with Accept header set to application/xml. The server side will catch the NotFoundException and using an ExceptionMapper it will return a Message Entity annotated with correct Jaxb annotation. So in this case the choosen media type will be application/octet-stream
        According to the JAX-RS Spec, I was expecting the choosen media type to be application/xml.

      Lets apply the spec step by step for the given case to explain my point:

      1. Not applicable in this case
      
      2. Since we are dealing with a 404 there is no method and no class selected. So we have to select all *MessageBodyWriter * able to handle the Message entity.
       The  Resteasy JAXBXmlRootElementProvider should be selected among others since it is able to write the Message entity. So P will contains {...,"application/*+xml", "text/*+xml", ....}
      
      3. P is not empty so P = {...,"application/*+xml", "text/*+xml", ....}
      
      4. A is not empty so A = {"application/xml"}
      
      5. MediaType.valueOf("application/xml").isComptatible(MediaType.valueOf("application/*+xml")) returns true so M = {"application/xml"} (the most specific).
      
      6. M is not empty so lets jump to step 7
      
      7.  M.length = 1 so sort operation returns M = {"application/xml"}
      
      8. As M contains a concrete type the selected media type is Mselected = "application/xml". Finish so no need to process other steps
      
      

      Please find the unit test attached to the Jira.

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  asoldano Alessio Soldano
                  Reporter:
                  nicolas.n Nicolas NESMON
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: