JavaWeb ——HttpServletRequest 请求对象(附代码)
HttpServletRequest 是 JavaWeb 三大对象之一封装了客户端向服务器发送的所有请求数据是处理前端请求、获取参数、实现请求转发的工具。一、HttpServletRequest1. 作用当客户端发送 HTTP 请求到 Tomcat 服务器时Tomcat 会为每一次请求创建一个 HttpServletRequest 对象封装请求头、请求参数、请求 URL、客户端信息等所有请求数据开发者通过该对象即可获取客户端的所有请求信息。2. 功能分类封装并获取请求头数据如 User-Agent、Host获取请求相关基础信息请求方式、URL、客户端 IP、项目路径等解析并获取请求参数单值参数 / 多值参数支持 GET/POST解决请求中文乱码问题GET/POST 分别处理作为域对象实现一次请求内的数据共享实现请求转发服务器内部跳转3. 环境准备JDK8、Tomcat8.5默认支持 GET 请求中文无需额外配置项目结构原生 JavaWeb 项目包名cn.tx.servlet项目名javaweb0315下文所有路径均基于此可自行替换二、获取请求头数据1. 方法EnumerationString getHeaderNames()获取所有请求头名称String getHeader(String name)根据指定名称获取请求头值2. 代码1 ServletRequestHeaderServlet.javapackage cn.tx.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; public class RequestHeaderServlet extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解决响应中文乱码避免页面输出中文乱码 response.setContentType(text/html;charsetutf-8); PrintWriter out response.getWriter(); // 获取所有请求头名称并遍历 EnumerationString headerNames request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName headerNames.nextElement(); String headerValue request.getHeader(headerName); // 控制台打印请求头 System.out.println(headerName : headerValue); // 页面打印请求头 out.write(headerName : headerValue br/); } } }2 配置 web.xml!-- 注册获取请求头Servlet -- servlet servlet-nameRequestHeaderServlet/servlet-name servlet-classcn.tx.servlet.RequestHeaderServlet/servlet-class /servlet servlet-mapping servlet-nameRequestHeaderServlet/servlet-name url-pattern/request/header/url-pattern /servlet-mapping3. 运行验证访问地址http://localhost:8080/javaweb0315/request/header页面会展示所有请求头如 Host、User-Agent、Accept、Cookie 等Tomcat 控制台同步打印相同内容可用于服务端日志排查三、获取请求相关基础信息1. 常用方法方法名作用示例结果String getContextPath()获取项目上下文路径动态获取项目名/javaweb0315String getMethod()获取请求方式GET/POSTString getRequestURI()获取请求 URI不含域名、端口、参数/javaweb0315/request/infoStringBuffer getRequestURL()获取完整请求 URL不含参数http://localhost:8080/javaweb0315/request/infoString getQueryString()获取 URL 后的请求参数GET 专属name张三age20String getRemoteAddr()获取客户端 IP 地址127.0.0.1String getServletPath()获取Servlet 访问路径/request/infoint getServerPort()获取服务器端口号80802. 代码1 ServletRequestInfoServlet.javapackage cn.tx.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestInfoServlet extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType(text/html;charsetutf-8); response.getWriter().write(请求信息已打印到Tomcat控制台前往查看); // 逐行打印请求基础信息 System.out.println( HttpServletRequest请求基础信息 ); System.out.println(项目上下文路径 request.getContextPath()); System.out.println(请求方式 request.getMethod()); System.out.println(请求URI request.getRequestURI()); System.out.println(完整请求URL request.getRequestURL()); System.out.println(URL请求参数 request.getQueryString()); System.out.println(客户端IP request.getRemoteAddr()); System.out.println(Servlet访问路径 request.getServletPath()); System.out.println(服务器端口 request.getServerPort()); System.out.println(客户端端口 request.getRemotePort()); System.out.println(请求协议 request.getScheme()); System.out.println(服务器名称 request.getServerName()); } }2 配置 web.xml!-- 注册获取请求信息Servlet -- servlet servlet-nameRequestInfoServlet/servlet-name servlet-classcn.tx.servlet.RequestInfoServlet/servlet-class /servlet servlet-mapping servlet-nameRequestInfoServlet/servlet-name url-pattern/request/info/url-pattern /servlet-mapping3. 运行验证访问地址带参数测试 GEThttp://localhost:8080/javaweb0315/request/info?name张三age20重点查看 Tomcat 控制台getContextPath()是动态获取项目名的关键避免硬编码项目名导致的 404 问题。四、获取请求参数获取请求参数是 HttpServletRequest最常用的功能支持解析 GET/POST 提交的参数分单值参数文本、单选框和多值参数复选框方法通用GET/POST 无区别。1. 获取参数方法方法名作用适用场景String getParameter(String name)根据参数名获取单个值文本框、单选框、下拉框String[] getParameterValues(String name)根据参数名获取值数组复选框一个参数对应多个值EnumerationString getParameterNames()获取所有参数名遍历所有请求参数MapString, String[] getParameterMap()获取所有参数的键值对批量处理参数、参数校验2. 代码含 GET/POST 测试表单1 测试表单request_param.jsp放在 WebContent 下%-- 测试GET/POST提交单值参数多值参数 --% % page contentTypetext/html;charsetUTF-8 languagejava % html head titleHttpServletRequest获取请求参数/title /head body h3GET方式提交参数在地址栏可见/h3 form action${pageContext.request.contextPath}/request/param methodget 用户名input typetext nameusername value张三 placeholder请输入中文brbr 密码input typepassword namepassword value123456brbr 性别input typeradio namegender valuemale checked男 input typeradio namegender valuefemale女brbr 爱好input typecheckbox namehobby valuegame checked游戏 input typecheckbox namehobby valueread看书 input typecheckbox namehobby valuecode checked编程brbr input typesubmit valueGET提交 /form hr stylecolor: #ccc; h3POST方式提交参数在请求体不可见/h3 form action${pageContext.request.contextPath}/request/param methodpost 用户名input typetext nameusername value李四 placeholder请输入中文brbr 密码input typepassword namepassword value654321brbr 性别input typeradio namegender valuemale男 input typeradio namegender valuefemale checked女brbr 爱好input typecheckbox namehobby valuegame checked游戏 input typecheckbox namehobby valueread checked看书 input typecheckbox namehobby valuecode编程brbr input typesubmit valuePOST提交 /form /body /html2 参数解析 ServletRequestParamServlet.javapackage cn.tx.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import java.util.Map; import java.util.Set; public class RequestParamServlet extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解决POST请求中文乱码GET请求Tomcat8.5无需处理 request.setCharacterEncoding(UTF-8); // 解决响应中文乱码 response.setContentType(text/html;charsetutf-8); PrintWriter out response.getWriter(); // 1. 获取单值参数 out.write(h3 1. 单值参数获取getParameter()/h3); String username request.getParameter(username); String password request.getParameter(password); String gender request.getParameter(gender); out.write(用户名 username br/); out.write(密码 password br/); out.write(性别 gender br/); // 2. 获取多值参数复选框 out.write(h3 2. 多值参数获取getParameterValues()/h3); String[] hobbies request.getParameterValues(hobby); if (hobbies ! null hobbies.length 0) { out.write(爱好); for (String hobby : hobbies) { out.write(hobby ); } out.write(br/); } // 3. 遍历所有参数名 out.write(h3 3. 遍历所有参数名getParameterNames()/h3); EnumerationString paramNames request.getParameterNames(); while (paramNames.hasMoreElements()) { String paramName paramNames.nextElement(); // 多值参数需特殊处理单值参数直接获取 String paramValue request.getParameter(paramName); out.write(参数名 paramName → 参数值 paramValue br/); } // 4. 获取参数Map批量处理 out.write(h3 4. 获取参数键值对getParameterMap()/h3); MapString, String[] paramMap request.getParameterMap(); SetString paramKeys paramMap.keySet(); for (String key : paramKeys) { String[] values paramMap.get(key); out.write(key → ); for (String val : values) { out.write(val ); } out.write(br/); } } }3 配置 web.xml!-- 注册获取请求参数Servlet -- servlet servlet-nameRequestParamServlet/servlet-name servlet-classcn.tx.servlet.RequestParamServlet/servlet-class /servlet servlet-mapping servlet-nameRequestParamServlet/servlet-name url-pattern/request/param/url-pattern /servlet-mapping3. 运行验证访问表单地址http://localhost:8080/javaweb0315/request_param.jsp分别点击GET 提交和POST 提交页面均可正确解析单值参数和多值参数中文无乱码五、解决请求中文乱码问题前端提交中文参数时若不做编码处理后端会获取到???乱码主要原因是Tomcat 默认使用 ISO-8859-1 编码解析请求而前端默认是 UTF-8 编码编码不一致导致乱码。1. POST 请求中文乱码// 必须在所有getParameter()方法之前调用 request.setCharacterEncoding(UTF-8);说明该方法仅对POST 请求有效因为 POST 参数在请求体中方法作用于请求体编码在第一次调用 getParameter ()之前设置否则无效只需调用一次所有参数都会使用 UTF-8 解析2. GET 请求中文乱码Tomcat8.5 免处理GET 请求参数在URL 地址栏中无请求体因此request.setCharacterEncoding(UTF-8)对其无效处理方式分版本版本 1Tomcat8.5推荐Tomcat8.5 及以上版本默认使用 UTF-8 解析 URL 参数无需任何额外处理直接获取即可正常显示中文。版本 2Tomcat8.5 以下两种解决方案方案 1手动转局部有效推荐// 先通过ISO-8859-1获取字节数组再通过UTF-8解码 String username request.getParameter(username); username new String(username.getBytes(ISO-8859-1), UTF-8);方案 2修改 Tomcat 配置全局有效找到 Tomcat 安装目录下的/conf/server.xml在 Connector 标签中添加URIEncodingUTF-8Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 URIEncodingUTF-8/修改后重启 Tomcat所有 GET 请求的中文参数都会自动用 UTF-8 解析。六、request 域对象 请求转发1. request 域对象说明request 是域对象作用范围为一次请求的整个生命周期从客户端发起请求到服务器响应结束可通过 request 域在一次请求内的多个组件如 Servlet→Servlet、Servlet→JSP之间共享数据与 ServletContext 域的区别ServletContext 域是全局域服务器启动到关闭request 域是局部域仅一次请求更安全、更轻量域对象方法void setAttribute(String name, Object value)向域中存入数据键值对值为 Object 类型Object getAttribute(String name)根据键名获取域中数据需强制类型转换void removeAttribute(String name)根据键名移除域中数据2. 请求转发说明请求转发是服务器内部的跳转由 HttpServletRequest 实现是将请求从一个 Servlet/JSP 转发到另一个 Servlet/JSP整个过程属于一次请求。特点服务器内部跳转客户端浏览器地址栏不变整个过程是一次请求request 域数据可在转发的组件间共享转发路径为服务器内部路径无需加项目名仅能转发到当前项目内部的资源无法跨域方法// 路径为目标资源的Servlet/JSP路径无需加项目名 request.getRequestDispatcher(/目标资源路径).forward(request, response);3. 代码Servlet→Servlet 转发 域数据共享1 转发方 ServletRequestForwardServlet1.java存入域数据package cn.tx.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class RequestForwardServlet1 extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解决POST中文乱码 request.setCharacterEncoding(UTF-8); // 获取前端提交的参数模拟业务处理 String username request.getParameter(username); // 向request域存入数据一次请求内共享 request.setAttribute(userName, username); request.setAttribute(msg, 这是从转发方Servlet1传入的域数据); request.setAttribute(code, 200); // 请求转发到Servlet2服务器内部路径无需加项目名 request.getRequestDispatcher(/request/forward2).forward(request, response); } }2 被转发方 ServletRequestForwardServlet2.java获取域数据package cn.tx.servlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class RequestForwardServlet2 extends HttpServlet { Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 解决响应中文乱码 response.setContentType(text/html;charsetutf-8); PrintWriter out response.getWriter(); // 从request域中获取Servlet1转发过来的数据 String userName (String) request.getAttribute(userName); String msg (String) request.getAttribute(msg); Integer code (Integer) request.getAttribute(code); // 页面展示域数据 out.write(h3 请求转发成功 - 获取request域数据 /h3); out.write(状态码 code br/); out.write(用户名 userName br/); out.write(提示信息 msg br/); // 可选移除域数据 request.removeAttribute(userName); } }3 转发测试表单request_forward.jsp%-- 请求转发测试表单提交到Servlet1转发到Servlet2 --% % page contentTypetext/html;charsetUTF-8 languagejava % html head titlerequest请求转发域对象/title /head body h3request请求转发测试一次请求域数据共享/h3 form action${pageContext.request.contextPath}/request/forward1 methodpost 请输入用户名中文input typetext nameusername placeholder如张三 requiredbrbr input typesubmit value提交并转发 /form /body /html4 配置 web.xml!-- 注册转发方Servlet1 -- servlet servlet-nameRequestForwardServlet1/servlet-name servlet-classcn.tx.servlet.RequestForwardServlet1/servlet-class /servlet servlet-mapping servlet-nameRequestForwardServlet1/servlet-name url-pattern/request/forward1/url-pattern /servlet-mapping !-- 注册被转发方Servlet2 -- servlet servlet-nameRequestForwardServlet2/servlet-name servlet-classcn.tx.servlet.RequestForwardServlet2/servlet-class /servlet servlet-mapping servlet-nameRequestForwardServlet2/servlet-name url-pattern/request/forward2/url-pattern /servlet-mapping4. 运行验证访问表单地址http://localhost:8080/javaweb0315/request_forward.jsp输入中文用户名如张三点击「提交并转发」地址栏不变仍为/request/forward1页面跳转到 Servlet2 的内容页面正确展示从 Servlet1 的 request 域中获取的所有数据中文无乱码一次请求内request 域数据可在转发的组件间自由共享。七、要点总结HttpServletRequest 为每一次请求创建一个实例封装所有请求数据获取参数的 4 个方法通用GET/POST 请求无区别重点处理中文乱码POST 乱码用request.setCharacterEncoding(UTF-8)必须在 getParameter () 之前调用Tomcat8.5 默认支持 GET 中文低版本需手动转码或修改 server.xmlrequest 是域对象作用范围为一次请求用于转发时的数据共享请求转发是服务器内部跳转地址栏不变一次请求无需加项目名1request.getParameter () 和 request.getAttribute () 的区别维度getParameter()getAttribute()作用获取前端提交的请求参数获取域中存入的对象数据数据来源前端表单 / URL 地址栏后端通过 setAttribute () 存入返回值类型String单值/String []多值Object需强制类型转换适用场景解析前端提交的参数一次请求内的组件间数据共享2请求转发的特点服务器内部跳转浏览器地址栏不发生变化整个过程属于一次 HTTP 请求request 域数据可共享转发路径为服务器内部路径无需添加项目名仅能转发到当前项目内部资源不支持跨域效率高无需客户端再次发起请求3为什么 POST 请求的中文乱码处理方法对 GET 无效POST 请求的参数存放在请求体中request.setCharacterEncoding(UTF-8)作用于请求体的编码解析GET 请求的参数存放在URL 地址栏中无请求体因此该方法对其无效Tomcat8.5 对 URL 地址栏的参数默认使用 UTF-8 解析因此无需额外处理八、访问地址汇总获取请求头http://localhost:8080/javaweb0315/request/header获取请求基础信息http://localhost:8080/javaweb0315/request/info?name张三age20获取请求参数GET/POSThttp://localhost:8080/javaweb0315/request_param.jsp请求转发 域对象http://localhost:8080/javaweb0315/request_forward.jsp结尾HttpServletRequest 是 JavaWeb 开发的基础也是后续学习 SSM、Spring Boot 的铺垫。本文所有代码均基于原生 JavaWeb 规范可直接复刻运行。如果觉得本文对你有帮助欢迎点赞 收藏 关注后续会持续更新 JavaWeb 知识点
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438456.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!