Close

JAX-RS - Restrict Media Types using @Consumes and @Produces

[Last Updated: May 22, 2017]

Resource methods/classes can declare the supported request and response media types using the @Consumes and @Produces annotations respectively.

A request is mapped to a resource method with matching Accept request header value to the value specified by @Produces.

Similarly a request is mapped to a resource method with matching Content-Type request header value to the value specified by @Consumes.

If @Produces is absent or has not specified it's value element then the method can be matched for any 'Accept' header of type */*.

Similarly if @Consumes is absent or has not specified it's value element then the method can be matched with 'Content-Type' request header of type */*.


@Produces:

The @Produces annotation is used to specify the MIME media types or representations a resource can produce and send back to the client. If @Produces is applied at the class level, all the methods in a resource can produce the specified MIME types by default. If applied at the method level, the annotation overrides any @Produces annotations applied at the class level.

If no methods in a resource are able to produce the MIME type in a client request, the JAX-RS runtime sends back an HTTP "406 Not Acceptable" error.

A resource method can uniquely (without ambiguity) be defined by @Produces (other than @Path and http verbs).
Note: if we try to define two resource methods which are not uniquely defined we will have container start up time validation exception. Since we are using Jersey we will see this exception:

org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization. [[FATAL] A resource model has ambiguous (sub-)resource method for HTTP method GET and input mime-types as defined by"@Consumes" and "@Produces" annotations at Java methods ........ at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:555)

Here's a simple example how we can use @Produces annotation

@GET
@Path("{orderId}")
@Produces("text/xml")
public String getOrderAsHtmlById(....){
  .....
}

@Consumes

The @Consumes annotation is used to specify which MIME media types of representations a resource can accept, or consume, from the client. If @Consumes is applied at the class level, all the response methods accept the specified MIME types by default. If applied at the method level, @Consumes overrides any @Consumes annotations applied at the class level.

If a resource is unable to consume the MIME type of a client request, the JAX-RS runtime sends back an HTTP 415 ("Unsupported Media Type") error.

By specifying a different media type that a Java resource method can consume, we can have one more level of uniquely defined resources. Here's a simple example of using this annotation:

@GET
@Consumes({"text/plain,text/html"})
@Path("/users/{username}")
public String getUser(@PathParam("username") String userName) {
        ...
}


Example Project

Dependencies and Technologies Used:

  • jersey-core-server 2.22.1: Jersey core server implementation.
  • jersey-container-servlet 2.22.1: Jersey core Servlet 3.x implementation.
  • jersey-test-framework-provider-jdk-http 2.22.1: Jersey Test Framework - JDK HTTP container.
  • JDK 1.8
  • Maven 3.0.4

Restrict Media Example Select All Download
  • restrict-media-type
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • OrderService.java
        • test
          • java
            • com
              • logicbig
                • example

    See Also