Over a million developers have joined DZone.

A Detailed Look at Controllers in Java EE 8 MVC

DZone's Guide to

A Detailed Look at Controllers in Java EE 8 MVC

An MVC Controller is a JAX-RS resource method annotated with @Controller. If a class is annotated with @Controller, then all resource methods of this class are regarded as controllers.

· Java Zone
Free Resource

Learn how to troubleshoot and diagnose some of the most common performance issues in Java today. Brought to you in partnership with AppDynamics.

Java EE MVC is a new action based MVC framework planned for Java EE 8 and specified in JSR-371. This is the second post of my Java EE 8 MVC tutorial. The first post covered the basics and shows how to get started with Ozark, the Java EE 8 MVC reference implementation.

In this post we will have a more detailed look at MVC Controllers.

MVC Controllers

A controller is responsible for processing incoming requests. It invokes business logic, updates the model and returns the view that should be rendered. An MVC Controller is a JAX-RS resource method annotated with @Controller. If a class is annotated with @Controller, then all resource methods of this class are regarded as controllers.

The following example shows a simple Controller that renders a product details page for a given product ID:

public class ProductController {

  private Models models;

  private ProductService productService;

  public String getProductDetailPage(@QueryParam("id") long productId) {
    Product product = this.productService.getProduct(productId);
    models.put("product", product);
    return "/WEB-INF/jsp/productDetailPage.jsp";

This Controller resolves a product id (passed as id request parameter) to a product using a ProductService. The obtained product is added to the model and a path to a view is returned. The view is then rendered with the information stored in the model.

Like in JAX-RS, the @Path annotation is used to define the URL path. This Controller is accessible via a URL that looks like this:


The following example shows a hybrid class with one MVC controller method and one traditional JAX-RS resource method:

public class HybridController {

  public Response jaxrs() {
    return Response.status(200).build();

  public String mvc() {
    return "/WEB-INF/jsp/hello.jsp";

Controller methods work very similar to JAX-RS resource methods. However, there are two small differences:

  • A return type of String on Controller methods is interpreted as a view path. With JAX-RS resource methods the returned String is interpreted as text content.
  • The default response media type for Controller methods is text/html. Like in JAX-RS the media type can be changed using the @Produces annotation.

MVC Controller classes and hybrid classes with MVC Controller methods need to be CDI-managed beans. Like JAX-RS resource classes, MVC controller classes are instantiated per request. For every request, a new Controller class instance is created.

Like in JAX-RS the supported HTTP verb is defined by annotations. If a controller method should listen for HTTP POST requests, it needs to be annotated with @POST instead of @Get.

For example:

public class PostController {

  public String post() {
    return "/WEB-INF/jsp/hello.jsp";

Controller Return Types

Four different return types are supported on MVC controller methods:

  • String - The returned string value is interpreted as view path.
  • void - In this case the view need to be defined using the @View annotation
  • Viewable - An abstraction that includes information about a view, the model and the used view engine.
  • Response - A JAX-RS response. The entity type of the response needs to be String, void or Viewable.

The following class defines four controller methods using different return types. All methods return the same response:

public class ReturnTypesController {

  public void returnVoid() {

  public String returnString() {
    return "/WEB-INF/jsp/hello.jsp";

  public Viewable returnViewable() {
    return new Viewable("/WEB-INF/jsp/hello.jsp");

  public Response returnResponse() {
    return Response.status(Response.Status.OK)

Returning a JAX-RS Response is the most flexible way. This way the JAX-RS Response builder can be used to modify the HTTP status code, response headers and more.

If void is used as return type, the view needs to be defined using the @View annotation. @View can be applied to methods (like in the previous example) and classes. If a class is annotated with @View, the view is applied to all controller methods in this class. A class level @View annotation can be overridden by a more specific view definition on method level, like shown in the following example:

public class ViewController {

  public void first() {
    // renders foo.jsp

  public void second() {
    // renders bar.jsp

  public String third() {
    // renders baz.jsp
    return "/WEB-INF/jsp/baz.jsp";


The @Controller annotation can be used on methods and classes. When used on classes, all methods of the class are considered as controllers. Controller methods invoke business logic and determine the view that should be rendered. Classes with Controller methods are CDI managed beans. For every request, a new class instance will be created. Traditional JAX-RS resource methods can be combined with MVC Controller methods in the same class.

In the next posts about Java EE 8 MVC we will have a look at parameter binding and validation.

You can find the example source code on GitHub.

Understand the needs and benefits around implementing the right monitoring solution for a growing containerized market. Brought to you in partnership with AppDynamics.

java ,java ee 8 ,controllers ,mvc

Published at DZone with permission of Michael Scharhag, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}