無論是Servlet,還是Filter,Listener等,在自定義Filter時,要想使它起作用,那麼必須要對它進行配置,一般都有兩種配置的方式,一種是基于的,另一種則是基于
配置式
的。
注解式
以Servlet為例:
在web.xml中配置:類上注解式:(基于配置式的話,就不要使用它的配置式了,即不要同時配置該Servlet的web.xml的servlet配置和類上注解添加)<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>mys</servlet-name> <servlet-class>com.mycat.web.MyFirstServlet</servlet-class> <init-param> <param-name>tom</param-name> <param-value>123</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>mys</servlet-name> <url-pattern>/myser</url-pattern> </servlet-mapping> </web-app>
package com.mycat.web; import javax.servlet.*; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import java.io.IOException; import java.io.PrintWriter; /** * 自定義的Servlet必須實作Servlet接口 */ @WebServlet(value = "/myser",initParams = @WebInitParam(name="tom",value="123")) public class MyFirstServlet implements Servlet { private ServletConfig servletConfig; private ServletRequest servletRequest; @Override public void init(ServletConfig servletConfig) throws ServletException { this.servletConfig=servletConfig; System.out.println("Servlet的初始化方法..."); } @Override public ServletConfig getServletConfig() { return servletConfig; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { this.servletRequest=servletRequest; System.out.println("service....運作時方法"); PrintWriter writer = servletResponse.getWriter(); System.out.println("獲得Servlet的配置對象:"+this.getServletConfig()); System.out.println("變量tom的值:"+servletConfig.getInitParameter("tom")); servletRequest.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html;charset=utf-8"); servletResponse.setCharacterEncoding("utf-8"); writer.println("==============================="); writer.println("<a href='myser2?username=2'>去myser2</a>"); } @Override public String getServletInfo() { return servletRequest.getServletContext().getServerInfo(); } @Override public void destroy() { System.out.println("Servlet的銷毀方法..."); } }
1.為什麼基于注解的方式可以被識别,并且可以被通路
1)先來看看@WebServlet這個注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {}; // 使用:@WebInitParam(參數清單)
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
對于Servlet來說,他有 name, value, urlpattern, loadOnStatus, initParams, asyncSupported, smallIcon, largeIcon, description, displayName 共10的屬性
name: 自定義Servlet的名稱 ,String類型。對應于web.xml中< servlet-name>的配置
value: 自定義 Servlet的映射模式,即等價于urlPattern屬性,與urlPattern屬不同同時使用,多個的話,使用逗号分隔開。參數是String[]。
urlPattern:自定義 Servlet的映射模式,即等價于value屬性,與value屬不同同時使用,對應于web.xml中< url-pattern>标簽的配置。多個的話,使用逗号分隔開。參數是String[]。
loadOnStartup: 指定Servlet的加載順序,等同于web.xml中< load-on-startup>标簽的配置,整型數值
initParams:指定一組Servlet的初始化參數,相當于web.xml中的< init-param>标簽,可以看做是Servlet的全局變量。
asyncSupported: 聲明Servlet是否支援異步操作模式,等同于web.xml中< asyn-supported>标簽
description: 對于Servlet的描述,等同于web.xml中< description>标簽
displayName: 該Servlet的顯示名,通常配合工具使用,等價于web.xml中< display-name>标簽
smallIcon和largeIcon: 表示的是Servlet的顯示圖示,即标簽頁左側的小圖示。這裡隻是表示兩個尺寸的,值為String類型的,即小圖示的位址。
使用示例:
loadOnStartUp: 即隻是Servlet法人加載順序,當其值為負數時,表示隻有在第一次請求這個Servlet,才會被加載,當其值為0或者整數時則表示整個應用程式啟動時就立即加載,而且 loadOnStartUp 越小的越先被加載。
//一個參數時,預設是value,是以可以也寫成@WebServlet("/myser2")) @WebServlet(value = "/myser2")) public class MySecondServlet extends HttpServlet { ....
@WebServlet(value = "/myser2",initParams = @WebInitParam(name="tom",value="123")) public class MySecondServlet extends HttpServlet { ....
// 多個初始化參數 initParams={@WebInitParam(...),@WebInitParam(...)...} @WebServlet(value = "/myser2",initParams = {@WebInitParam(name="username",value="tom"),@WebInitParam(name="password",value="123")}) public class MySecondServlet extends HttpServlet { ....
@WebServlet(value = "/myser2",initParams = @WebInitParam(name="tom",value="123")) public class MySecondServlet extends HttpServlet { ....
@WebServlet(value = "/myser2",loadOnStartup = -1) public class MySecondServlet extends HttpServlet { ....
分析總結:
無論是基于配置配置式的,還是基于注解式的,都會提供給對應的參數,讓引擎來解析為一個Servlet,但是注解的話,應該有個配置啥的來掃描:那就是web.xml中< web-app>标簽的metadata-complete屬性。
2)< web-app>标簽的metadata-complete屬性
metadata-complete屬性表示部署時目前的配置是否完全,值為true,表示完全,隻會應用web.xml的配置,而不會去掃描類似@WebServlet,@WebFilter,@WebListener等注解和web-frame.xml配置。 預設值
是metadata-complete=false,即不完全,會對項目中類進行掃描,是否有相關的注解配置,同時也會加載web-frame.xml等插件配置。
示例代碼:
four.jsp連結到映射到/myser4的Servlet
①預設情況:(metadata-complete=false)
web.xml中配置:MyFourServlet代碼:<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> </web-app>
測試結果:(正常運作)package com.mycat.web; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import java.io.IOException; @WebServlet("/myser4") public class MyFourServlet implements Servlet { private ServletRequest servletRequest; private ServletConfig servletConfig; @Override public void init(ServletConfig servletConfig) throws ServletException { this.servletConfig=servletConfig; System.out.println("Servlet名稱:"+servletConfig.getServletName()); System.out.println("應用上下文路徑:"+servletConfig.getServletContext().getContextPath()); } @Override public ServletConfig getServletConfig() { return servletConfig; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { this.servletRequest=servletRequest; System.out.println("運作方法..."); } @Override public String getServletInfo() { return servletConfig.getServletContext().getServerInfo(); } @Override public void destroy() {} }
Servlet名稱:com.mycat.web.MyFourServlet
應用上下文路徑:/my
運作方法…
②自定義值為true情況:(metadata-complete=true)
web.xml中配置:MyFourServlet代碼:<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" metadata-complete=true version="4.0"> </web-app>
不變測試結果:(頁面運作狀态 404 ,運作出錯,找不到對應的Servlet)Type Status Report
Message /my/myser4
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
3.關于metadata-complete屬性使用結論
本意是中繼資料書否完全(web.xml中),如果需要注解方式定義元件時,顯然必須設定為false,也就是預設值