Servlet学习3 -- Response对象和Servlet
一.Response对象
-
Response的作用
Response对象是用来设置HTTP响应消息的,包括了响应行,响应头,响应体。
-
Response继承体系
ServletResponse -- 接口
| 继承
HttpServletResponse -- 接口
| 实现
org.apache.catalina.connector.ResponseFacade 类(tomcat) -
Response的功能API
-
设置响应行(格式:HTTP/1.1 200 ok)
setStatus(int sc)
:设置状态码 -
设置响应头
setHeader(String name, String value)
-
设置响应体
设置响应体有两种方式:
-
PrintWriter getWriter()
:字符输出流 -
ServletOutputStream getOutputStream()
:字节输出流ServletOutputStream是OutputStream的子类,可以当做OutputStream对待,输出字节流,当需要输出二进制格式的响应时需要使用getOutputStream()。
注意:两个方法getWriter()和getOutputStream()都可以发送响应消息体,但是两个不能同时使用,会出现异常。
-
-
重定向功能
重定向是一种资源跳转的方式。
方法为:
void sendRedirect(String path)
重定向特点:
- 重定向,浏览器的地址栏会变化。
- 重定向可以访问其他服务器的站点资源。
- 重定向是两次请求,无法使用request对象共享数据。
重定向和转发的区别:
- 重定向是response发出的响应,转发是request调用
- 因为重定向是response发出的响应,浏览器拿到后会再去请求,所以重定向是两次请求,而转发是服务器内部的,对于浏览器来说并没有再次请求,只有一次请求。
- 重定向是response返回给浏览器的,浏览器再去请求,因此可能下一次请求是其他服务器的资源(比如www.baidu.com),因此地址栏是会变化的,而转发是服务器内部,浏览器并不知道,所以地址栏不会变化,当然也无法访问其他服务器的资源了,只能访问当前服务器下的资源。
-
-
关于路径的书写问题
使用规则:判断路径是给谁使用
给服务器使用:不需要加虚拟目录(比如转发)
给浏览器使用:需要加虚拟目录(比如重定向),虚拟目录最好使用方法获取,request.getContextPath()
-
response乱码问题
原因:response缓冲区的默认编码是ISO8859-1,这个码表是没有中文的,所以需要手动更改response的编码方式。
解决方式:在获取响应输出流之前设置编码:
response.setContentType("text/html;charset=utf-8")
二.ServletContext对象
-
什么是ServletContext对象
ServletContext对象在Tomcat启动的时候就会创建,代表着整个web应用,可以和程序的容器(服务器)通信。
-
ServletContext对象作用
- ServletContext代表着整个Web应用,那么所有的Servlet都共享同一个ServletContext对象,因此Servlet之间可以通过ServletContext对象实现通信
- ServletContext可以获取整个web应用的配置信息
- 利用ServletContext能够读取web应用的资源文件
-
ServletContext对象获取
-
通过request对象获取
request.getServletContext()
-
通过HttpServlet获取
this.getServletContext()
-
-
ServletContext对象功能
-
获取MIME类型
MIME类型:是在互联网通信过程中定义的一种文件数据类型,格式为:大类型/小类型,比如text/html,image/jpg等
方法:
String getMimeType(String file)
-
域对象(共享数据)
setAttribute(String name, Object value)
getAttribute(String name)
removeAttribute(String name)
注意:ServletContext的范围是对所有的Servlet
-
获取资源文件的路径
以前获取文件路径,只需要指定文件的绝对路径或相对路径即可,但在web应用中不可行,因为web应用是部署在服务器上的,对于路径的获取有以下几种情况:
- 如果资源文件在src下某个包中,则路径该是:/WBE-INF/classes/包名/文件名
- 如果资源文件在Web根目录下,则路径是:/文件名
- 如果资源文件在WEB-INF目录下:则路径是:/WEB-INF/文件名
获取资源文件路径的方法有两种:
-
getResourceAsStream(String path)
:获取的是相对路径 -
getRealPath(String path)
:获取的是绝对路径
示例:
假设有如下文件:
src文件夹下包com.zzy.web有一个a.txt
WEB-INF文件夹下有一个b.txt
WEB-INF文件夹下的lib文件夹有一个c.txt
WEB-INF根目录下有一个d.txt
ServletContext-path.png@WebServlet("/PathServlet") public class PathServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1. 获取a.txt InputStream aInput = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/zzy/web/a.txt"); System.out.println(aInput); String aPath = this.getServletContext().getRealPath("/WEB-INF/classes/com/zzy/web/a.txt"); System.out.println(aPath); System.out.println("-----------------"); // 2. 获取b.txt InputStream bInput = this.getServletContext().getResourceAsStream("/WEB-INF/b.txt"); System.out.println(bInput); String bPath = this.getServletContext().getRealPath("/WEB-INF/b.txt"); System.out.println(bPath); System.out.println("-----------------"); // 3. 获取c.txt InputStream cInput = this.getServletContext().getResourceAsStream("/WEB-INF/lib/c.txt"); System.out.println(cInput); String cPath = this.getServletContext().getRealPath("/WEB-INF/lib/c.txt"); System.out.println(cPath); System.out.println("-----------------"); // 4. 获取d.txt InputStream dInput = this.getServletContext().getResourceAsStream("/d.txt"); System.out.println(dInput); String dPath = this.getServletContext().getRealPath("/d.txt"); System.out.println(dPath); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
输出如下:
java.io.ByteArrayInputStream@623dd620 F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\WEB-INF\classes\com\zzy\web\a.txt ----------------- null F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\WEB-INF\b.txt ----------------- java.io.ByteArrayInputStream@76d00c1b F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\WEB-INF\lib\c.txt ----------------- java.io.ByteArrayInputStream@5315f6de F:\IDEATest\JavaWebTest\out\artifacts\BlogTest_war_exploded\d.txt
注意:
ServletContext.getResourceAsStream("/WEB-INF/b.txt"),实测找不到文件,返回了null,但用getRealPath()可以获取到绝对路径。所以在这个目录下的文件还是用getRealPath()去获取吧。
这个问题还不清楚是为啥,知道了再补上。
-