1.HTTP协议
请求消息
:客户端发送给服务器端的数据
响应消息
:服务器端发送给客户端的数据
1.1.数据格式
请求消息:请求行、请求头、请求空行、请求体
响应消息:响应行、响应头、响应空行、响应体
1.2.响应数据格式
响应行
1.组成:协议/版本
响应状态码
状态码描述
2.响应状态码:服务器告诉客户端浏览器本次请求和响应的状态:https://baike.baidu.com/item/HTTP状态码/5053660?fr=aladdin2.1.状态码都是三位数字
2.2.分类:
- 1XX:服务器接收客户端消息但是没有接收完成,等待一段时间后,发送1XX状态码询问客户端是否还有数据没发完
- 2XX:
成功
,代表:200- 3XX:
重定向
,代表:302(重定向),304(访问缓存)- 4XX:客户端错误,代表:404(请求路径没有对应资源),
405
(请求方式没有对应的doXXX方法)`- 5XX:服务器端错误,代表:500(服务器内部出现异常)
响应头
1.格式:头名称 值
2.常见响应头:
- Context-Type:服务器告诉客户端本次响应体数据格式以及编码格式
- Context-disposition:服务器告诉客户端以什么格式打开响应体数据
- in-line:默认值,在当前页面打开
- attachment;filename-XXX:以附件形式打开响应体,文件下载
响应空行
:空行响应体
:传输的数据
2.Response对象
2.1.Response对象功能
功能:设置响应消息
- 设置响应行
设置状态码:setStatus(int sc)
- 设置响应头
设置响应头:setHeader(String name,String value)
- 设置响应体
使用步骤:
1.获取输出流
- 字符输出流:PrintWriter getWriter()
- 字节输出流:ServletOutputStream getOutputStream()
2.使用输出流将数据输出到客户端浏览其中
2.2.Response对象相关案例
2.2.1.完成重定向
//ResponseDemo1
package xpu.edu.web.servlet.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("/ResponseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo1.....");
//访问ResponseDemo1会自动跳转到ResponseDemo2资源
//1.设置状态码为302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","/untitled/ResponseDemo2");
//简单的重定向方法
response.sendRedirect("/untitled/ResponseDemo2");}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
//ResponseDemo2
package xpu.edu.web.servlet.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("/ResponseDemo2")
public class ResponseDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo2.....");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
重定向的特点
面试题:forward(转发)和redirect(重定向)区别
1.转发的特点:
- 转发的地址栏不变
- 转发只能访问当前服务器下的资源
- 转发是一次请求,
可以使用request对象来共享数据
2.重定向的特点
- 重定向地址栏发生变化
- 重定向可以访问其他站点的资源
- 重定向是两次请求,
不可以使用request对象来共享数据
- 路径的写法
1.路径的分类
- 相对路径:通过相对路径不可以确定唯一资源
规则:
找到当前资源和目标资源之间的相对位置关系
,“./”代表当前目录,“…/”代表后退一级目录
不以/开头,以.开头的路径,如./index.html
- 绝对路径:通过绝对路径可以确定唯一资源
以/开头的路径,如/untitled/ResponseDemo1
规则:判断定义的路径是给谁用的
,判断请求从哪里发出
- 给客户端浏览器使用:
加虚拟目录
,比如重定向,建议虚拟目录动态获取:request.getContextPath()- 给服务器使用:
不需要加虚拟路径
,比如转发动态获取虚拟目录,防止虚拟路径变化带来大量修改操作:
2.2.2.服务器输出字符数据到浏览器
- 获取字符输出流
- 输出数据
!!!注意乱码问题
:PrintWriter writer = response.getWriter()获取的流的默认编码是ISO-8859-1,所以为了防止乱码,要设置该流的默认编码(获取流之前设置)
,告诉浏览器应该使用的编码:response.setContentType(“text/html;charset=UTF-8”);
@WebServlet("/ResponseDemo3")
public class ResponseDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取流对象之前设置流的默认编码(也可以不设置)
response.setCharacterEncoding("GBK");
//告诉浏览器,服务器发出的消息体数据的编码,建议浏览器使用该编码解码
response.setHeader("content-type","text/html;charset=UTF-8");
//****简单的形式设置编码****
response.setContentType("text/html;charset=UTF-8");
//获取字符输出流
PrintWriter writer = response.getWriter();
//输出数据
writer.write("hello response");
//可以识别标签
writer.write("<h1>hello response</h1>");
//中文会乱码说明编解码不一致,浏览器默认字符集和操作系统有关
writer.write("你好 response");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
2.2.3.服务器输出字节数据到浏览器
@WebServlet("/ResponseDemo4")
public class ResponseDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
//输出数据
outputStream.write("你好".getBytes("UTF-8"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
2.2.4.验证码
验证码本质上是一张图片
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
/**
* 点击超链接或者图片,需要换一张
* 1.给超链接和图片绑定单击事件
* 2.重新设置图片的src属性值
*/
window.onload = function () {
//获取图片对象
var img = document.getElementById("Check");
//绑定单击事件
img.onclick = function () {
//加时间戳,防止路径一样直接访问缓存,那样图片没有变化
var date = new Date().getTime();
img.src = "/untitled/CheckCode?" + date;
}
//获取超链接对象
var img1 = document.getElementById("Change");
//绑定单击事件
img1.onclick = function () {
//加时间戳,防止路径一样直接访问缓存,那样图片没有变化
var date = new Date().getTime();
img.src = "看不清换一张?" + date;
}
}
</script>
</head>
<body>
<img id = "Check" src = "/untitled/CheckCode" />
<a id = "change" href = "">看不清换一张?</a>
</body>
</html>
/**
* 验证码
*/
@WebServlet("/CheckCode")
public class CheckCode extends HttpServlet {
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_INT_RGB);//RGB表示三原色的图片
//2.美化图片
//2.1.填充背景色
//获取画笔对象
Graphics graphics = image.getGraphics();
//设置画笔颜色
graphics.setColor(Color.PINK);
//填充颜色
graphics.fillRect(0,0,width,height);
//2.2.画边框
graphics.setColor(Color.BLUE);
//边框有一个像素宽度
graphics.drawRect(0,0,width - 1,height - 1);
//2.3.生成随机内容
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random ran = new Random();
for (int i = 1; i < 5; i++) {
//生成随机角标
int index = ran.nextInt(str.length());
//获取字符
char c = str.charAt(index);
//写验证码
graphics.drawString(c + "",width / 5 * i,height / 2);
}
//2.4.画干扰线
for (int i = 0; i < 6; i++) {
int x1 = ran.nextInt(width);
int x2 = ran.nextInt(width);
int y1 = ran.nextInt(height);
int y2 = ran.nextInt(height);
graphics.setColor(Color.GREEN);
graphics.drawLine(x1,y1,x2,y2);
}
//3.将图片输出到页面展示
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
}
3.ServletContext对象
概念:ServletContext对象代表整个Web应用,可以和程序的容器(服务器)来通信
3.1.获取ServletContext对象
通过request对象获取
:request.getServletContext()通过HttpServlet获取
:this.getServletContext()
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext对象的获取
//1.通过request
ServletContext servletContext = request.getServletContext();
//2.通过HttpServlet获取
ServletContext servletContext1 = this.getServletContext();
System.out.println(servletContext == servletContext1);//true
}
3.2.功能
获取MIME类型
- MIME类型定义:在互联网通信过程中定义的一种文件数据类型
- 格式:大类型/小类型,eg:text/html
@WebServlet("/ServletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext对象功能
//获取ServletContext对象,通过HttpServlet获取
ServletContext servletContext1 = this.getServletContext();
//定义一个文件名称(实际应用中是动态获取的)
String filename = "a.jpg";
//获取MIME类型
String mimeType = servletContext1.getMimeType(filename);
System.out.println(mimeType);//image/jpeg
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
域对象:共享数据
- setAttribute(String name,Object value)
- getAttribute(String name)
- removeAttribute(String name)
ServletContext域对象的范围
:所有用户所有请求数据,范围大,生命周期成,要谨慎使用
获取文件的真实(服务器)路径
方法:String getRealPath(String path)
@WebServlet("/ServletContextDemo3")
public class ServletContextDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象,通过HttpServlet获取
ServletContext servletContext1 = this.getServletContext();
//获取文件的服务器路径
String realPath = servletContext1.getRealPath("/b.txt");//Web目录下资源访问
System.out.println(realPath);
//File file = new File(realPath);
String realPath1 = servletContext1.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(realPath1);
String realPath2 = servletContext1.getRealPath("/WEB-INF/classes/a.txt");//src目录下访问资源
System.out.println(realPath2);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}