Servlet
一、創建Servlet類
在Java EE中,Servlet用來接收和響應終端用戶的請求。Servlet是所有Web應用程序的核心類,是唯一既可以直接處理和響應用戶請求,也可以將處理工作委托給應用中的其它部分的類。除非某些過濾器提前終止了客戶端的請求,否則所有的請求都將被發送到某些Servlet中。
所有的Servlet都實現了javax.servlet.Servlet接口,但通常不是直接實現的,Servlet知識一個簡單的接口,包含了初始化並銷毀和處理請求的方法。無論什么類型的請求都將會調用service方法。
作為響應HTTP請求的java.servlet.http.HttpServlet,並實現了只接受HTTP請求的service方法。提供了響應每種HTTP方法類型的方法的空實現。
方法 | Servlet方法 | 目的 |
GET | doGet() | 從指定的URL中獲取資源 |
HEAD | doHead() | 與GET一致,但是只返回頭部數據 |
POST | doPost() | 通常用於處理Web表單提交 |
PUT | doPut() | 存儲URL中提供的實體 |
DELETE | doDelete() | 刪除URL標識的資源 |
OPTIOND | doOptions() | 返回支持的HTTP方法 |
TRACE | doTrace() | 用於診斷目的 |
Servlet將總是繼承HttpServlet。這樣方法的接受的是javax.servlet.http.HttpServletRequest和javax.servlet.http.HttpServletResponse參數,這樣就可以輕松訪問Servlet服務所處理的請求中的HTTP特定的特性。
創建全新的空Servlet開始,讓它繼承HttpServlet。任何未重寫的HTTP Servlet方法都將返回一個HTTP狀態405作為響應,需要重寫doGET()方法,添加對HTTP GET方法的支持。
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class helloServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException{ resopnse.getWriter().println(" "); } }
初始化方法和銷毀方法
@Override public void init() throws ServletException { System.out.println("Servlet " + this.getServletName() + " has started."); } @Override public void destroy() { System.out.println("Servlet " + this.getServletName() + " has stopped."); }
二、配置可部署的Servlet
在創建完Servlet之后,盡管已經有了一個可以響應HTTP GET請求並發出問候的類,需要再WEB-INF目錄中創建的web.xml文件,並對Servlet進行配置,使它可以正確地部署到服務器中。然后使得瀏覽器可以訪問到該Servlet。
在web.xml中的初始化文件:
<?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_3_1.xsd" version="3.1"> <display-name>Hello World Application</display-name><--?代表了應用程序在應用服務器中顯示的名字--> </web-app>
當需要該訴Web容器創建一個之前實例Servlet的實例,因此在描述符文件中的開始和結束標志符中添加一個Servlet標簽:
<servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.wrox.HelloServlet</servlet-class> </servlet>
同時
<load-on-startup>1</load-on-startup>
如果多個Servlet配置都包含了該標簽,它們將按照標簽內值的大小順序啟動,值越小越先啟動。,如果多個Servlet的<load-on-startup>配置相同,將按照它們在描述符文件中出現的順序啟動。
將Servlet映射到URL中,在告訴應用服務器如何啟動Servlet之后,需要告訴該Servlet應該如何應該對那些請求URL做出響應:
<servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/greeting</url-pattern> </servlet-mapping>
使用該配置之后,所有訪問應用程序相對URL/greeting的請求都將有helloServlet處理,其中<servlet>和<servlet-mapping>標簽內的<servlet-name>標簽應該一致。當然可以通過多個<url-pattern>標簽,讓多個URL映射到同一個servlet中。對有相同邏輯但是不同處理頁面的web就可以將其連接到同一個servlet,只是在<servlet-name>中添加不同的實例名稱。
三、doGet()和doPost()
Servlet類的service方法會處理所有到達的請求。最終,它必須根據所使用的協議解析並處理到達請求中的數據,然后返回客戶端可接受的響應。擴展HttpServlet使我們不需要考慮到任何細節。
HttpServletRequest接口是對ServletRequest的擴展,將提供關於收到請求的額外的與HTTP協議相關信息。
獲取請求參數:
HttpServletRequest最重要的功能是從客戶端發送的請求中獲取參數。請求參數有兩種不同的形式:
查詢參數(URI參數),以application/x-www-form-urlencodeed或multipart/form-data編碼的請求正文。
getParameter方法將返回參數的單個值,如果參數有多個值,將返回第一個值,getParameterValues將返回參數的值的數組。
確定與請求內容相關的信息:
getContentType方法將確定HTTP請求內容的類型,
getContentLenght方法和getContentLengthLong都返回了請求正文的長度,
getCharacterEncoding方法將返回請求內容的字符編碼。
讀取請求的內容:
getInputStream和getReader都可以用來讀取請求的內容,如果是UTF-8和ISO-8859-1則使用getReader是最簡單的方法,如果是二進制格式則使用getInputStream是最方便的,但是在調用其中一個方法之后不可以再調用另外一個。
獲取請求的特有數據:
getRequestURL,返回客戶端完整用於創建請求的完整的URL。
getRequestURI,只返回URL中服務器路徑部分。
getServletPath,返回更少的URI。
getHeader,返回制定名字的頭數據。
getHeaderName,返回請求中所有頭數據的名字的枚舉。
getIntHeader和getDataHeader。
使用HttpServletResponse
HttpServletResponse提供了對請求中與HTTP協議相關屬性的訪問,並且可以使用相應對象完成設置響應頭,編寫響應正文,重定向請求,設置HTTP狀態碼以及將Cookies返回到客戶端等任務。
編寫響應正文:
就是講內容輸出道響應正文中,可以是在瀏覽器中顯示的HTML、瀏覽器中希望獲取的圖像或者下載的文件內容。getOutputStream方法將返回一個javax.servlet.ServletOutputStream,而方法getWriter將返回一個java.io.PrintWriter,通過他們可以向響應中輸出數據,但是不要對一個對象同時使用上述兩種方法。在向響應正文中輸出數據時,可能需要設置內容類型或編碼格式:setContentType和setCharacterEncoding。
另外還可以使用:
setStatus:設置HTTP響應狀態碼,
getStatus:獲取當前的響應狀態,
sendError:設置狀態碼,
sendRedirect:將客戶端重定向至另一個URL。
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String user = request.getParameter("user"); if(user == null) user = HelloServlet.DEFAULT_USER; response.setContentType("text/html"); response.setCharacterEncoding("UTF-8"); PrintWriter writer = response.getWriter(); writer.append("<!DOCTYPE html>\r\n") .append("<html>\r\n") .append(" <head>\r\n") .append(" <title>Hello User Application</title>\r\n") .append(" </head>\r\n") .append(" <body>\r\n") .append(" Hello, ").append(user).append("!<br/><br/>\r\n") .append(" <form action=\"greeting\" method=\"POST\">\r\n") .append(" Enter your name:<br/>\r\n") .append(" <input type=\"text\" name=\"user\"/><br/>\r\n") .append(" <input type=\"submit\" value=\"Submit\"/>\r\n") .append(" </form>\r\n") .append(" </body>\r\n") .append("</html>\r\n"); }
四、初始化參數配置應用程序
初始化參數配置應用程序可以提供一些配置應用程序和其中Servlet的方式。通過上下文初始化參數和Servlet初始化參數進行設置是最簡單的方法,這些參數可以定義關系數據庫的鏈接信息,提供發送訂單警告的郵件地址,這些參數在啟動時定義,重啟才會被修改。
<context-param> <param-name>settingOne</param-name> <param-value>foo</param-value> </context-param> <context-param> <param-name>settingTwo</param-name> <param-value>bar</param-value> </context-param>
在初始化參數之后可以在Servlet代碼的任何地方使用這些參數
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletConfig c = this.getServletConfig(); PrintWriter writer = response.getWriter(); writer.append("database: ").append(c.getInitParameter("database")) .append(", server: ").append(c.getInitParameter("server")); }
另外一種初始化參數的方法是通過注解:
@WebServlet{ name = "servletParameterServlet", urlPatterns = {"/servletParameters"}, initParams = { @WebInitParam{name = "database", value = "CustomerSupport"}, @WebInitParam{name = "server", value = "10.0.12.5"} } }