前言:HttpServletRequest對象封裝了客戶端進行HTTP協議請求時的全部信息,HttpServletRequest繼承了ServletRequest,因此和ServletRequest同樣,是由tomcat服務器提供實現的。具體過程以下:html
1)Web客戶向Servlet容器發出Http請求;java
2)Servlet容器解析Web客戶的Http請求;web
3)Servlet容器建立一個HttpRequest對象,在這個對象中封裝Http請求信息;api
1.HttpServlet
瀏覽器
說到HttpServletRequest就不得不說一下HttpServlet,下面看它的API:tomcat
java.lang.Object javax.servlet.GenericServlet javax.servlet.http.HttpServlet
Method Summary | |
---|---|
protected void |
doDelete(HttpServletRequest req,HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a DELETE request. |
protected void |
doGet(HttpServletRequest req,HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a GET request. |
protected void |
doHead(HttpServletRequest req,HttpServletResponse resp) Receives an HTTP HEAD request from the protected service method and handles the request. |
protected void |
doOptions(HttpServletRequest req,HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a OPTIONS request. |
protected void |
doPost(HttpServletRequest req,HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a POST request. |
protected void |
doPut(HttpServletRequest req,HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a PUT request. |
protected void |
doTrace(HttpServletRequest req,HttpServletResponse resp) Called by the server (via the service method) to allow a servlet to handle a TRACE request. |
protected long |
getLastModified(HttpServletRequest req) Returns the time the HttpServletRequest object was last modified, in milliseconds since midnight January 1, 1970 GMT. |
protected void |
service(HttpServletRequest req,HttpServletResponse resp) Receives standard HTTP requests from the public service method and dispatches them to thedo XXX methods defined in this class. |
void |
service(ServletRequest req,ServletResponse res) Dispatches client requests to the protected service method. |
service(ServletRequest req,ServletResponse res)
方法和servlet中的一致,在每次請求時調用。只抽取部分方法,概要信息以下:
(1).doGet(HttpServletRequest req,HttpServletResponse resp)
:接收HTTP的GET請求;服務器
(2).doPost(HttpServletRequest req,HttpServletResponse resp)
:接收HTTP的POST請求;cookie
(3).service(HttpServletRequest req,HttpServletResponse resp)
:接收HTTP請求,並把它分配到doXXX方法中;網絡
2.HttpServletRequest的API:session
String |
getAuthType() Returns the name of the authentication scheme used to protect the servlet. |
String |
getContextPath() Returns the portion of the request URI that indicates the context of the request. |
Cookie[] |
getCookies() Returns an array containing all of the Cookie objects the client sent with this request. |
long |
getDateHeader(String name) Returns the value of the specified request header as a long value that represents aDate object. |
String |
getHeader(String name) Returns the value of the specified request header as a String . |
Enumeration |
getHeaderNames() Returns an enumeration of all the header names this request contains. |
Enumeration |
getHeaders(String name) Returns all the values of the specified request header as an Enumeration ofString objects. |
int |
getIntHeader(String name) Returns the value of the specified request header as an int . |
String |
getMethod() Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT. |
String |
getPathInfo() Returns any extra path information associated with the URL the client sent when it made this request. |
String |
getPathTranslated() Returns any extra path information after the servlet name but before the query string, and translates it to a real path. |
String |
getQueryString() Returns the query string that is contained in the request URL after the path. |
String |
getRemoteUser() Returns the login of the user making this request, if the user has been authenticated, or null if the user has not been authenticated. |
String |
getRequestedSessionId() Returns the session ID specified by the client. |
String |
getRequestURI() Returns the part of this request's URL from the protocol name up to the query string in the first line of the HTTP request. |
StringBuffer |
getRequestURL() Reconstructs the URL the client used to make the request. |
String |
getServletPath() Returns the part of this request's URL that calls the servlet. |
HttpSession |
getSession() Returns the current session associated with this request, or if the request does not have a session, creates one. |
HttpSession |
getSession(boolean create) Returns the current HttpSession associated with this request or, if there is no current session andcreate is true, returns a new session. |
Principal |
getUserPrincipal() Returns a java.security.Principal object containing the name of the current authenticated user. |
boolean |
isRequestedSessionIdFromCookie() Checks whether the requested session ID came in as a cookie. |
boolean |
isRequestedSessionIdFromUrl() Deprecated. As of Version 2.1 of the Java Servlet API, use isRequestedSessionIdFromURL() instead. |
boolean |
isRequestedSessionIdFromURL() Checks whether the requested session ID came in as part of the request URL. |
boolean |
isRequestedSessionIdValid() Checks whether the requested session ID is still valid. |
boolean |
isUserInRole(String role) Returns a boolean indicating whether the authenticated user is included in the specified logical "role". |
這裏只列舉經常使用的幾個方法(有些API中沒有列舉到的,是在ServletRequest中已有的方法):
(1)得到客戶機信息
:返回客戶端發出請求時的完整URL。getRequestURL()
getRequestURI()
:返回請求行中的資源名部分。
getQueryString()
:返回請求行中的參數部分。
getRemoteAddr()
:返回發出請求的客戶機的IP地址。
getRemoteHost()
:返回發出請求的客戶機的完整主機名。
getRemotePort()
:返回客戶機所使用的網絡端口號。
getLocalAddr()
:返回WEB服務器的IP地址。
getLocalName()
:返回WEB服務器的主機名。
(2)得到客戶機請求頭
getHeaders(String name)
:得到請求頭信息組成的Enumeration。
(3)得到客戶機請求參數(客戶端提交的數據)
getParameterMap():獲取參數名和參數值的
String[]組成的鍵值對,即返回的類型爲
Map(
String
,String[]
),用於多參數值。
3.項目的目錄結構
4.web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>javaWeb_07</display-name> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>httpRequestDemo</servlet-name> <servlet-class>com.dao.chu.HttpRequestDemo</servlet-class> </servlet> <servlet-mapping> <servlet-name>httpRequestDemo</servlet-name> <url-pattern>/httpRequest</url-pattern> </servlet-mapping> </web-app>
5.login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>登錄頁</title> </head> <body> <!-- 相對路徑寫action="httpRequest"; --> <!-- 絕對路徑寫action="/javaWeb_07/httpRequest"; --> <form action="httpRequest" method="get"> 用戶名:<input type="text" name="user"> <br><br> 密碼 <input type="password" name="password"> <br><br> <!-- 一組信息 --> interesting: <input type="checkbox" name="interesting" value="reading">Reading <input type="checkbox" name="interesting" value="writing">Writing <input type="checkbox" name="interesting" value="football">Football <input type="checkbox" name="interesting" value="game">Game <input type="checkbox" name="interesting" value="shopping">Shopping <input type="checkbox" name="interesting" value="party">Party <input type="checkbox" name="interesting" value="TV">TV <br><br> <input type="submit" value="提交"> </form> </body> </html>
(1)只寫一個service方法
package com.dao.chu; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Enumeration; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * <p> * Title: HttpRequestDemo Description:繼承了HttpServlet的測試類 * </p> */ public class HttpRequestDemo extends HttpServlet { /** serialVersionUID */ private static final long serialVersionUID = 1L; // 獲得請求的URL地址 String requestUrl = ""; // 獲得請求行中的資源部分 String requestUri = ""; // 獲得請求的URL地址中附帶的參數 String queryString = ""; // 獲得來訪者的IP地址 String remoteAddr = ""; // 來訪者主機名 String remoteHost = ""; // 客戶機所使用的網絡端口號 int remotePort = 0; // 獲得請求方式GET/POST String method = ""; // 獲取WEB服務器的IP地址 String localAddr = ""; // 獲取WEB服務器的主機名 String localName = ""; /** * 繼承了HttpServlet的service方法 */ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //調用公共輸出方法 commonPrint(request, response); } /** * Title: commonPrint * Description:公共輸出方法 * @param request * @param response */ private void commonPrint(HttpServletRequest request, HttpServletResponse response) { // 設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器 response.setCharacterEncoding("UTF-8"); // 經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據,若是不加這句話,那麼瀏覽器顯示的將是亂碼 response.setHeader("content-type", "text/html;charset=UTF-8"); requestUrl = request.getRequestURL().toString(); requestUri = request.getRequestURI(); queryString = request.getQueryString(); remoteAddr = request.getRemoteAddr(); method = request.getMethod(); localAddr = request.getLocalAddr(); localName = request.getLocalName(); PrintWriter out; try { out = response.getWriter(); out.write("<hr/>"); out.write("(1)獲取客戶機信息:"); out.write("<br/>"); out.write("請求的URL地址:" + requestUrl); out.write("<br/>"); out.write("請求的資源:" + requestUri); out.write("<br/>"); out.write("請求的URL地址中附帶的參數:" + queryString); out.write("<br/>"); out.write("來訪者的IP地址:" + remoteAddr); out.write("<br/>"); out.write("來訪者的主機名:" + remoteHost); out.write("<br/>"); out.write("使用的端口號:" + remotePort); out.write("<br/>"); out.write("請求的方式:" + method); out.write("<br/>"); out.write("服務器的IP地址:" + localAddr); out.write("<br/>"); out.write("服務器的主機名:" + localName); // 獲取的客戶機的請求頭信息 out.write("<br/>"); out.write("<hr/>"); out.write("(2)獲取客戶機的請求頭信息:"); out.write("<br/>"); // 獲得全部請求頭名組成的Enumeration Enumeration<String> headerNames = request.getHeaderNames(); // 循環 while (headerNames.hasMoreElements()) { // 獲得全部的請求頭名 String headerName = (String) headerNames.nextElement(); // 根據請求頭名獲得全部請求頭值 String headerValue = request.getParameter(headerName); out.write(headerName + ": " + headerValue); out.write("<br/>"); } // 獲取的客戶機的請求信息 out.write("<br/>"); out.write("<hr/>"); out.write("(3)獲取客戶機的請求信息:"); out.write("<br/>"); // 獲取參數名和參數值的String[]組成的鍵值對 Map<String, String[]> map = request.getParameterMap(); Set<Entry<String, String[]>> entrySet = map.entrySet(); for (Entry<String, String[]> entry : entrySet) { out.write(entry.getKey() + ": " + Arrays.asList(entry.getValue())); out.write("<br/>"); } } catch (IOException e) { e.printStackTrace(); } } }
(2)寫有service方法,doget方法,dopost方法
package com.dao.chu;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* <p>
* Title: HttpRequestDemo Description:繼承了HttpServlet的測試類
* </p>
*/
public class HttpRequestDemo extends HttpServlet {
/** serialVersionUID */
private static final long serialVersionUID = 1L;
// 獲得請求的URL地址
String requestUrl = "";
// 獲得請求行中的資源部分
String requestUri = "";
// 獲得請求的URL地址中附帶的參數
String queryString = "";
// 獲得來訪者的IP地址
String remoteAddr = "";
// 來訪者主機名
String remoteHost = "";
// 客戶機所使用的網絡端口號
int remotePort = 0;
// 獲得請求方式GET/POST
String method = "";
// 獲取WEB服務器的IP地址
String localAddr = "";
// 獲取WEB服務器的主機名
String localName = "";
/**
* 繼承了HttpServlet的service方法
*/
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
System.out.println("調用了service方法");
//調用公共輸出方法
commonPrint(request, response);
}
/**
* 繼承了HttpServlet的doGet方法
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("調用了doGet方法");
//調用公共輸出方法
commonPrint(request, response);
}
/**
* 繼承了HttpServlet的doPost方法
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("調用了doPost方法");
//調用公共輸出方法
commonPrint(request, response);
}
/**
* Title: commonPrint
* Description:公共輸出方法
* @param request
* @param response
*/
private void commonPrint(HttpServletRequest request,
HttpServletResponse response) {
// 設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器
response.setCharacterEncoding("UTF-8");
// 經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據,若是不加這句話,那麼瀏覽器顯示的將是亂碼
response.setHeader("content-type", "text/html;charset=UTF-8");
requestUrl = request.getRequestURL().toString();
requestUri = request.getRequestURI();
queryString = request.getQueryString();
remoteAddr = request.getRemoteAddr();
method = request.getMethod();
localAddr = request.getLocalAddr();
localName = request.getLocalName();
PrintWriter out;
try {
out = response.getWriter();
out.write("<hr/>");
out.write("(1)獲取客戶機信息:");
out.write("<br/>");
out.write("請求的URL地址:" + requestUrl);
out.write("<br/>");
out.write("請求的資源:" + requestUri);
out.write("<br/>");
out.write("請求的URL地址中附帶的參數:" + queryString);
out.write("<br/>");
out.write("來訪者的IP地址:" + remoteAddr);
out.write("<br/>");
out.write("來訪者的主機名:" + remoteHost);
out.write("<br/>");
out.write("使用的端口號:" + remotePort);
out.write("<br/>");
out.write("請求的方式:" + method);
out.write("<br/>");
out.write("服務器的IP地址:" + localAddr);
out.write("<br/>");
out.write("服務器的主機名:" + localName);
// 獲取的客戶機的請求頭信息
out.write("<br/>");
out.write("<hr/>");
out.write("(2)獲取客戶機的請求頭信息:");
out.write("<br/>");
// 獲得全部請求頭名組成的Enumeration
Enumeration<String> headerNames = request.getHeaderNames();
// 循環
while (headerNames.hasMoreElements()) {
// 獲得全部的請求頭名
String headerName = (String) headerNames.nextElement();
// 根據請求頭名獲得全部請求頭值
String headerValue = request.getParameter(headerName);
out.write(headerName + ": " + headerValue);
out.write("<br/>");
}
// 獲取的客戶機的請求信息
out.write("<br/>");
out.write("<hr/>");
out.write("(3)獲取客戶機的請求信息:");
out.write("<br/>");
// 獲取參數名和參數值的String[]組成的鍵值對
Map<String, String[]> map = request.getParameterMap();
Set<Entry<String, String[]>> entrySet = map.entrySet();
for (Entry<String, String[]> entry : entrySet) {
out.write(entry.getKey() + ": "
+ Arrays.asList(entry.getValue()));
out.write("<br/>");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)寫有service方法,doget方法,dopost方法,且service方法調用了父類的service(HttpServletRequest req,HttpServletResponse resp)
方法。
package com.dao.chu; import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Enumeration; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * <p> * Title: HttpRequestDemo Description:繼承了HttpServlet的測試類 * </p> */ public class HttpRequestDemo extends HttpServlet { /** serialVersionUID */ private static final long serialVersionUID = 1L; // 獲得請求的URL地址 String requestUrl = ""; // 獲得請求行中的資源部分 String requestUri = ""; // 獲得請求的URL地址中附帶的參數 String queryString = ""; // 獲得來訪者的IP地址 String remoteAddr = ""; // 來訪者主機名 String remoteHost = ""; // 客戶機所使用的網絡端口號 int remotePort = 0; // 獲得請求方式GET/POST String method = ""; // 獲取WEB服務器的IP地址 String localAddr = ""; // 獲取WEB服務器的主機名 String localName = ""; /** * 繼承了HttpServlet的service方法 */ @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("調用了service方法"); //調用公共輸出方法 commonPrint(request, response); //依舊調用父類的方法 super.service(request, response); } /** * 繼承了HttpServlet的doGet方法 */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("調用了doGet方法"); //調用公共輸出方法 commonPrint(request, response); } /** * 繼承了HttpServlet的doPost方法 */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("調用了doPost方法"); //調用公共輸出方法 commonPrint(request, response); } /** * Title: commonPrint * Description:公共輸出方法 * @param request * @param response */ private void commonPrint(HttpServletRequest request, HttpServletResponse response) { // 設置將字符以"UTF-8"編碼輸出到客戶端瀏覽器 response.setCharacterEncoding("UTF-8"); // 經過設置響應頭控制瀏覽器以UTF-8的編碼顯示數據,若是不加這句話,那麼瀏覽器顯示的將是亂碼 response.setHeader("content-type", "text/html;charset=UTF-8"); requestUrl = request.getRequestURL().toString(); requestUri = request.getRequestURI(); queryString = request.getQueryString(); remoteAddr = request.getRemoteAddr(); method = request.getMethod(); localAddr = request.getLocalAddr(); localName = request.getLocalName(); PrintWriter out; try { out = response.getWriter(); out.write("<hr/>"); out.write("(1)獲取客戶機信息:"); out.write("<br/>"); out.write("請求的URL地址:" + requestUrl); out.write("<br/>"); out.write("請求的資源:" + requestUri); out.write("<br/>"); out.write("請求的URL地址中附帶的參數:" + queryString); out.write("<br/>"); out.write("來訪者的IP地址:" + remoteAddr); out.write("<br/>"); out.write("來訪者的主機名:" + remoteHost); out.write("<br/>"); out.write("使用的端口號:" + remotePort); out.write("<br/>"); out.write("請求的方式:" + method); out.write("<br/>"); out.write("服務器的IP地址:" + localAddr); out.write("<br/>"); out.write("服務器的主機名:" + localName); // 獲取的客戶機的請求頭信息 out.write("<br/>"); out.write("<hr/>"); out.write("(2)獲取客戶機的請求頭信息:"); out.write("<br/>"); // 獲得全部請求頭名組成的Enumeration Enumeration<String> headerNames = request.getHeaderNames(); // 循環 while (headerNames.hasMoreElements()) { // 獲得全部的請求頭名 String headerName = (String) headerNames.nextElement(); // 根據請求頭名獲得全部請求頭值 String headerValue = request.getParameter(headerName); out.write(headerName + ": " + headerValue); out.write("<br/>"); } // 獲取的客戶機的請求信息 out.write("<br/>"); out.write("<hr/>"); out.write("(3)獲取客戶機的請求信息:"); out.write("<br/>"); // 獲取參數名和參數值的String[]組成的鍵值對 Map<String, String[]> map = request.getParameterMap(); Set<Entry<String, String[]>> entrySet = map.entrySet(); for (Entry<String, String[]> entry : entrySet) { out.write(entry.getKey() + ": " + Arrays.asList(entry.getValue())); out.write("<br/>"); } } catch (IOException e) { e.printStackTrace(); } } }
7.填寫jsp頁面表單,發出HTTP請求
8.三種狀況的現象
(1)頁面顯示
控制檯無輸出,說明成功調用了service方法。
(2)頁面顯示
控制檯輸出:
說明雖然寫了dopost和doget方法,可是卻沒有接收到請求。
(3)頁面顯示
控制檯打印:
很顯然此次接收到了doGET方法
8.爲了追求根源,咱們找到HttpServlet的service方法的源碼:
/** * <p>Title: HttpServlet的service方法的源碼</p> * <p>Description: </p> * @throws ServletException * @throws IOException */ protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); if (method.equals("GET")) { long lastModified = getLastModified(req); if (lastModified == -1L) { doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch (IllegalArgumentException iae) { ifModifiedSince = -1L; } if (ifModifiedSince < lastModified / 1000L * 1000L) { maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(304); } } } else if (method.equals("HEAD")) { long lastModified = getLastModified(req); maybeSetLastModified(resp, lastModified); doHead(req, resp); } else if (method.equals("POST")) { doPost(req, resp); } else if (method.equals("PUT")) { doPut(req, resp); } else if (method.equals("DELETE")) { doDelete(req, resp); } else if (method.equals("OPTIONS")) { doOptions(req, resp); } else if (method.equals("TRACE")) { doTrace(req, resp); } else { String errMsg = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[1]; errArgs[0] = method; errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(501, errMsg); } }
String method = req.getMethod();if (method.equals("GET")){doGet(req, resp);}等
的確有接收請求的方式,根據判斷的請求方式轉到相應的方法。而咱們在(2)中繼承了HttpServlet,覆蓋了service方法,沒有調用原來父類的方法,因此即便寫了doget和dopost也接收不到請求。
附:
本次項目源碼:點擊打開連接