请求与响应
web服务器接收到客户端的http请求,会针对这个请求分别创建一个代表请求的HttpServletRequest和一个代表响应的HttpServletResponse。
HttpServletRequest:获取客户端请求过来的参数。
HttpServletResponse:给客户端响应一些信息。(set、get、add)
一、HttpServletResponse
1、简单分类
(1)负责向客户端(浏览器)发送数据的相关方法
| getOutputStream() | 该方法用于返回Servlet引擎创建的字节输出流对象,Servlet程序可以按字节形式输出响应正文。 |
|---|---|
| getWriter() | 该方法用于返回Servlet引擎创建的字符输出流对象,Servlet程序可以按字符形式输出响应正文。 |
注意:
1,getOutputStream()和getWriter()这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。
2,getOutputStream()返回的字节输出流对象,类型为:ServletOutputStream,直接输出字节数组中的二进制数据。
3,getWriter()方法将Servlet引擎的数据缓冲区包装成P:rintWriter类型的字符输出流对象后返回,PrintWriter对象只能输出字符文本内容。
(2)负责向客户端(浏览器)发送响应头的相关方法
void setCharacterEncoding(String charset);
void setContentLength(int len);
void setContentLengthLong(long var1);
void setContentType(String var1);
| addDateHeader(String name ,long date) | 该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间 |
|---|---|
| addHeader(String name,String value) | 该方法是设置有多个值的响应头,参数name表示响应头名称,参数value表示响应头的值 |
| addIntHeader(String name,int value) | 该方法是设置有多个值且值的类型为int类型的响应头 |
| setHeader(String name,String value) | 该方法是设置只有一个值的响应头,参数name表示响应头名称,参数value表示响应头的值 |
| setDateHeader(String name,long value) | 该方法是设置只有一个值且值的类型为long类型的响应头,例如expies响应头,表示过期时间 |
| setIntHeader(String name,int value) | 该方法是设置只有一个值且值的类型为int类型的响应头,例如Content-Length响应头,该响应头是代表响应内容有多少字节数 |
//设置Content-Type响应头
resp.setHeader("Content-Type","text/html;charset=utf-8");
//添加一个响应头:xxx是表示某一响应头
resp.addHeader("xxx", "123");
//通知客户端响应内容长度为888个字节
resp.setIntHeader("Context-Length", 5);
//设置过期时间为:5000毫秒
resp.setDateHeader("", 5000);
(3) 负责向客户端(浏览器)发送响应状态码的相关方法
| setStatus(int value) | 设置临时定向响应码 |
|---|
(4)响应状态码的常量
HttpServletResponse定义了很多状态码的常量(具体可以查看Servlet的API),当需要向客户端发送响应状态码时,可以使用这些常量,避免了直接写数字,常见的状态码对应的常量:
| SC_NOT_FOUND | 状态码404对应的常量 |
|---|---|
| SC_OK | 状态码200对应的常量 |
| SC_INIERNAL_SERVER_ERROR | 状态码500对应的常量 |
200:请求响应成功 200
3xx:请求重定向 (重定向:重新到所给的新位置)
4xx:找不到资源 404
资源不存在
5xx:服务器代码错误 500 502:网关错误
2、常见应用
(1)向浏览器输出消息
(2)下载文件
要获取下载文件的路径——下载的文件名——让浏览器能够支持下载我们所需要的东西——获取下载文件的输入流——创建缓冲区——获取OutputStream对象——将FileOutputStream流写入到buffer缓冲区
——使用OutputStream将缓冲区中的数据输出到客户端
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.要获取下载文件的路径
String realPath = "D:\\code\\javaweb-01-servlet\\response\\target\\classes\\1.jpg";
System.out.println("下载文件的路径"+realPath);
// 2.下载的文件名
String filename = realPath.substring(realPath.lastIndexOf("/") + 1);
// 3.让浏览器能够支持下载("Content-disposition")我们所需要的东西 中文文件名 URLEncoder.encode(filename,"UTF-8")编码,否则可能乱码。
resp.setHeader("Content-disposition","attachment;filename"+filename+ URLEncoder.encode(filename,"UTF-8"));
// 4.获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5.创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 6.获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7.将FileOutputStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端
while ((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
}
3、验证码功能
验证怎么来的
前端实现
后端实现 需要用到java的图片类产生一个图片
public class ImageServlet extends HttpServlet {
public ImageServlet() {
super();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//让浏览器3秒刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(100,20, BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D) image.getGraphics(); //笔
//设置图片的背景颜色
g.setColor(Color.WHITE);
g.fillRect(0,0,100,20);
//给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpg");
//网站存在缓存,不让浏览器缓存
resp.setDateHeader("Expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
boolean write = ImageIO.write(image, "jpg", resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String s = random.nextInt(99999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7- s.length(); i++) {
sb.append("0");
}
s = sb.toString() + s;
return s;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4、实现重定向
![]()
web资源B收到客户端A的请求后,B会通知客户端A去访问另外一个web资源C,这个过程叫做重定向。
常见场景
用户登录
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
resp.setHeader("Location","/r/img");
resp.setStatus(302);
*/
resp.sendRedirect("/r/img"); //重定向
}
面试题:重定向和转发的区别
相同点:页面都会实现跳转
不同点:请求转发的时候,url不会发生变化 重定向的时候,url会发生变化
二、HttpServletRequset
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,Http请求中的所有信息都会被封装
到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息。
![]()

1、获取前端传递的参数,并请求转发

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println("=====================");
//后台接收中文乱码问题
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbies));
System.out.println("=====================");
//resp.sendRedirect();重定向
//this.getServletContext() 转发
//通过请求转发
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}


浙公网安备 33010602011771号