目录
HTTP协议
请求消息:客户端发送给服务器端的数据
数据格式:
1.请求行
2.请求头
3.请求空行
4.请求体
响应消息:服务器端发送给客户端的数据
数据格式:
1.响应行2.响应头
3.响应空行
4.响应体
Response响应消息
响应行
组成:协议/版本 响应状态码 状态码描述 例如HTTP/1.1 200 OK
响应状态码:服务器告诉客户端浏览器请求和响应的一个状态
状态码:
特点:状态码都是三位数字组成
分类:
1xx :服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx状态码
2xx :成功。代表性状态码:200
3xx :重定向。
代表:302(重定向),资源跳转的一种方式
代表:304 访问缓存
4xx :客户端错误
代表1: 404(请求路径没有对应的资源)
代表2:405(请求方式没有对应doXxx方法)
5xx :服务器端错误
代表1: 500(服务器内部出现异常)
响应头
格式:头名称:值
常见的响应头
1.Content-Type :服务器告诉客户端本次响应体数据格式以及编码格式
例如,Content-Type: text/html;charset=UTF-8,作用:告诉浏览器当前页面是html格式的,以及当前页面的编码格式,这会改变浏览器解码格式
2.Content-dispostion :服务器告诉客户端以什么格式打开响应体数据
值:
1.in - line :默认值,在当前页面内打开
2.attachment:filename = xxx : 以附件形式打开响应体。例如文件下载
响应体
真实的传输的数据
Response对象
功能:设置响应消息
设置响应行:
HTTP/1.1 200 OK
1.设置状态码:setStatus(int sc)
设置响应头:
setHeader(String name,String value)
设置响应体:
使用步骤:
获取输出流
字符输出流:PrintWriter getWriter()
字节输出流:ServletOutputStream getOutputStream()
2.使用输出流,将数据输出到客户端浏览器
案例练习
实现重定向
步骤:1.浏览器访问A资源时,告诉浏览器重定向:状态码302
2.告诉浏览器B资源的路径:响应头location:B资源的路径
转发的特点:
1.转发地址栏路径不变
2.转发只能访问当前服务器下的资源
3.转发是一次请求,可以使用request对象来共享数据
重定向的特点:
1.地址栏发生变化
2.重定向可以访问其他站点(服务器)的资源
3.重定向是两次请求,不能用request对象来共享数据
路径
路径分类:
1.绝对路径:通过绝对路径可以确定唯一的资源,例如http://localhost:8080/project01/demo01 通常写为/project01/demo01,以/开头
规则:判断定义的路径是给谁用的(判断请求从哪里发出·)
1.给客户端浏览器用的(重定向),需要加虚拟目录(项目的访问路径)
2.给服务器使用(服务器内部资源跳转,不需要客户点击链接),不需要加虚拟目录
注意:为了让以后写的代码具有通用性,防止未来改虚拟目录,跳转的路径将无法访问,我们使用request.getContextPath()来动态获取目录
2.相对路径:通过相对路径不可以确定唯一的资源,例如, ./index.html ,以 . 开头,可以省略./
./ :标识当前目录
../:标识后退一级目录
规则:找到访问当前资源和目标资源之间的相对位置关系
/*
重定向
访问demo01资源,会自动跳转到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;
@WebServlet("/demo01")
public class ServletResponse01 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo01被访问啦");
//1.设置状态码为302
response.setStatus(302);
//2.设置响应头location
// response.setHeader("location","/demo02");
//或者使用简单的重定向方法
response.sendRedirect("/demo02");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,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("/demo02")
public class ServletResponse02 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);
}
}
获取字符流
乱码问题
原因:编码解码不一样
解决方案:写在最前面设置响应头
response.setHeader("content-type","text/html;charset=utf-8");
更简单的形式
response.setContentType("text/html;charset=utf-8");
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取流对象之前设置编码
//response.setCharacterEncoding("GBK");
//因为我们事先可能不知道浏览器的编码
//我们需要告诉浏览器,服务器发送的消息体数据的编码,建议浏览器使用该编码解码,用下面这句替代设置编码代码
// response.setHeader("content-type","text/html;charset=utf-8");
//response提供了一个简单的形式设置编码
response.setContentType("text/html;charset=utf-8");
//获取字符输出流
PrintWriter pw = response.getWriter();
//输出数据
pw.write("hello,response");
//获取字节输出流
ServletOutputStream sos = response.getOutputStream();
//输出数据
sos.write("hello".getBytes("utf-8"));
}
ServletContext对象
概念:代表整个web应用,可以和程序的容器(服务器)来通信。
作用:
1.获取MIME类型
MIME类型:在互联网通信过程中定义的一种文件数据类型,http遵循了这种标准
MIME类型格式:大类型/小类型 例如text/html,image/jpeg
作用:用于Content-type响应头的设置,告诉浏览器发的数据是什么类型什么格式,浏览器就会以相应的方式解析。
获取方式:String getMimeType(String file)
原因:其实是通过文件后缀名获取的,因为所有文件对应的MiME类型都装在tomcat服务器中,而ServletContext又恰好可以与服务器通信。
2.域对象:共享数据
setAttribute(String name,Object value)
getAtrribute(String name)
removeAttribute(String name)
servletContext对象范围:所有用户所有请求的数据,普通对象范围只能在一次请求中共享数据。
servletContext生命周期:服务器启动,被创建,服务器停止,才被销毁。
缺点:不太安全,因为所有对象都可以使用
3.获取文件的真实路径(服务器路径)
方法: String getRealPath(String path)
获取对象的两种方法:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//servletContext的获取
ServletContext context1= request.getServletContext();
ServletContext context2 = this.getServletContext();
System.out.println(context1 == context2);//true
//无论用哪种方式获取,最终获取的都是同一个。
}
获取MIME类型:
public class ServletContext1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//servletContext的获取
// ServletContext context1= request.getServletContext();
ServletContext context2 = this.getServletContext();
System.out.println(context2 == context2);//true
//无论用哪种方式获取,最终获取的都是同一个。
String filename = "a.jpg";
String mimetype =context2.getMimeType(filename);
System.out.println(mimetype);
}
获取文件的真实路径:
例如,我们用获取真实路径的方法获取配置文件。我们知道,配置文件在idea中可以放在三处,分别是在src,web,web下新建的WEB-INF下。
举例说明,file.xml file2.xml file3.xml分别在src,web,WEB-INF中放置的。
如何获取这些文件的真实目录呢?
因为我们总是需要将配置文件加载进内存,例如在用druid连接池技术连接数据库时就会用class.getClassLoader()的方式将src下的文件加载进内存,但是这种方法非常局限,只限于src下的文件。
我们知道每一个项目都存在一个相应的配置文件:
在电脑中找到这个配置文件:
打开这个配置文件来看看:
path是虚拟路径,真正对应的服务器路径是docBase里的路径。
先来访问web目录下的file2的真实服务器路径:
public class ServletContext2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = this.getServletContext();
//获取文件的服务器真实路径
String realPath = context.getRealPath("/file2.xml");
System.out.println(realPath);
}
上面的图片显示了当我们输入/file2.xml 时访问的是web目录下的资源。
其中/代表的是上图中的D:\JAVA\JAVAhei\response\out\artifacts\response_war_exploded路径,那么web目录下的文件恰好就在该路径下,当我们要访问其他自己创建的文件夹下的文件时,那么就应该与file2.xml的位置相对比即可。
那么当我们访问WEB-INF的文件时又该如何呢?
先来看看对比file2.xml文件,WEB-INF下的文件在哪里
file2.xml文件所在处:
WEB-INF文件夹下的file3文件所在处:
访问WEB-INF下的file3文件:
public class ServletContext3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context1 = this.getServletContext();
String realpath = context1.getRealPath("/WEB-INF/file3.xml");
System.out.println(realpath);
}
如何访问src目录下的file文件呢?
src下的所有文件将会被放到WEB-INF目录下的classes目录下:
访问src目录下的file文件:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context1 = this.getServletContext();
String realpath = context1.getRealPath("/WEB-INF/classes/file.xml");
System.out.println(realpath);
}