详细了解 Java EE 8 MVC 中的控制器

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 63w+ 字,讲解图 2808+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2200+ 小伙伴加入学习 ,欢迎点击围观

Java EE MVC 是一个新的基于动作的 MVC 框架,计划用于 Java EE 8 并在 JSR-371 中指定。这是我的 Java EE 8 MVC 教程的第二篇文章。第一篇文章介绍了基础知识,并展示了如何 开始使用 Ozark (Java EE 8 MVC 参考实现)。

在这篇文章中,我们将更详细地了解 MVC 控制器。

MVC 控制器

控制器负责处理传入的请求。它调用业务逻辑、更新模型并返回应呈现的视图。 MVC 控制器是一种使用@Controller 注释的JAX-RS 资源方法。如果一个类被@Controller注解,那么这个类的所有资源方法都被视为控制器。

以下示例显示了一个简单的控制器,它呈现给定产品 ID 的产品详细信息页面:


 @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 将产品 ID(作为 id 请求参数传递)解析为产品。将获得的产品添加到模型中,并返回视图的路径。然后使用存储在模型中的信息呈现视图。

与在 JAX-RS 中一样,@Path 注释用于定义 URL 路径。可以通过如下所示的 URL 访问此控制器:


 @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"; } }

以下示例显示了一个具有一个 MVC 控制器方法和一个传统 JAX-RS 资源方法的混合类:


 @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"; } }

控制器方法的工作方式与 JAX-RS 资源方法非常相似。但是,有两个小区别:

  • Controller 方法的返回类型 String 被解释为视图路径。使用 JAX-RS 资源方法,返回的字符串被解释为文本内容。
  • Controller 方法的默认响应媒体类型是 text/html。与 JAX-RS 一样,可以使用 @Produces 注释更改媒体类型。

MVC 控制器类和具有 MVC 控制器方法的混合类需要是 CDI 管理的 bean。与 JAX-RS 资源类一样,MVC 控制器类是根据请求实例化的。对于每个请求,都会创建一个新的 Controller 类实例。

与 JAX-RS 一样,受支持的 HTTP 动词由注释定义。如果一个控制器方法应该监听 HTTP POST 请求,它需要用 @POST 而不是 @Get 注释。

例如:


 @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"; } }

控制器返回类型

MVC 控制器方法支持四种不同的返回类型:

  • String - 返回的字符串值被解释为视图路径。
  • void - 在这种情况下,需要使用 @View 注释定义视图
  • 可查看 - 包含有关视图、模型和使用的视图引擎的信息的抽象。
  • 响应 - JAX-RS 响应。响应的实体类型需要是 String、void 或 Viewable。

下面的类定义了四种使用不同返回类型的控制器方法。所有方法都返回相同的响应:


 @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"; } }

返回 JAX-RS 响应是最灵活的方式。这样,JAX-RS 响应构建器可用于修改 HTTP 状态代码、响应标头等。

如果使用 void 作为返回类型,则需要使用 @View 注释定义视图。 @View 可以应用于方法(如前面的示例)和类。如果一个类被@View注解,视图将被应用到这个类中的所有控制器方法。类级别的 @View 注释可以被方法级别上更具体的视图定义覆盖,如以下示例所示:


 @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"; } }

概括

@Controller 注解可以用在方法和类上。在类上使用时,该类的所有方法都被视为控制器。控制器方法调用业务逻辑并确定应呈现的视图。具有 Controller 方法的类是 CDI 管理的 bean。对于每个请求,都会创建一个新的类实例。传统的 JAX-RS 资源方法可以与同一个类中的 MVC 控制器方法组合。

在下一篇关于 Java EE 8 MVC 的文章中,我们将了解参数绑定和验证。

您可以在 GitHub 上找到示例源代码。

相关文章