Request
备注:该技术博客的内容是我根据技术视频整理与总结的(并非复制粘贴)。原视频源于黑马JavaWeb课程
一、Request原理
首先,我们要掌握request和response对象的原理
1.request和response对象是由服务器创建的。我们来使用他们呢
2.request对象是来获取请求消息,response对象是来设置响应消息
这样才能更好地指导这两个对象怎么去学习,他们是做什么的。我们通过画图的方式来讲解:
首先,请求会携带请求消息找demo1资源,可以找到
因为我们在服务器端有一个Servlet配置的urlpatten是/demo1 (@WebServlet(“/demo1”))
所以找到了这个类,然后Tomcat会自动执行service方法
我们聊聊这个过程:
1.Tomcat服务器会根据请求url中的资源路径(/demo1)去创建对应的SerlvetDemo1对象
2.Tomcat服务器会创建两个对象,分别是request和response对象。request对象中封装请求消息数据
3.tomcat将request和response两个对象传递service方法,并且去调用service方法
4.我们可以来操作通过request对象获取请求消息数据,可以通过response对象设置响应消息数据
5.服务器在给浏览器做出响应之前会从response对象中去拿程序员设置的响应消息数据
接下来,我们来学request对象获取请求消息
但是学习它之前我们先说一说request继承体系结构
二、Request继承体系结构
ServletRequest --接口
| 继承关系
HttpServlet Request --接口
| 实现关系
org.apache.catalina.connector.RequestFacade
org.apache.catalina.connector.RequestFacade是一个类,实现了HTTPServlet接口。
这个类是Tomcat编写的,Tomcat将来通过这个类来创建Request对象,并且传递给service方法。
三、Request对象的功能
获取请求消息数据:
- 获取请求行数据
请求行:
GET /day14/demo1?name=zhangsan HTTP/1.1
获取数据方法:
1.获取请求方式:GET
String getMehtod()
2.获取虚拟目录(重点掌握):/day14
String getContextPath()
3.获取Servlet路径:/demo1
String getServletPath()
4.获取get方式的请求参数:name=zhangsan
String getQueryString()
5.获取请求的URI(重点掌握):/day14/demo1
String getRequestURI(): /day14/demo1
StringBuffer getRequestURL(): http://localhost/day14/demo1
URL:统一资源定位符 http://localhost/day14/demo1 (相当于中华人民共和国)
URI:统一资源标识符 /day14/demo1 (相当于共和国)
6.获取协议及版本: HTTP/1.1
String getProtocol()
7.获取客户机的IP地址:
String getRemoteAddr()
代码演示:
package cn.itcast.web.request;
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 javax.swing.*;
import java.io.IOException;
/**
* 演示Request对象获取请求行数据
*/
@WebServlet("/requestDemo1")
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取请求方式:
String method = request.getMethod();
System.out.println(method);
//2.获取虚拟目录(重点掌握):
String contextPath = request.getContextPath();
System.out.println(contextPath);
//3.获取Servlet路径:
String servletPath = request.getServletPath();
System.out.println(servletPath);
//4.获取get方式的请求参数:
String queryString = request.getQueryString();
System.out.println(queryString);
//5.获取请求的URI(重点掌握):
String requestURI = request.getRequestURI();
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURI);
System.out.println(requestURL);
//6.获取协议及版本:
String protocol = request.getProtocol();
System.out.println(protocol);
//7.获取客户机的IP地址:
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
输出结果如下:
GET
/day14
/requestDemo1
name=zhangsan
/day14/requestDemo1
http://localhost/day14/requestDemo1
HTTP/1.1
0:0:0:0:0:0:0:1
- 获取请求头数据
获取方法:
1.(重点掌握)String getHeader(String name):通过请求头的名称获取请求头的值
2.Enumeration<String> getHeaderNames():获取所有的请求头名称
代码演示:
package cn.itcast.web.request;
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;
@WebServlet("/requestDemo4")
public class RequestDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//演示获取请求头数据:referer
String referer = request.getHeader("referer");
System.out.println(referer);//http://localhost/day14/login.html
//防盗链
if (referer != null){
if (referer.contains("/day14")){
//正常访问
System.out.println("播放电影...");
}else{
//盗链
System.out.println("想看电影吗?来优酷吧....");
}
}
}
}
- 获取请求体数据
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
获取请求体步骤:
1.获取流对象
BufferedReader getReader():获取字符输入流,只能操作字符数据 (此博客演示这个方法)
ServletInputSream getInputStream():获取字节输入流,可以操作任何类型数据(在文件上传知识点后讲解)
2.再从流对象中拿数据
代码展示:
package cn.itcast.web.request;
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.BufferedReader;
import java.io.IOException;
@WebServlet("/requestDemo5")
public class RequestDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体--请求参数
//1.获取字符流
BufferedReader br = request.getReader();
//2.读取数据
String line = null;
while ((line = br.readLine()) != null){
System.out.println(line);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
四、其他功能
- 获取请求参数通用方式:不论get还是post请求方式都可以使用下列方式方法来获取请求参数。
1.String getParameter(String name):根据参数名称获取参数值 (常用)
2.String[] getParameterValues(String name):根据参数名称获取数值的数组
3.Enumeration<String> getParameterNames():获取所有请求的参数名称
4.Map<String,String[]> getParameterMap():获取所有参数的map集合 (常用)
代码演示这四个方法:
第一个方法:
@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//post 获取请求参数
//根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println("post");
System.out.println(username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get 获取请求参数
/*//根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println("get");
System.out.println(username);*/
this.doPost(request,response);
}
}
================================================================================
第二个方法:
@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//post 获取请求参数
//根据参数名称获取参数值
String username = request.getParameter("username");
/*System.out.println("post");
System.out.println(username);*/
//根据参数获取参数值的数组
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get 获取请求参数
/*//根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println("get");
System.out.println(username);*/
this.doPost(request,response);
}
}
================================================================================
第三个方法:
@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//post 获取请求参数
//根据参数名称获取参数值
String username = request.getParameter("username");
/*System.out.println("post");
System.out.println(username);*/
//根据参数获取参数值的数组
String[] hobbies = request.getParameterValues("hobby");
/*for (String hobby : hobbies) {
System.out.println(hobby);
}*/
//获取所有请求的参数名称
Enumeration<String> parameterNames = request.getParameterNames();
while (parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
System.out.println(name);
String value = request.getParameter(name);
System.out.println(value);
System.out.println("------------------------------------");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get 获取请求参数
/*//根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println("get");
System.out.println(username);*/
this.doPost(request,response);
}
}
================================================================================
第四个方法:
@WebServlet("/requestDemo6")
public class RequestDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//post 获取请求参数
//根据参数名称获取参数值
String username = request.getParameter("username");
/*System.out.println("post");
System.out.println(username);*/
//根据参数获取参数值的数组
String[] hobbies = request.getParameterValues("hobby");
/*for (String hobby : hobbies) {
System.out.println(hobby);
}*/
//获取所有请求的参数名称
Enumeration<String> parameterNames = request.getParameterNames();
/*while (parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
System.out.println(name);
String value = request.getParameter(name);
System.out.println(value);
System.out.println("------------------------------------");*/
//获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
//遍历
Set<String> keyset = parameterMap.keySet();
for (String name : keyset) {
//根据键获取值
String[] values = parameterMap.get(name);
System.out.println(name);
for (String value : values) {
System.out.println(value);
}
System.out.println("-----------------------");
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//get 获取请求参数
/*//根据参数名称获取参数值
String username = request.getParameter("username");
System.out.println("get");
System.out.println(username);*/
this.doPost(request,response);
}
}
- 请求转发:一种在服务器内部的资源跳转方式
1.步骤:
1.通过request对象来获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
2.使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
2.特点:
1.浏览器地址栏路径不发生变化
2.只能转发到当前的服务器内部资源中
3.转发是一次请求
代码演示:
//RequestDemo8类
@WebServlet("/requestDemo8")
public class RequestDemo8 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8888被访问了...");
//转发到demo9资源
/*RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
requestDispatcher.forward(request,response);*/
request.getRequestDispatcher("/requestDemo9").forward(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
=========================================================================================
//RequestDemo9类
@WebServlet("/requestDemo9")
public class RequestDemo9 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo9999被访问了...");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
- 共享数据:
域对象:一个有作用范围的对象,可以在范围内共享数据。
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
1.void setAttribute(String name,Object obj):存储数据
2.Object getAttribute(String name):通过键获取值
3.void remove Attribute(String name):通过键移除键值对
1234567
代码演示:
//RequestDemo8类
@WebServlet("/requestDemo8")
public class RequestDemo8 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8888被访问了...");
//转发到demo9资源
/*RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
requestDispatcher.forward(request,response);*/
//存储数据到request域中
request.setAttribute("msg","hello");
request.getRequestDispatcher("/requestDemo9").forward(request,response);
/*request.getRequestDispatcher("http://www.itcast.cn").forward(request,response);*/
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
=========================================================================================
//RequestDemo9类
@WebServlet("/requestDemo9")
public class RequestDemo9 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取数据
Object msg = request.getAttribute("msg");
System.out.println(msg);
System.out.println("demo9999被访问了...");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
- 获取ServletContext对象(有个印象即可)
1.ServletContext getServletContext()
1
代码如下:
@WebServlet("/requestDemo10")
public class RequestDemo10 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = request.getServletContext();
System.out.println(servletContext);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
五、解决中文乱码问题:
get方式:tomcat8以上的版本已经将get方式乱码问题解决了
post方式:会乱码
解决:在获取参数前,设置request的编码 request.setCharacterEncoding("urf-8");
代码演示如下:
@WebServlet("/requestDemo7")
public class RequestDemo7 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.设置流的编码
request.setCharacterEncoding("utf-8");
//获取请求参数username
String username = request.getParameter("username");
System.out.println(username);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}