HTTP——响应消息、Response、ServletContext
响应消息数据格式
响应行
协议/版本 响应状态码 状态码描述
响应状态码
服务器告知客户端浏览器本次请求和响应的状态
状态码都为三位数字
状态码分类
1xx:服务器接收客户端消息但没有接收完成,等待一段时间后发送1xx状态码
2xx:请求响应成功,如200
3xx:重定向,如302(重定向),304(访问缓存)
4xx:客户端错误,如404(请求路径没有对应资源),405(请求方式没有对应方法)
5xx:服务器端错误,如500(服务器内部异常)
响应头
响应头名称:响应头值
○ 常见的响应头
- Content-Type:服务器告知客户端本次响应体的数据格式以及编码格式
- Content-disposition:服务器告知客户端以什么格式打开响应体数据,默认值为in-line(在当前页面打开),可选值attachment(以附件形式打开响应体)
响应空行
空行,分隔响应头和响应体
响应体
服务器端给客户端传递的数据
Response
设置响应行
○ void setStatus(int sc) :设置状态码
设置响应头
○ void setHeader(String name, String value) :设置响应头,参数为响应头名称,响应头值
设置响应体
获取输出流
方法 | 描述 |
---|---|
ServletOutputStream getOutputStream() | 获取字节输出流 |
PrintWriter getWriter() | 获取字符输出流 |
使用输出流
// 获取字符输出流
PrintWriter writer = response.getWriter();
// 输出数据
writer.write("<p>Response</p>");
// 获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
// 输出数据
outputStream.write("Response".getBytes());
输出中文乱码问题
浏览器的默认字符集以当前操作系统语言为准,若操作系统为中文,则浏览器默认为GBK(GB2312)
而Tomcat的默认编码格式ISO-8859-1,编码解码使用的字符集不一致,则会出现中文乱码问题
在获取输出流之前,要设置流的默认编码
response.setCharacterEncoding();
response.setCharacterEncoding("GBK");
但是若浏览器解码为utf-8,也会出现乱码问题,所以服务器需要告知浏览器服务器发送消息数据的编码格式,设置响应头的Content-type响应头值为对应字符集
response.setHeader("content-type","text/html;charset=GBK");
也可以通过提供好的 setContentType() 方法来设置
response.setContentType("text/html;charset=GBK");
通过该方法可以不设置流编码,该方法可以同时设置流编码并告知客户端响应消息使用的流编码
==该方法同样也要在获取输出流之前调用==
重定向
将各种网络请求重新定个方向转到其它位置
方法1
- 设置状态码为 302
response.setStatus(302);
- 设置location响应头,响应头值为路径
response.setHeader("location","/Response/responseDemo1");
示例
responseDemo
@WebServlet("/responseDemo")
public class ResponseDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 若访问 /responseDemo,将自动跳转到 /responseDemo1
System.out.println("this is demo");
// 设置状态码
response.setStatus(302);
// 设置响应头
response.setHeader("location","/Response/responseDemo1");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
responseDemo1
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("this is demo1");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
控制台输出
this is demo
this is demo1
方法2
使用 void sendRedirect(String location) 方法进行重定向
示例
将方法1中的responseDemo代码更改为
@WebServlet("/responseDemo")
public class ResponseDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 若访问 /responseDemo,将自动跳转到 /responseDemo1
System.out.println("this is demo");
// 重定向
response.sendRedirect("/Response/responseDemo1");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
重定向与转发的区别
转发 forward | 重定向 redirect | |
---|---|---|
地址栏路径 | 不变 | 改变 |
可访问资源 | 只能访问当前服务器下的资源 | 可访问其他服务器的资源 |
请求次数 | 一次 | 两次 |
由于重定向是两次请求,所以无法使用Request对象共享数据
重定向路径写法
路径分类
(1). 相对路径:通过相对路径不可以确定唯一资源
./login.html
以 . 开头的路径
要确定当前资源与目标资源之间的相对位置关系
./:代表当前目录
../:代表上一级目录
(2). 绝对路径:通过绝对路径可以确定唯一资源
http : //localhost:8080/Response/responseDemo1
以 / 开头的路径
要判断定义的路径的使用对象/判断请求从哪里发出
- 若使用对象为客户端(如重定向,请求由浏览器发出),则需要添加虚拟目录
- 若使用对象为服务器(如转发,为服务器内部资源跳转),则不需要添加虚拟目录
动态获取虚拟目录
若重定向路径定义为绝对路径的情况下,项目虚拟目录发生变化,则需要更改大量的路径,可以使用Request对象的getContextPath()方法获取虚拟目录,并将其拼接到重定向的路径中
response.sendRedirect(contextPath + "/responseDemo1");
ServletContext
代表整个Web应用,可以和程序容器(服务器)进行通信
获取ServletContext对象
通过Request对象来获取
request.getServletContext();
通过HttpServlet获取
this.getServletContext();
通过两种方法获取到的ServletContext对象为同一个对象
javax.servlet.ServletContext servletContext1 = request.getServletContext();
javax.servlet.ServletContext servletContext2 = this.getServletContext();
System.out.println(servletContext1 == servletContext2); // 输出 true
功能
获取MIME类型
MIME类型:MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,是在互联网通信过程中定义的一种文件数据类型,是一种标准,用来表示文档、文件或字节流的性质和格式
大类型/小类型 如:text/html
方法 | 描述 | 参数 |
---|---|---|
String getMimeType(String s) | 获取MIME类型 | String 文件名 |
ServletContext servletContext = this.getServletContext(); // 获取ServletContext对象
String filename = "file.txt"; // 定义文件名称
String mimeType = servletContext.getMimeType(filename); // 获取文件的MIME类型
System.out.println(mimeType); // 输出结果为 text/plain
共享数据
方法 | 描述 |
---|---|
void setAttribute(String name, Object o) | 存储数据 |
Object getAttribute(String name) | 通过键来获取值 |
void removeAttribute(String name) | 通过键移除键值对 |
ServletContext对象范围:所有用户所有请求的数据
若当用户1使用浏览器1访问Servlet1时调用了setAttribute()方法存储了数据,用户2通过浏览器2访问Servlet2是调用 getAttribute()方法依然可以获取到用户1存储的数据
获取文件的真实路径(服务器路径)
○ String getRealPath(String Path)
ServletContext servletContext = this.getServletContext();
String path = servletContext.getRealPath("/"); // 访问web目录下资源
path = servletContext.getRealPath("/WEB-INF"); // 访问WEB-INF目录下资源
path = servletContext.getRealPath("/WEB-INF/classes"); // 访问src目录下资源
评论