注解和可插拔性

优质
小牛编辑
134浏览
2023-12-01

在 web 应用中,使用注解的类仅当它们位于 WEB-INF/classes 目录中,或它们被打包到位于应用的 WEB-INF/lib 中的 jar 文件中时它们的注解才将被处理。

Web 应用部署描述符的 web-app 元素包含一个新的 “metadata-complete” 属性。“metadata-complete”属性定义了 web 描述符是否是完整的,或是否应该在部署时检查 jar 包中的类文件和 web fragments。如果 “metadata-complete” 设置为“true”,部署工具必须必须忽略存在于应用的类文件中的所有指定部署信息的 servlet 注解和web fragments。如果 metadata-complete 属性没有指定或设置为“false”,部署工具必须检查应用的类文件的注解,并扫描 web fragments。

以下注解必须被 Servlet 3.0 兼容的容器支持。

@WebServlet

该注解用于在 Web 应用中定义 Servlet 组件。该注解在一个类上指定并包含声明 Servlet 的元数据。必须指定注解的 urlPatterns 或 value属性。所有其他属性是可选的默认设置(请参考 javadoc 获取更多细节)。当注解上唯一属性是 url 模式时推荐使用 value 且当也有使用其他属性时使用 urlPatterns 属性。在同一注解上同时使用 value 和 urlPatterns 属性是非法的。如果没有指定 Servlet 名字则默认是全限定类名。被注解的 sevlet 必须指定至少一个 url 模式进行部署。如果同一个 Servlet 类以不同的名字声明在部署描述符中,必须实例化一个新的 Servlet 实例。如果使用不同名字添加的同一个 Servlet 类使用定义在4.4.1节 “编程式添加和配置 Servlet” 的编程式 API 添加到ServletContext,使用 @WebServlet 注解声明的属性值必须被忽略,必须创建一个指定名字的 Servlet 的新的实例。 @WebServlet 注解的类必须继承 javax.servlet.http.HttpServlet类。

下面是如何使用该注解的一个示例。

CODE EXAMPLE 8-1 @WebServlet Annotation Example

@WebServlet(”/foo”)
public class CalculatorServlet extends HttpServlet{
    //...
}

下面是如何使用该注解指定更多的属性的一个示例。

CODE EXAMPLE 8-2 @WebServlet annotation example using other annotation attributes specified

@WebServlet(name=”MyServlet”, urlPatterns={"/foo", "/bar"})
public class SampleUsingAnnotationAttributes extends HttpServlet{
    public void doGet(HttpServletRequest req, HttpServletResponse res) {
    }
}

@WebFilter

该注解用于在 Web 应用中定义 Filter。该注解在一个类上指定且包含声明过滤器的元数据。如果没有指定 Filter 名字则默认是全限定类名。注解的 urlPatterns 属性, servletNames 属性 或 value 属性必须被指定。所有其他属性是可选的默认设置(请参考 javadoc 获取更多细节)。当注解上唯一属性是 url 模式时推荐使用 value 且当也有使用其他属性时使用 urlPatterns 属性。在同一注解上同时使用 value 和 urlPatterns 属性是非法的。

@WebFilter 注解的类必须实现javax.servlet.Filter。

下面是如何使用该注解的一个示例。

CODE EXAMPLE 8-3 @WebFilter annotation example

@WebFilter(“/foo”)
public class MyFilter implements Filter {
    public void doFilter(HttpServletRequest req, HttpServletResponse res)
    {
        ...
    }
}

@WebInitParam

该注解指定了必须要传递给 Servlet 或 Filter 的初始化参数。这个是 WebServlet 和 WebFilter 注解的属性之一。

@WebListener

WebListener 注解用于注解用来获得特定 web 应用上下文中的各种操作事件的监听器。@WebListener 注解的类必须实现以下接口:

  • javax.servlet.ServletContextListener
  • javax.servlet.ServletContextAttributeListener
  • javax.servlet.ServletRequestListener
  • javax.servlet.ServletRequestAttributeListener
  • javax.servlet.http.HttpSessionListener
  • javax.servlet.http.HttpSessionAttributeListener
  • javax.servlet.http.HttpSessionIdListener

一个例子:

@WebListener
public class MyListener implements ServletContextListener{
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext sc = sce.getServletContext();
        sc.addServlet("myServlet", "Sample servlet", "foo.bar.MyServlet", null, -1);
        sc.addServletMapping("myServlet", new String[] {"/urlpattern/*" });
    }
}

@MultipartConfig

该注解,当指定在 Servlet 上时,表示请求期望是 mime/multipart 类型。相应 servlet 的 HttpServletRequest 对象必须使用 getParts 和getPart 方法遍历各个 mime 附件以获取 mime 附件。javax.servlet.annotation.MultipartConfig 的 location 属性和<multipart-config><location>元素被解析为一个绝对路径且默认为 javax.servlet.context.tempdir。如果指定了相对地址,它将是相对于 tempdir 位置。绝对路径与相对地址的测试必须使用java.io.File.isAbsolute。

其他注解/惯例

除了这些注解,定义在第15.5节的“注解和资源注入”将继续工作在这些新注解上下文中。

默认情况下,所有应用将有 index.htm(l) 和 index.jsp 在 welcome-file-list 列表中。该描述符可以用来覆盖这些默认设置。 当使用注解时,从 WEB-INF/classes 或 WEB-INF/lib 中的不同框架 jar 包/类加载监听器、Servlet 的顺序是没有指定的。如果顺序是很重要的,那么请看 web.xml 模块部分和后面的 web.xml 和 web-fragment.xml 顺序部分。顺序仅能在部署描述符中指定。