前言: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也接收不到请求。
附:
本次项目源码:点击打开连接