Статьи

Подробный взгляд на контроллеры в Java EE 8 MVC

Java EE MVC — это новая основанная на действии инфраструктура MVC, запланированная для Java EE 8 и определенная в JSR-371 . Это второй пост моего учебника по Java EE 8 MVC. В первом посте рассматриваются основы и показано, как начать работу с Ozark , эталонной реализацией Java EE 8 MVC.

В этом посте мы более подробно рассмотрим контроллеры MVC.

Контроллеры MVC

Контролер отвечает за обработку входящих запросов. Он вызывает бизнес-логику, обновляет модель и возвращает представление, которое должно быть отображено. Контроллер MVC — это метод ресурсов JAX-RS, аннотированный @Controller. Если класс аннотируется @Controller, то все методы ресурсов этого класса считаются контроллерами.

В следующем примере показан простой контроллер, который отображает страницу сведений о продукте для данного идентификатора продукта:


@Path("product")
@Controller
public class ProductController {

  @Inject
  private Models models;

  @Inject
  private ProductService productService;

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

Этот Контроллер разрешает идентификатор продукта (передаваемый как параметр запроса идентификатора) в продукт, используя ProductService Полученный продукт добавляется в модель и возвращается путь к представлению. Затем представление отображается с информацией, хранящейся в модели.

Как и в JAX-RS, аннотация @Path используется для определения пути URL. Этот контроллер доступен через URL, который выглядит следующим образом:


/<application-path>/product?id=42

В следующем примере показан гибридный класс с одним методом контроллера MVC и одним традиционным методом ресурса JAX-RS:


@Path("hybrid")
public class HybridController {

  @GET
  @Path("jaxrs")
  public Response jaxrs() {
    return Response.status(200).build();
  }

  @Path("mvc")
  @GET
  @Controller
  public String mvc() {
    return "/WEB-INF/jsp/hello.jsp";
  }
}

Методы контроллера работают очень похоже на методы ресурсов JAX-RS. Однако есть два небольших различия:

  • Тип возврата String для методов Controller интерпретируется как путь к представлению. С помощью методов ресурсов JAX-RS возвращаемая строка интерпретируется как текстовое содержимое.
  • Тип носителя ответа по умолчанию для методов контроллера — text / html. Как и в JAX-RS, тип носителя можно изменить с помощью аннотации @Produces.

Классы контроллера MVC и гибридные классы с методами контроллера MVC должны быть компонентами, управляемыми CDI. Как и классы ресурсов JAX-RS, классы контроллеров MVC создаются для каждого запроса. Для каждого запроса создается новый экземпляр класса Controller.

Как и в JAX-RS, поддерживаемый HTTP-глагол определяется аннотациями. Если метод контроллера должен прослушивать HTTP-запросы POST, он должен быть аннотирован @POST вместо @Get.

Например:


@Controller
@Path("http")
public class PostController {

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

Типы возврата контроллера

Четыре различных типа возврата поддерживаются в методах контроллера MVC:

  • String — Возвращаемое значение строки интерпретируется как путь просмотра.
  • void — В этом случае представление должно быть определено с помощью аннотации @View.
  • Видимый — абстракция, которая включает информацию о представлении, модели и используемом движке представления.
  • Ответ — ответ JAX-RS. Тип объекта ответа должен быть String, void или Viewable.

Следующий класс определяет четыре метода контроллера, использующих разные типы возврата. Все методы возвращают один и тот же ответ:


@Controller
@Path("return-types")
public class ReturnTypesController {

  @GET
  @View("/WEB-INF/jsp/hello.jsp")
  @Path("return-void")
  public void returnVoid() {
  }

  @GET
  @Path("return-string")
  public String returnString() {
    return "/WEB-INF/jsp/hello.jsp";
  }

  @GET
  @Path("return-string")
  public Viewable returnViewable() {
    return new Viewable("/WEB-INF/jsp/hello.jsp");
  }

  @GET
  @Path("return-response")
  public Response returnResponse() {
    return Response.status(Response.Status.OK)
        .entity("/WEB-INF/jsp/hello.jsp")
        .build();
  }
}

Возврат ответа JAX-RS является наиболее гибким способом. Таким образом, построитель ответов JAX-RS можно использовать для изменения кода состояния HTTP, заголовков ответов и многого другого.

Если void используется в качестве возвращаемого типа, представление должно быть определено с помощью аннотации @View. @View можно применять к методам (как в предыдущем примере) и классам. Если класс аннотирован @View, представление применяется ко всем методам контроллера в этом классе. Аннотацию @View уровня класса можно переопределить с помощью более конкретного определения представления на уровне метода, как показано в следующем примере:


@Controller
@Path("views")
@View("/WEB-INF/jsp/foo.jsp")
public class ViewController {

  @GET
  @Path("first")
  public void first() {
    // renders foo.jsp
  }

  @GET
  @Path("second")
  @View("/WEB-INF/jsp/bar.jsp")
  public void second() {
    // renders bar.jsp
  }

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

Резюме

Аннотация @Controller может использоваться для методов и классов. При использовании в классах все методы класса рассматриваются как контроллеры. Методы контроллера вызывают бизнес-логику и определяют представление, которое должно быть отображено. Классы с методами Controller являются управляемыми компонентами CDI. Для каждого запроса будет создан новый экземпляр класса. Традиционные методы ресурсов JAX-RS можно комбинировать с методами контроллера MVC в одном классе.

В следующих статьях о Java EE 8 MVC мы рассмотрим привязку и проверку параметров.

Вы можете найти пример исходного кода на GitHub .