
Request和Response都是Servlet的service方法的参数,Request负责获取请求数据,而Response负责设置相应数据~
一.Request
1.继承体系

Tomcat负责解析数据,因此由Tomcat来提供实现类~
2.获取请求数据
- 请求行

- 请求头

- 请求体

需要注意的是只有Post方法才有请求体。因此请求体的方法应该写到Servlet的doPost方法中~

3.通用方式获取请求参数


尝试一下,先写一个用户表单:
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="//Servlet_F1_war/demo2" >
<input type="text" name="username"><br/>
<input type="password" name="password"><br/>
<input type="checkbox" name="gender" value="男">男<br/>
<input type="checkbox" name="gender" value="女">女<br/>
<input type="submit" ><br/>
</form>
</body>
</html>
注意, 第一个斜杠后面是项目的访问路径(也就是名称),第二个是自愿路径(这里是一个Servlet的注解!)
Servlet的代码如下(只演示第一个方法:)
java
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("此时调用的是get方法~");
Map<String,String[]> map = req.getParameterMap();
//键入:iter 快速遍历
for (String key : map.keySet()) {
System.out.print(key+" ");
String[] values = map.get(key);
for(String value : values)
{
System.out.print(value + ",");
}
System.out.println();
}
}
Get方法将参数提交到Url里面:
打印成功:

然后将表单的提交方式改为post,doGet方法修改如下:
java
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String m =req.getMethod();
System.out.println("此时调用的是"+m+"方法~");
Map<String,String[]> map = req.getParameterMap();
//键入:iter 快速遍历
for (String key : map.keySet()) {
System.out.print(key+" ");
String[] values = map.get(key);
for(String value : values)
{
System.out.print(value + ",");
}
System.out.println();
}
}
然后doPost直接调用doGet:
java
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
post方法将参数隐藏在请求体中:

请求成功(中文有些乱码,暂时忽略):

完整的代码如下,经供参考:
java
package Myweb;
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.Map;
@WebServlet("/demo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String m =req.getMethod();
System.out.println("此时调用的是"+m+"方法~");
Map<String,String[]> map = req.getParameterMap();
//键入:iter 快速遍历
for (String key : map.keySet()) {
System.out.print(key+" ");
String[] values = map.get(key);
for(String value : values)
{
System.out.print(value + ",");
}
System.out.println();
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
4.解决乱码
post的解决非常简单,只需要如下代码设置字符流的输入编码,即可完美解决:
java
req.setCharacterEncoding("UTF-8");
搞定~

对于汉字类型的数据,在get方式中会通过Url编码变为16进制数据。乱码的原因是Tomcat在解码时默认使用ISO-8859-1。这里给出一个通用的方式,假设中文数据的名称为username:
java
username = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);
也可以解决post方式。
不过,Tomcat8版本之后已经默认解决了GET方式乱码的问题,大家不需要操心~
5.请求转发
一种在服务器内部的资源跳转方式。

新建Servlet3号和4号如下:
java
package Myweb;
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("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("使用的是Servlet3号~");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
java
package Myweb;
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("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("使用的是Servlet4号~");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
在Servlet3中书写请求转发到Servlet4的代码:
java
req.getRequestDispatcher("/demo4").forward(req,resp);
访问Servlet3成功后,Servlet4也会一起成功:



请求转发的特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器的内部资源
- 一次请求可以在转发的资源间使用request共享数据
二.Response
1.设置响应数据

2.完成重定向
重定向是一种资源跳转方式。状态码是:302。 位置的格式是**:响应头Location:xxx**

定义两个Servlet:
java
package Myweb.Response;
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("/respd1")
public class RespDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("访问的是Response1~");
resp.setStatus(302);
resp.setHeader("Location","/Servlet_F1_war/respd2");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
java
package Myweb.Response;
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("/respd2")
public class RespDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("重定向的Resp2也被访问了~");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
虚拟路径一定要写对,这是易错点。

如上,访问1号2号也会被重定向~
java
resp.sendRedirect("/Servlet_F1_war/respd2");
如上是一种简化写法。
重定向的特点:
- 浏览器地址栏路径发生变化
- 可以重定向到任意位置的资源(服务器内部、外部均可)
- 两次请求,不能在多个资源使用request共享数据
重定向与请求转发的特点完全相反~
针对于虚拟路径:
- 浏览器使用:需要加虚拟目录(项目访问路径)
- 服务端使用:不需要加虚拟目录
javaString contextPath = request.getContextPath(); response.sendRedirect(contextPath+"/resp2");
如上是动态配置虚拟目录的方式~
3.响应字符数据
java
PrintWriter writer=resp.getWriter();
//获取字符输出流
writer.write("啦啦啦~");
writer.write("<h1>HELLO</h1>");
通过Response对象获取字符输出流,并写出数据~

存在乱码现象,且按照普通文本的读取方式~
java
resp.setContentType("text/html;charset=UTF-8");
设置头的解析方式,并设置流的编码为UTF-8。

成功。
(流不需要关闭,Response对象销毁后服务器会将其自动关闭~)
4.响应字节数据
XML
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
引入工具类坐标。
java
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1、读取文件
FileInputStream fis=new FileInputStream("E:\\照片//德拜.jpg");
//2、获取字节输出流
ServletOutputStream os = resp.getOutputStream();
//3、完成流的复制
IOUtils.copy(fis,os);
}
如上。

即可成功读取图片~