Request(获取请求信息)
工作流程:
1.通过请求的url的资源路径,tomcat会生成相应的Servlet实现对象。
2.tomcat服务器会创建request对象和response对象,request对象接收请求消息数据。
3.tomcat将request和response方法传递给service方法并且调用service方法
4.程序员可以通过request对象获取请求的消息数据,并且设置response的响应数据
5.服务器在给浏览器响应之前获取response
1.获取请求行内容
请求行部分 | 获取请求行内容的方法 | 示例代码 | 返回值 |
请求方法(Method) | getMethod() | String method = request.getMethod(); | "GET" |
(重点)请求 URI(URL) | getRequestURI() | String uri = request.getRequestURI(); | "/index.html" |
协议版本(Protocol) | getProtocol() | String protocol = request.getProtocol(); | "HTTP/1.1" |
查询字符串(Query String) | getQueryString() | String queryString = request.getQueryString(); | null (如果没有查询字符串) |
(重点)上下文路径(Context Path) | getContextPath() | String contextPath = request.getContextPath(); | "" (如果没有上下文路径,则为空字符串) |
案例代码:
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/requestHang") public class RequestHang extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取方法 String method =req.getMethod(); System.out.println("使用的方法是"+method); // * 获取上下文路径 String contextPath = req.getContextPath(); System.out.println("请求的上下文路径是"+contextPath); // * 获取URI String Uri = req.getRequestURI(); System.out.println("请求的URI是"+Uri); // 获取协议版本 String version = req.getProtocol(); System.out.println("请求的协议版本是"+version); // 获取查询字符串 String string = req.getQueryString(); System.out.println("请求附带的查询字符串是"+string); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取方法 String method =req.getMethod(); System.out.println("使用的方法是"+method); // * 获取上下文路径 String contextPath = req.getContextPath(); System.out.println("请求的上下文路径是"+contextPath); // * 获取URI String Uri = req.getRequestURI(); System.out.println("请求的URI是"+Uri); // 获取协议版本 String version = req.getProtocol(); System.out.println("请求的协议版本是"+version); // 获取参数 String username = req.getParameter("username"); System.out.println("Username is "+username); } }
index.jsp代码:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>测试发送消息</title> </head> <body> <form action="/com_alphamilk_war_exploded/requestHang" method="get"> <input name="username"> <input type="submit" value="提交"> </form> </body> </html>
通过url访问结果如下:
编辑
可以看到请求出现了乱码,下一步就是解决请求乱码问题.
2.解决乱码问题
1.控制台输出乱码
如果tomcat的版本是在10以下的,用中文可能会出现乱码问题,这里用的是9版本,解决方法:
打开tomcat文件夹找到conf配置文件
配置文件在conf下面,将配置中的字符集改成GBK,修改后的配置如下图:
编辑
修改后重新启动结果如下:
编辑
2.post请求方式中参数中文乱码
通过将表单提交方式改为post,再在内容输入中文,通过request方法的getParameter获取参数username
编辑
可以看到输出的结果是一串乱码。所以需要进行修补
编辑
解决方法:设置流的编码即可
// 设置流的编码 req.setCharacterEncoding("utf-8");
编辑
重启服务器并再次运行:
编辑
3.获取请求头部分
示例:请求头(Request Header):Accept-Language: en-US,en;q=0.9
请求头名称 | 获取请求头值的方法 | 示例代码 | 返回值 |
Accept-Language | getHeader("Accept-Language") | String acceptLanguage = request.getHeader("Accept-Language"); | "en-US,en;q=0.9" |
所有请求头名称 | getHeaderNames() | Enumeration<String> headerNames = request.getHeaderNames(); | 包含所有请求头名称的枚举 |
案例代码:获取所有请求头信息与对应的值
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; @WebServlet("/rsHead") public class RequestHead extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 通过迭代器Enumration遍历请求头 Enumeration<String> enumeration = req.getHeaderNames(); // 开始遍历 while (enumeration.hasMoreElements()){ String name = enumeration.nextElement(); // 找到获取头名称的值 String value = req.getHeader(name); System.out.println(name+" == " +value); } } }
编辑
案例代码2:设置外部跳转无法访问,只能通过项目内的页面访问资源
通过请求头referer获取访问到当前页面的来源(如果是直接输入地址则referer为空)
首先桌面随便创建一个html文件,然后通过文件的超链接实行跳转到刚才页面
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>冒牌登陆系统</title> </head> <body> <a href="http://localhost:9998/com_alphamilk_war_exploded/rsHead">访问尝试</a> </body> </html>
编辑 防止外部跳转访问代码:
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/refererTest") public class rsRefer extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置Referer String referer = req.getHeader("referer"); // 防盗链机制 if (referer != null){ if (referer.contains("/com_alphamilk_war_exploded")){ System.out.println("正常访问"); }else { System.out.println("非法访问,请从官网处进行访问"); } } } }
重启服务器后,此时再通过随便创建的html文件修改路径后访问得到:
编辑
4.获取请求体
只有post请求方式才有请求体
步骤:
1.获取流对象 BufferReader
2.从流对象中获取值 nextline();
常用方法:
方法名 | 作用 |
getReader() |
获取请求的输入流,并返回一个BufferedReader 对象,用于读取来自客户端的请求数据。 |
getInputStream() |
获取请求的输入流,并返回一个ServletInputStream 对象,用于直接从客户端请求中读取字节数据。 |
案例代码:
html代码:
<html> <head> <title>测试发送消息</title> </head> <body> <form action="http://localhost:9998/com_alphamilk_war_exploded/body" method="post"> <input type="text" name="username" placeholder="用户名"><br> <input type="text" name="password" placeholder="密码"><br> <input type="submit"> </form> </body> </html>
Servlet类代码:
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; @WebServlet("/body") public class RequestBody extends HttpServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { BufferedReader reader = req.getReader(); String line; while (reader.readLine()!=null){ line = reader.readLine(); System.out.println(line); } } }
通过输入用户名与密码再提交表单
编辑
编辑
5.其他功能
1.获取参数通用方式(不管post请求还是get请求都可以用、重点):
方法名 | 作用 |
getParameter(String name) |
获取指定名称的请求参数的值。如果有多个同名参数,只返回第一个参数的值。 |
getParameterValues(String name) |
获取指定名称的请求参数的所有值。如果参数存在多个值,返回一个包含所有值的字符串数组。 |
Enumeration<String> getParameterNames() |
返回一个枚举对象,包含所有请求参数的名称。可以使用该枚举对象遍历所有请求参数的名称。 |
getParameterMap() |
返回一个Map 对象,其中包含所有的请求参数和它们的值。键是参数名称,值是参数的值(以字符串数组形式)。 |
案例代码:
服务器代码
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; @WebServlet("/Demo3") public class ReqOther extends HttpServlet{ HttpServletRequest req; HttpServletResponse resp; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Enumeration<String> enumeration = req.getParameterNames(); String names; // 通过迭代器遍历输出所有的参数名与对应的值 while (enumeration.hasMoreElements()){ names = enumeration.nextElement(); System.out.println(names+":"+req.getParameter(names)); } } // 由于是通用方法,所以如果有post请求则更改为Get请求流程 @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 注意post方法会出现中文乱码问题,需要转为utf-8格式编码 req.setCharacterEncoding("utf-8"); this.req = req; this.resp = resp; this.doGet(req, resp); } }
web代码更改路径地址后输入,并提交
编辑
编辑
当一个表单中出现多个相同的名字时候就需要用getParameterValues或者getParameterMap存放。
2.请求转发(服务器内部资源的跳转方式)
方法名 | 作用 |
getRequestDispatcher(String path) |
获取与给定相对路径(path )相关联的 RequestDispatcher 对象,用于在同一个 Web 应用程序内部的不同资源之间进行请求转发。 |
forward(ServletRequest request, ServletResponse response) |
将请求和响应对象转发给另一个资源(如 Servlet、JSP 页面),停止当前资源的执行,并将控制权交给目标资源,由目标资源负责生成响应。 |
案例代码:
创建一个资源类,一个访问类,通过访问类访问资源类
访问类:
package com.company; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.concurrent.TimeUnit; //资源跳转 @WebServlet("/Demo4") public class rsPatcher extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { System.out.println("3s后进行跳转"); // 3秒后进行跳转 TimeUnit.SECONDS.sleep(3); }catch (Exception e){ e.printStackTrace(); } // 定义要跳转的资源类路径 RequestDispatcher requestDispatcher = req.getRequestDispatcher("/Demo5"); // 进行跳转 requestDispatcher.forward(req,resp); } }
资源类:
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/Demo5") public class pro extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("我是资源类,我被访问了"); } }
输出:
编辑
注意:跳转只能跳转到当前项目中的资源,如果把资源改为外部路径,比如www.baidu.com这样就无法进行跳转。并且转发知识一次的请求
3.共享数据
由于一个类中的数据往往只能该类使用,但是有些资源需要进行多个对象能共享使用,所以引入了共享数据
方法名 | 作用 |
setAttribute(String name, Object value) |
将一个数据对象(value)与给定的名称(name)关联起来,将其存储在 ServletContext、HttpSession 或 HttpServletRequest 中,以便多个对象之间共享使用。 |
getAttribute(String name) |
根据给定的名称(name),从 ServletContext、HttpSession 或 HttpServletRequest 中获取与之关联的数据对象。 |
removeAttribute(String name) |
根据给定的名称(name),从 ServletContext、HttpSession 或 HttpServletRequest 中删除关联的数据对象。 |
案例代码:
设置一个运输物资类,一个资源类
运输物资类:
package com.company; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/Demo6") public class Demo6 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置共享资源,格式为 键值->对象 req.setAttribute("msg","物资"); System.out.println("当前为跳转类进行运输:"+req.getAttribute("msg")); RequestDispatcher requestDispatcher = req.getRequestDispatcher("/Demo7"); // 进行跳转 requestDispatcher.forward(req,resp); } }
资源类
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/Demo7") public class Demo7 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("资源类获取到"+req.getAttribute("msg")); } }
编辑