用户的浏览器往服务器端发送数据的时候,把传送的数据都放在Request对象中进行封装,到服务器端的Servlet代码中就需要使用Request把数据提取出来
文章目录
Request对象
在Java端通过Request对象获取用户浏览器传来的数据,负责获取客户端的请求数据。Request对象是客户端向服务器发出请求,包括客户端提供的信息和一些服务器的信息,比如说我们在客户端通过HTML网页或者网页地址超链接提供的一些键值对信息,通过Request就可以获取出来。
- 以下是Request对象获取请求行
method | return | describe |
---|---|---|
getMethod() | String | 获取提交的方式 |
getRequestURI() | String | 获取请求的参数,请求服务器相对路径 |
getRequestURL() | StringBuffer | 获取请求的参数,请求服务器绝对路径 |
getQueryString() | String | 获取请求行 ?后面的参数 (GET) |
getContextPath() | String | 获取WEB应用名称 |
URI:统一资源标识符
URL:统一资源定位器
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Request对象获取请求行
*
* @author 18147
*/
@WebServlet("/line")
public class LineServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//因为运行时调用的是doGet方法,所以所有演示代码都在doGet函数中编写
//实际操作时,两种方法也是相互调用关系,只需写一个即可
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取提交的方式
//getMethod()获取客户端的请求⽅式
String method = request.getMethod();
System.out.println("method = " + method);
//获取请求的参数,获取请求的服务器路径
String uri = request.getRequestURI();//uri是相对路径
StringBuffer url = request.getRequestURL();//url是从http协议开始的绝对路径
System.out.println("uri = " + uri);
System.out.println("url = " + url);
//获取请求行?之后的参数
String queryString = request.getQueryString();
System.out.println("queryString = " + queryString);
//获取当前web项目访问地址
String contextPath = request.getContextPath();
System.out.println("contextPath = " + contextPath);
}
}
修改方案:
成功!!!
Request对象获取请求头
请求头数据格式键值对: k:v
用浏览器举例:每当用户发出一条请求的时候(例如说刷新界面),浏览器就会把请求头中所有的键值对信息通过Request对象传到Servlet中,然后在Servlet中再通过Request对象把所有请求头获取出来
method | return | description |
---|---|---|
getHeader(String name) | String | 获得⼀个key对应⼀个value的请求头 |
getHeaderNames() | enum | 获得所有请求头的键 |
测试上述两种API
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 18147
* 举例:用Host键值对来测试通过key值来返回指定value值
* 举例:
*/
@WebServlet("/head")
public class HeadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//因为运行时调用的是doGet方法,所以所有演示代码都在doGet函数中编写
//实际操作时,两种方法也是相互调用关系,只需写一个即可
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取指定key的请求头信息
String header = request.getHeader("Host");
System.out.println("Host : " + header);
//获取所有请求头的key
}
}
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**
* @author 18147
*/
@WebServlet("/head")
public class HeadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//因为运行时调用的是doGet方法,所以所有演示代码都在doGet函数中编写
//实际操作时,两种方法也是相互调用关系,只需写一个即可
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取指定key的请求头信息
String header = request.getHeader("Host");
System.out.println("Host : " + header);
//获取所有请求头的key(枚举类型)
/*
* Enumeration getHeaderNames() 获取所有的请求头的键
* 返回值Enumeration接⼝ (向量枚举)
* 集合:1.0-1.1 Enumeration 集合1.2 迭代器
* Iterator迭代器接⼝: hasNext() next()
* Enumeration接⼝: hasMoreElement() nextElement()
*/
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()){//如果请求头中还有key
String key = headerNames.nextElement();//获取键
String values = request.getHeader(key);//通过当前的键来确定对应的值,和第一个API的效果一样
System.out.println(key +" = "+values);//输出测试
}
}
}
😈Request获取请求参数
method | return | description |
---|---|---|
getParameter(表单中的name值) | String | 获得提交的参数(⼀个name对应⼀个value) |
getParameterValues(表单中的name值) | String[] | 获得提交的参数(⼀个name对多个value) |
getParameterMap() | Map<String,String[]> | 获得提交的参数,将提交的参数名称和对应值存⼊到⼀个Map集合中 |
首先建立一个页面的框架,新建一个html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/param" method="get">
⽤户名:<input type="text" name="username"><br/>
密 码:<input type="password" name="password"><br/>
爱 好:<input type="checkbox" name="hobby" value="Basketball">篮球
<input type="checkbox" name="hobby" value="football">⾜球
<input type="checkbox" name="hobby" value="pingpang">乒乒球
<br/>
<input type="submit">
</form>
</body>
</html>
- getParameter()
- getParameterValues()
- getParameterMap()
总代码:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
@WebServlet("/param")
public class ParamsServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);//两个用同一套方式
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取浏览器提交的参数(一个name对应一个值的情况)
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("username = "+username);
System.out.println("password = "+password);
//获取浏览器提交的参数(一个name对应多个值的情况)
String[] hobbies = request.getParameterValues("hobby");//提供给的html界面只有hobby一项是对应多个值的
System.out.println("hobby = "+ Arrays.toString(hobbies));
//获取浏览器提交的参数(将提交的参数名称和参数值存入到一个Map集合当中)
Map<String, String[]> map = request.getParameterMap();
for (Map.Entry entry : map.entrySet()){
Object key = entry.getKey();
String[] value =(String[]) entry.getValue();
System.out.println(key+"-----------"+Arrays.toString(value));
}
}
}
Request对象接收表单请求参数的中文乱码处理
method为get
时就算输入中文也不会出现乱码的问题,但是当我们调用post
方法的时候中文乱码的问题就出现了
- 产生乱码的原因:
post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区默认编码格式为ISO-8859-1,不支持中文
下面是已经将method改为post
的html
可以看到下面中文部分已经变成了乱码
处理办法就是在doGet函数获取参数之前写入下面这条语句(将request的缓冲区的编码修改了即可):
protected void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
//将request的缓冲区的编码修改
request.setCharacterEncoding("utf-8");
//获取请求参数
String user = request.getParameter("user");
System.out.println("user = " + user);
}
之后再进行其他操作
中文乱码问题已经解决!!!
get方法写入中文
Tomcat8.5以及之后的版本会自动解决中文乱码问题,但是以前的版本不确定,如果和post方法同样出现了中文乱码问题和上面一样办法解决
- 生成乱码原因:
get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了 - 解决方案:
将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码
protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {
/*
get⽅式提交的数据在 请求⾏中
Tomcat8.5之后, Tomcat⾃动处理了get请求的中⽂乱码问题, 但在之前的Tomcat版本
中,get请求的中⽂乱码需要⾃⾏处理
⽼版本Tomcat中⽂乱码的解决:将存⼊到request缓冲区中的值以ISO-8859-1的⽅式获取
到,以UTF-8的⽅式进⾏解码。
*/
String user = request.getParameter("username");
//将存⼊到request缓冲区中的值以ISO-8859-1的⽅式获取到
//把给到的ISO-8859-1的数据拆开,按utf-8的格式拼装起来
byte[] bytes = user.getBytes("iso-8859-1");
//以UTF-8的⽅式进⾏解码
String value = new String(bytes, "utf-8");
System.out.println("user = " + user);
}
Request域对象
浏览器发送请求给服务器的Servlet,Servlet处理完Java代码后通过Response响应对象把结果返回给浏览器
Request作为域对象的API
Request对象
就是从客户端浏览器
向服务器发送的一次请求信息的封装,服务器端的Response响应对象将这些个对象返回给浏览器,实质上Request中所保存的数据有效期也是一次请求范围
(从客户端浏览器
向服务器
发送⼀次请求,服务器
针对这次请求对浏览器
作出响应。当服务器作出响应之后,通过Response对象将处理后的数据返回给浏览器客户端响应,当用户响应了返回数据后,Request和Response对象就销毁了,保存在其中的数据就无效了),也就是一次请求
与响应
的闭环区间。
method | return | description |
---|---|---|
setAttribute(String name, Object obj) | void | 向Request域中保存数据 |
getAttribute(String name) | Object | 从Request域中获取数据 |
removeAttribute(String name) | void | 从Request域中移除数据 |
在一个包下创建两个Servlet,测试API使用
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 18147
*/
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//存数据到Request域对象
request.setAttribute("key","value");
//从Request域对象中取出数据
Object value = request.getAttribute("key");
System.out.println("MyServlet == "+value);
}
}
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 18147
*/
@WebServlet("/my2")
public class My2Servlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//从Request域对象中取出数据
Object value = request.getAttribute("key");
System.out.println("MyServlet == "+value);
}
}
Request域对象实际应用——请求、转发
首先从客户端浏览器
发送一个请求到服务器中的Servlet1,在服务器内部进行转发,将请求的数据由Servlet1转发给Servlet2,最后给客户端浏览器
响应回结果。
转发的作用:之前创建的两个Servlet文件
请求转发API了解
method | return | description |
---|---|---|
getRequestDispatcher(String path) | RequestDispatcher | 通过ServletRequest对象获得RequestDispatcher对象 |
forward(ServletRequest request, ServletResponse response) | void | 根据RequestDispatcher中的方法进行请求转发 |
在之前的代码基础上添加转发功能
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 18147
*/
@WebServlet("/my")
public class MyServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//存数据到Request域对象
request.setAttribute("key", "value");
//从Request域对象中取出数据
Object value = request.getAttribute("key");
System.out.println("MyServlet == " + value);
//请求转发给Servlet2
request.getRequestDispatcher("/my2").forward(request, response);
}
}
这里要强调的是:请求转发操作是不能跨项目操作的,其中forward()方法包含的两个参数实际上就是Myservlet中的,既然是同一个request和response,也没有响应到浏览器中销毁,所以能自动跳转到转发地址“/my2”,并调用其方法。
转发和重定向
区别总结
- 请求转发是一次请求一次响应,而重定向是两次请求两次响应。
- 请求转发地址栏不会变化的,重定向地址栏发生变化。
- 请求转发路径不带工程名,重定向需要带工程名路径。
- 请求转发只能在本网站内部,重定向可以定向到任何网站。
如果需要使用request进行值传递,需要通过请求转发完成。
如果页面需要跳转到其他网站上必须使用重定向, 不能使用request进行值传递。