## HTTP协议:
1、请求消息:客户端发送给服务器端的数据
* 数据格式:
1、请求行
2、请求头
3、请求空行
4、请求体
2、响应消息:服务器端发送给客户端的数据
* 数据格式:
1、响应行
1、组成:协议/版本 响应状态码 状态码描述
2、响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
1、状态码都是3位数字
2、分类:
1、1xx:服务器接收客户端消息,但没有接收完成,等到一段时间后,发送1xx多状态码
2、2xx:成功。代表:200
3、3xx:重定向。代表:302(重定向);304(访问缓存)
4、4xx:客户端错误。
* 404:请求路径没有对应的资源
* 405:请求方式没有对应的doXxx方法
5、5xx:服务器端错误。代表:500(服务器内部出现异常)
2、响应头
1、格式: 头名称 :值
2、常见的响应头:
1、Content-type:服务器告诉客户端本次响应体数据格式以及编码格式
2、Content-disposition:服务器告诉客户端以什么格式打开响应体数据
* 值:
* in-line:默认值,在当前页面内打开
* attachment;filename-xxx:以附件形式打开响应体。文件下载
3、响应空行
4、响应体:传输的数据
* 响应字符串格式:
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
Content-Length: 101
Date: Wed, 06 Jun 2018 07:08:42 GMT
<html>
<head>
<title>$Title$</title>
</head>
<body>
hello , response
</body>
</html>
## Response对象
1、功能:设置响应消息
1、设置响应行
1、格式:HTTP/1.1 200 ok
2、设置状态码:setStatus(int sc)
2、设置响应头:setHeader(String name, String value)
3、设置响应体
* 步骤:
1、获取输出流:
* 字符输出流:PrintWrite getWrite()
* 字节输出流:ServletOutPutSream get OutputStream()
2、使用出书流,将数据输出到客户端浏览器
2、案例
1、重定向
* 重定向:资源跳转的方式
* 代码实现:
package com.Response.demo01; 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("/responseDemo01") public class ResponseDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("go to demo2222"); /*//1、设置状态码 resp.setStatus(302); //2、设置响应头 resp.setHeader("location","/responseDemo02");*/ //更简单的重定向方法 resp.sendRedirect("/responseDemo02"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
* 重定向的特点:
1、地址栏发生编码
2、重定向可以访问其他站点(服务器)的资源
3、重定向是两次请求,不能使用request对象来共享数据
* 转发的特点:
1、转发地址栏路径不变
2、转发只能访问当前服务器下的资源
3、转发是一次请求,可以使用request对象来共享数据
* 路径写法:
1、路径分类:
* 相对路径:通过相对路径不可以确定唯一资源
* 如:./index.html
* 不以/开头,以.开头
* 规则:找到当前资源和目标资源之间的相对位置关系
* ./:当前目录
* ../:后退一级目录
* 绝对路径:通过绝对路径可以确定唯一资源
以/开头的路径
* 规则:判断定义的路径是给谁用?判断请求将来从哪儿发出
* 给客户端浏览器使用:需要加虚拟目录(项目的访问路径)
* 建议虚拟目录动态获取:request.getContextPath()
* <a> <form> 重定向
* 给服务器使用:不需要虚拟目录
* 转发路径
2、服务器输出字符数据到浏览器
* 步骤:
1、获取字符输出流
2、输出数据
* 注意:
* 乱码问题:
1、PrintWriter pw = resp.getWriter();获取的流的默认编码是ISO-8859-1
2、设置该流的默认编码
3、告诉浏览器响应体使用的编码
package com.Response.demo02; 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.io.PrintWriter; /** * 输出字符数 */ @WebServlet("/responseDemo03") public class ResponseDemo01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置响应编码集 resp.setCharacterEncoding("utf-8"); resp.setHeader("content-type","text/html;charset=utf-8"); //简单形式设置编码(要在获取流之前设置) resp.setContentType("text/html;charset=utf-8"); //1、获取字符输出流 PrintWriter pw = resp.getWriter(); //2、输出数据 pw.write("你好呀!冯艇钧"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
3、服务器出书字节数据到浏览器
* 步骤:
1、获取字节输出流
2、输出数据
4、验证码
1、本质:图片
2、目的:防止恶意表单注册
基本逻辑:
package com.Response.demo02; import javax.imageio.ImageIO; 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.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.PrintWriter; import java.util.Random; /** * 验证码 */ @WebServlet("/checkCode") public class checkCode extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { int width = 200; int height = 100; //创建一个对象,在内存中蹄片(验证码图片对象) BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); //2、美化图片 //2.1 填充背景色 Graphics g = image.getGraphics(); g.setColor(Color.PINK);//设置画笔颜色 g.fillRect(0, 0, width, height); //2.2 画边框 g.setColor(Color.BLUE); g.drawRect(0, 0, width, height); //3.2 写验证码 String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; //生成随机角标 Random r = new Random(); for (int i = 1; i <= 4; i++) { int index = r.nextInt(str.length()); //获取字符 char ch = str.charAt(index);//随机字符 System.out.println(ch); g.drawString(ch + "", width / 5 * i, height / 2); } /*g.drawString("A",20,25); g.drawString("B",40,25); g.drawString("C",60,25); g.drawString("D",80,25);*/ //3.4 画干扰线 g.setColor(Color.green); for (int i = 0; i < 10; i++) { int x1 = r.nextInt(width); int x2 = r.nextInt(width); int y1 = r.nextInt(height); int y2 = r.nextInt(height); g.drawLine(x1,x2,y1,y2); } //g.drawLine(1,1,30,30); //3、将图片输出到页面 ImageIO.write(image, "jpg", resp.getOutputStream()); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } }
点击图片生成验证码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>验证码</title> <script> window.onload = function () { //点击图片切换验证码 let code = document.getElementById("checkCode"); /*code.onclick = function () { code.src = "/checkCode?" + new Date().getTime(); }*/ let link = document.getElementById("link"); link.onclick = function () { code.src = "/checkCode?" + new Date().getTime(); } } </script> </head> <body> <img src="/checkCode" id="checkCode"> <a href="" id="link">看不清楚图片换一张?</a> </body> </html>