目录
Request(获取请求信息)
1.获取请求行内容
2.解决乱码问题
3.获取请求头部分
4.获取请求体
5.其他功能
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>
既然能获取到外部访问源地址,那么现在通过限制请求头的访问,外部地址的访问就会输出非法访问。
服务器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.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"));
}
}