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 .