1. Response组成
1.1 响应行
- 响应行是由 协议/ 版本,响应状态码,状态码描述组成。
- 响应状态码:
- 1.1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1XX多状态码
- 2.2xx:成功
- 3.3xx:302(重定向),304(访问缓存)
- 4.4xx:客户端请求错误, 404(请求路径没有对应的资源) ,405(请求方式没有对应的doxxx方法)
- 5.5xx:服务器端内部出现异常
1.2 响应头
- 响应头是由响应头名称和值组成。
- 常见的响应头:
- content-type:服务器告诉客户端本次响应体数据格式以及编码格式
- content- disposition:服务器告诉客服端以什么格式打开响应体数据
1.3 响应空行
- 分隔响应头和响应空行
1.4 响应体
- 就是传输的数据
2. Response对象
2.1 设置响应行
- 设置响应行中的状态码:setStatus(int sc);
2.2 设置响应头
- 设置响应头名称与其对应的值:setHeader(String name ,String values);
2.3 设置响应体
- 获取输出流
字节输出流:printWriter getWriter
字符输出流:servletOutputStream getOutputStream() - 使用输出流,将数据输出到客户端浏览器
3. 案例
3.1 重定向("/responseDemo1"重定向到"/responseDemo2")
- 方式一:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo1.....");
//1.设置状态码
response.setStatus(302);
//2.设置重定向的路径
response.setHeader("location","/responseDemo2");
}
- 方式二:
response.sendRedirect("/responseDemo2");
重定向与转发
-
重定向:
1.地址栏发送变化
2.重定向可以访问其他站点(服务器)的资源
3.重定向是两次请求,不能使用request对象来共享数据 -
转发:
1.转发地址栏路径不变
2.转发只能访问当前服务器下的资源
3.转发是一次请求,可以使用request对象来共享数据
3.2 服务器向浏览器输出字符流数据
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取字符输出流
PrintWriter pw = response.getWriter();
//2.输出数据
pw.write("你好 response");
}
注意:
- 服务器向浏览器输出中文数据时,可能会出现乱码
解决方式一:
response.setHeader(“content-type”,“text/html;charset=utf-8”);
解决方式二:
response.setContentType(“text/html;charset=utf-8”);
3.3 服务器向浏览器输出字节数据
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码
response.setContentType("text/html;charset=utf-8");
//获取字节输出流
ServletOutputStream sp = response.getOutputStream();
//输出数据
sp.write("你好".getBytes("utf-8"));
}
注意:
- 字节流一般输出图片等流数据,很少输出中文,纯文本数据等。
3.4 验证码
服务器里面的图片:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置验证码的宽高
int width=100;
int height=50;
//1.创建一对象,在内存中的图片(验证码图片)
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
//2.美化图片
//2.1 填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0,1,width,height);
//2.2 画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width-1,height-1);
//2.3 写验证码
Random r = new Random();
String str="ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst0123456789";
for(int i=0;i<4;i++){
int index = r.nextInt(str.length());
char c = str.charAt(index);
g.drawString(c+"",width/5*(i+1),height/2);
}
//2.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,y1,x2,y2);
}
//3.将图片输出到页面展示
ImageIO.write(image, "jpg", response.getOutputStream());
}
前端获取后台的图片:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
window.onload=function () {
//1. 获取图片对象
var img= document.getElementById("checkcode");
//2. 绑定单击事件
img.onclick=function () {
//加时间戳
var date=new Date().getTime();
img.src="/checkCode?"+date;
}
//3.a标签绑定点击事件
var a=document.getElementById("change");
a.onclick=function () {
//加时间戳
var date=new Date().getTime();
img.src="/checkCode?"+date;
}
}
</script>
</head>
<body>
<img id="checkcode" src="/checkCode">
<a id="change" href="javascript:void(0)">看不清,换一张</a>
</body>
</html>
注意:
- 第一次加载验证码图片之后,客户端浏览器会有缓存,后面请求的路径如果相同,则不会加载新的验证码,可在路径中传入一些没有意义的参数,避免与前面的路径相同即可。