1. Request: 获取请求数据
2. Response: 设置请求数据
从图中可以看出,ServletRequest
和HttpServletRequest
都是Java提供的,两者是继承关系,并且都是接口,接口无法创建对象,所以service
方法参数中的对象都是由Tomcat创建,因此就要用到Request继承体系中的**RequesrFacade
**
service
方法、deGet
方法还有doPost
方法最终都由Web服务器Tomcat来调用,所以Tomcat提供了方法参数接口的具体实现类,并完成了对象的创建HTTP请求数据一共包括三部分:请求行、请求头、请求体,三部分数据获取方式如下
请求行包括三部分内容,分别是请求方式
、请求资源路径
、HTTP协议及版本
对于这三部分内容,request对象都提供了对应的方法来获取:
GET
String getMethod()
/request-deom
String getContextPath()
http://localhost:8080/request-demo/req1
StringBuffer getRequestURL()
/request-demo/req1
String getRequestURI()
username=zhangsan&password=123
String getQueryString()
对于请求头数据,格式为key:value
,如下
根据请求头名称获取对应值的方法为:
String getHeader(String name)
浏览器在发送GET请求的时候是没有请求体的,所以要把请求方式变更为POST请求体中的数据格式如下:
Request对象提供了两种方式来获取请求体中的数据:
ServletInputStream getInputStream()
:获取字节输入流,如果前端发送的是字节数据,比如传递的是文件数据,则使用该方法
BufferedReader getReader()
:获取字符输入流,如果前端发送的是纯文本数据,则使用该方法
请求参数是请求数据的部分内容
GET
请求的请求参数在请求行中
POST
请求的的请求参数在请求体中
Ⅰ、
请求参数的获取常用的两种方式
String getQueryString()
BufferedReader getReader()
Ⅱ
request提供的通用的方式
Map<String, String[]> getParameter()
String[] getParameterValues(String name)
String getParameter(String name)
小结
req.getParameter()方法使用的频率会比较高
以后我们再写代码的时候,就只需要按照如下格式来编写:
public class RequestDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//采用request提供的获取请求参数的通用方式来获取请求参数
//编写其他的业务代码...
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
请求转发(forward):一种在服务器内部的资源跳转方式
(1)浏览器发送数据给服务器,服务器中对应的资源A接收到请求
(2)资源A处理完请求后将请求发给资源B
(3)资源B处理完后将结果响应给浏览器
(4)请求从资源A到资源的B的过程就叫请求转发
reuest.getRequestDispatcher("资源路径").forward(request, responce)
具体实现步骤代码为:
/**
* 请求转发
*/
@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo5...");
//请求转发
request.getRequestDispatcher("/req6").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
此处主要解决的问题的传递数据
需要使用Request对象提供的三个方法:
存储数据到request域[范围,数据存储在request对象]中
void setAttribute(String name, Object o)
根据key获取值
Object getAttribute(String name)
根据key删除该键值对
void removeAttribute(String name)
获取字符输出流:PrintWriter getWriter()
获取字节输出流:ServletOutputStream getOutputStream()
Response重定向(redirect):一种资源跳转方式
(1)浏览器发送数据给服务器,服务器中对应的资源A收到请求
(2)资源A无法处理该请求,就会给服务器响应一个302
的状态码+location的一个访问资源B的路径
(3)浏览器收到响应状态码为302就睡重新发送请求到location对应的访问地址去访问资源B
(4)资源B收到请求后进行处理并最终给浏览器响应结果,这个过程就叫做重定向
response.setStatus(302)
response.setHeader("location", "资源B的访问路径")
简化版的实现方式
response.sendRedirect("资源B的访问路径")
其实判断的依据很简单,只需要记住下面的规则即可:
浏览器使用:需要加虚拟目录(项目访问路径)
服务端使用:不需要加虚拟目录
对于转发来说,因为是在服务端进行的,所以不需要加虚拟目录
对于重定向来说,路径最终是由浏览器来发送请求,就需要添加虚拟目录。
要将字符数据写回到浏览器,需要两个步骤
PrintWriter writer = response.getWriter()
writer.write("aaa")
(1)返回一个简单的字符串“aaa”
/**
* 响应字符数据:设置字符数据的响应体
*/
@WebServlet("/resp3")
public class ResponseDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//1. 获取字符输出流
PrintWriter writer = response.getWriter();
writer.write("aaa");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
(2)返回一串html字符串,并且能被浏览器解析
PrinteWriter writer = response.getWriter();
//content-type,告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
response.setHeader("content-type","text/html");
writer.write("aaa
");
(3)返回一个中文字符串,需要注意设置响应数据的编码格式为utf-8
//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");
writer.write("您好")
将字节数据写回到浏览器,需要两个步骤
ServletOutputStream outputStream = response.getOutputStream()
outputStream.write(字节数据)
(1)返回一个图片文件到浏览器
/**
* 响应字节数据:设置字节数据的响应体
*/
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
byte[] buff = new byte[1024];
int len = 0;
while ((len = fis.read(buff))!= -1){
os.write(buff,0,len);
}
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
(2)上述代码中,对于流的copy的代码还是比较复杂的,所以我们可以使用别人提供好的方法来简化代码的开发,具体的步骤是:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
//fis:输入流
//os:输出流
IOUtils.copy(fis,os);
优化后的代码
/**
* 响应字节数据:设置字节数据的响应体
*/
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1. 读取文件
FileInputStream fis = new FileInputStream("d://a.jpg");
//2. 获取response字节输出流
ServletOutputStream os = response.getOutputStream();
//3. 完成流的copy
IOUtils.copy(fis,os);
fis.close();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}