簡介
servlet 本身是一個 JAVA 程序(或者其他環境的程序), 通過 web.xml 文件把 請求資源頁 反射成 JAVA對象到內存, 反射的對象需要實現 javax.servlet 裏的 HttpServlet 接口
映射方式
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>cn.it.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello/1234</url-pattern>
</servlet-mapping>
訪問主機名/hello/1234 就能映射到 cn.it.HelloServlet, 前提該類要實現好 implements Servlet 接口
Servlet 接口
public void init(ServletConfig config) throws ServletException
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>cn.it.HelloServlet</servlet-class>
<init-param>
<param-name>WEB_NAME</param-name>
<param-value>HELLO IT</param-value>
</init-param>
<init-param>
<param-name>WEB_NAME2</param-name>
<param-value>HELLO IT2</param-value>
</init-param>
<init-param>
<param-name>WEB_NAME3</param-name>
<param-value>HELLO IT3</param-value>
</init-param>
</servlet>
public void init(ServletConfig config) throws ServletException {
System.out.println("Init");
System.out.println(config.getInitParameter("WEB_NAME")); // 輸出: HELLO IT
Enumeration<String> names = config.getInitParameterNames();
while( names.hasMoreElements() )
{
String name = names.nextElement();
System.out.println(name + ":" + config.getInitParameter(name)); // 遍歷輸出
// init
// PARAM
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
servlet 層次範圍
轉載下別人的筆記
一、Servlet生命週期
servlet的生命週期:init(ServletConfig)、service(ServletRequest,ServletResponse)、destroy()
- public class HelloWorldInit implements Servlet {
- public HelloWorldInit(){
- System.out.println("hello 默認構造");
- }
- public void init(ServletConfig config) throws ServletException {
- System.out.println("init");
- }
- public void service(ServletRequest request, ServletResponse response)
- throws ServletException, IOException {
- System.out.println("service");
- }
- public void destroy() {
- System.out.println("destroy");
- }
- public ServletConfig getServletConfig() {
- return null;
- }
- public String getServletInfo() {
- return null;
- }
- }
輸出結果:
爲什麼會創建構造方法?
Tomcat服務器加載web.xml中的<servlet-class>com.test.HelloWorldInit</servlet>時,會根據這個類路徑通過反射創建該類的實例。在服務器中操作大概過程如下:
- Class clazz = Class.forName("com.test.HelloWorldInit");
- Object obj = clazz.newInstance();//調用了構造方法
然後通過反射獲取該對象裏的init和service方法並調用,調用時會傳入相應的實參(ServletConfig、ServletRequest和ServletResponse)
二、init(ServletConfig config)和service(ServletRequest request, ServletResponse response)倆方法的參數解析
- public void init(ServletConfig config) throws ServletException {
- System.out.println("config:"+config);
- }
- public void service(ServletRequest request, ServletResponse response)
- throws ServletException, IOException {
- System.out.println("request:"+request+"\n"+"response:"+response);
- }
輸入結果:
上圖輸出的結果分別是ServletConfig、ServletRequest、ServletResponse的實現類,下圖爲源碼中的實現
(1)javax.servlet.ServletConfig(接口),該接口下有四個抽象方法
- public void init(ServletConfig config) throws ServletException {
- //1、<servlet-name>返回這個裏面的名稱</servlet-name>
- System.out.println(config.getServletName());
- //2、返回指定初始化參數名稱的值,如果參數不存在就返回Null(在web.xml中要配置初始化參數)
- System.out.println(config.getInitParameter("gf"));
- //3、返回當前servlet的所有的初始化參數的名稱,返回的是一個Enumeration(枚舉)
- Enumeration<String> names = config.getInitParameterNames();
- while(names.hasMoreElements()){
- String name = names.nextElement();
- System.out.println(name + ":" + config.getInitParameter(name));
- }
- //4、ServletConfig保存了當前web項目的 ServletContext的引用
- ServletContext sc = config.getServletContext();
- System.out.println(sc);
- //實現類:org.apache.catalina.core.ApplicationContextFacade
- }
- <servlet>
- <servlet-name>helloWorldInit</servlet-name>
- <servlet-class>cn.test.HelloWorldInit</servlet-class>
- <!-- 配置初始化參數列表 -->
- <init-param>
- <!-- 初始化參數的名稱 -->
- <param-name>gf</param-name>
- <!-- 初始化參數的值 -->
- <param-value>規範</param-value>
- </init-param>
- </servlet>
(2)javax.servlet.ServletRequest和javax.servlet.ServletResponse(service方法的兩個參數)]
- /**第一個參數*/
- //接口:javax.servlet.ServletRequest
- //實現類:org.apache.catalina.connector.RequestFacade
- /*
- * 關係:
- * * public class RequestFacade implements HttpServletRequest {
- * * public interface HttpServletRequest extends ServletRequest {
- *
- * 總結: RequestFacade --> HttpServletRequest --> ServletRequest
- * ************
- * ServletRequest req = new RequestFacade();
- * HttpServletRequest http = new RequestFacade();
- * HttpServletRequest http2 = (HttpServletRequest)req;
- */
- /**第二個參數*/
- //接口:javax.servlet.ServletResponse
- //實現類:org.apache.catalina.connector.ResponseFacade
- /* 關係:
- * * public class ResponseFacade implements HttpServletResponse {
- * * public interface HttpServletResponse extends ServletResponse {
- *
- * * 總結:ResponseFacade --> HttpServletResponse --> ServletResponse
- */
- HttpServletResponse response = (HttpServletResponse)resp;
三、Servlet實現初始化工作
- public class FirstServlet extends HttpServlet {
- //進行初始化,直接覆蓋GenericServlet的init()方法
- @Override
- public void init() throws ServletException {
- //初始化工作
- }
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- this.doPost(request, response);
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- }
- }
- <servlet>
- <servlet-name>FirstServletxx</servlet-name>
- <servlet-class>cn.itcast.servlet.FirstServlet</servlet-class>
- <!-- 配置當前servlet在服務器啓動時加載順序
- 取值:0-6 ,值越小,優先加載
- -->
- <load-on-startup>2</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>FirstServletxx</servlet-name>
- <url-pattern>/firstServlet</url-pattern>
- </servlet-mapping>
四、servlet的虛擬路徑
1) 只能使用 / 或 * 開頭
2) / 和 *. 不能同時存在
3) / 或 /* 表示任意
4) 只有*.才表示通配符
五、項目路徑
(1)getAbsolutePath( )
案例1:
- public static void main(String[] args) {
- File file = new File("");
- System.out.println(file.getAbsolutePath());//absolute絕對的意思
- }
輸出結果:
用命令窗口執行:
JAVA項目的class文件是存放在項目根目錄的bin目錄下
案例2:
- public static void main(String[] args) {
- File file = new File("/") ; // '/'是相對路徑,相對於當前盤符 可以獲得當前盤符
- System.out.println(file.getAbsolutePath());
- }
輸出結果都爲:F:\(命令運行和eclipse運行)
總結:getAbsolutePath()使用java命令時輸出的路徑是當前Java命令停留的目錄,使用eclipse運行時輸出的路徑是當前項目根目錄的絕對路徑
注意:生成jar包后里面的沒有src和bin目錄的,生成jar包的過成是把bin目錄下的文件全都拷貝過來,所以將配置文件放在src下其實就是在根目錄下
(2)類加載器獲取路徑
- public static void main(String[] args) {
- //類加載器
- //通過類 -> 獲得字節碼 -> 獲得類加載器 -> 獲得資源路徑
- //路徑指向class文件存放的目錄
- URL url = Hello.class.getClassLoader().getResource("");
- / InputStream is = Hello.class.getClassLoader().getResourceAsStream(""); //跟getResource一樣
- System.out.println(url);
- }
輸出結果:file:/F:/myeclipse/Workspaces/TestProject/WebRoot/WEB-INF/classes/
注意:類加載器不能使用"/"
(3)ServletContext獲取路徑
ServletContext是對當前項目上下文的描述(對當前web項目所有內容的描述),tomcat爲每一個web項目單獨創建一個區域,用來管理整個項目。此區域稱爲ServletContext。
context root是指當前項目的根目錄:
* tomcat --> webapps/webName
* myeclipse --> webName/WebRoot 指向的是WebRoot目錄
- public void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
- ServletContext sc2 = this.getServletConfig().getServletContext();
- ServletContext sc = this.getServletContext();
- //1 、
- String path = sc.getRealPath("/1.html");//獲得實際路徑,要求/開頭
- System.out.println(path);// F:\apache-tomcat-7.0.29\webapps\day06\1.html
- //2、獲得資源文件
- URL url = sc.getResource("/1.html");
- System.out.println(url.getPath());// /localhost/day06/1.html
- //3、
- InputStream is = sc.getResourceAsStream("/1.html");
- System.out.println(is);
- }
輸出結果:F:\apache-tomcat-7.0.29\webapps\day06\1.html
要求必須以'/'開頭
(4)web的相對路徑
1、abc:與當前頁面同級的目錄或servlet的名稱
* <a href="c/c.html">c.html</a><br>
2、/abc:相對於web站點,%tomcat%/webapps/
* <a href="/day06_web/b/c/c.html">c.html</a><br>
3、./abc:當前目錄,與第一種情況相同
* <a href="./c/c.html">c.html</a><br>
4、../abc:上一次目錄
* <a href="../b/c/c.html">c.html</a><br>
六、Servlet過濾器Filter
所有的Servlet過濾器類都必須實現javax.servlet.Filter接口。這個接口含有3個過濾器類必須實現的方法:
init( FilterConfig config);//Servlet容器創建Servlet過濾器實例後將調用這個方法。在這個方法中可以讀取web.xml文件中Servlet過濾器的初始化參數
doFilter( ServletRequest req, ServletResponse resp ,FilterChain chain);//FilterChain參數用於訪問後續過濾器
destroy( );
在web.xml中必須先配置過濾器再配置Servlet
- import java.io.IOException;
- import java.io.PrintWriter;
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
- import javax.servlet.http.HttpServletRequest;
- public class MyFilter implements Filter {
- private FilterConfig config = null;
- private String blackList = null;
- public void init(FilterConfig config) throws ServletException {
- this.config = config;
- blackList = config.getInitParameter("blacklist");
- }
- public void destroy() {
- config = null;
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- String username = ((HttpServletRequest) request)
- .getParameter("username");
- if (username != null)
- username = new String(username.getBytes("ISO-8859-1"), "GB2312");
- if (username != null && username.indexOf(blackList) != -1) {
- response.setContentType("text/html;charset=GB2312");
- PrintWriter out = response.getWriter();
- out.println("<html><head></head><body>");
- out.println("<h1>對不起," + username + ",你沒有權限留言 </h1>");
- out.println("</body></html>");
- out.flush();
- return;
- }
- long before = System.currentTimeMillis();
- config.getServletContext().log(
- "NoteFilter:before call chain.doFilter()");
- chain.doFilter(request, response);
- config.getServletContext()
- .log("NoteFilter:after call chain.doFilter()");
- long after = System.currentTimeMillis();
- String name = "";
- if (request instanceof HttpServletRequest) {
- name = ((HttpServletRequest) request).getRequestURI();
- }
- config.getServletContext().log(
- "NoteFilter:" + name + ": " + (after - before) + "ms");
- }
- }
- <filter>
- <filter-name>myFilter</filter-name>
- <filter-class>com.test.filter.MyFilter</filter-class>
- <init-param>
- <param-name>blacklist</param-name>
- <param-value>hello</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>myFilter</filter-name>
- <url-pattern>/NoteServlet</url-pattern>
- </filter-mapping>