ServletResponse 悠悠 2023-10-04 12:53 8阅读 0赞 ##### 13.ServletResponse ##### ###### 13.1.介绍 ###### * 用途:用于设置响应消息 * 同样,ServletResponse是顶级父接口,因为我们常用Http协议,所以我们只介绍HttpServletReponse。 * ServletResponse接口 | 继承 HttpServletResponse接口 | 实现 org.apache.catalina.connector.ResponseFacade 类(tomcat) ###### 13.2.常用API ###### * public void setStatus(int sc) : 设置此响应的状态代码。 * public void setHeader(String name,String value) : 用给定的名称和值设置响应头 * public PrintWriter getWriter() : 返回可以向客户端发送字符文本的PrintWriter对象设置响应体,继承于ServletResponse。 * public ServletOutputStream getOutputStream() : 返回适合在响应中写入二进制数据的ServletOutputStream。servlet容器不编码二进制数据。 @WebServlet("/response1") public class ResponseServlet1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应状态码 response.setStatus(404); //设置响应头 response.setHeader("Content-Type", "text/html"); response.setHeader("Server", "Tomcat 8.5"); //设置响应体 response.getWriter().println("<h1 style='color:red'>File Not Found</h1>"); } } ###### 13.3.定时刷新 ###### * 使用refresh实现页面的定时刷新 @WebServlet("/refresh") public class RefreshServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //refresh用法一共有两种 //用法一:值只有一个数字,表示每隔多少秒刷新当前页面,实现页面时时刻刻刷新当前的时间 //转成YYYY-MM-dd HH:mm:ss String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); response.getWriter().println(time); //response.setHeader("refresh", "1"); //用法二:值里面有一个数字,并且还有一个url,表示的是经过多少秒之后跳转至url,然后结束 //response.setHeader("refresh", "3;url=" + request.getContextPath() + "/1.html"); response.setHeader("refresh", "3;url=http://www.cskaoyan.com"); } } ###### 13.4.重定向 ###### * 使用Location实现页面重定向,状态码为302或307 * refresh、重定向,浏览器默认使用get方式,而请求转发前后请求方法不变。 * Servlet源组件生成的响应结果不会被发送到客户端 * response.sendRedirect(String location) 方法一律返回状态码为302的响应结果。 * 如果源组件在进行重定向之前,已经提交了响应结果,会抛出IllegalStateException。为了避免异常,不应该在源组件中提交响应结果。 * //Cannot call sendRedirect() after the response has been committed * 在Servlet源组件重定向语句后面的代码也会执行。 * 源组件和目标组件不共享同一个ServletRequest对象。 * 对于sendRedirect(String location)方法的参数,如果以“/”开头,表示相对于当前服务器根路径的URL (不是当前应用的根目录)。以“http"//”开头,表示一个完整路径。 * `http://localhost/` * 目标组件不必是同一服务器上的同一个web应用的组件,它可以是任意一个有效网页。 @WebServlet("/redirect") public class RedirectServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //response.setStatus(302); //第一种写法 //response.setHeader("Location", request.getContextPath() + "/1.html"); //第二种写法 //response.setHeader("Location", "http://www.cskaoyan.com"); //我们上面是根据重定向的定义,自己去写了对应的实现 //服务器给我们提供了一个更为简便的API //第三种写法 response.sendRedirect(request.getContextPath() + "/1.html"); } } ###### 13.5.几种页面跳转方式的比较 ###### * 转发、刷新、重定向都可以用在servlet处理完毕之后,跳转至一个页面。 * 不同点: 1. 转发是request介导的,刷新、重定向是response介导的 2. 转发的两个组件之间可以共享request域,刷新、重定向是不可以的 3. 转发是一次请求,刷新、重定向会发送多次请求 4. 转发、刷新的状态码是200,重定向状态码是302、307 5. 刷新可以设置跳转的时间,转发、重定向做不到 6. 转发只可以在当前应用内部跳转,刷新、重定向不受限制,可以跳转到当前应用之外的任意网络资源 ###### 13.6.乱码的解决 ###### //响应体设置一个编码格式,同时将编码格式告诉给浏览器,两边统一即可 //1.可以通过响应头告知 @WebServlet("/response1") public class ResponseServlet1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应状态码 response.setStatus(404); //设置响应头 //response.setHeader("Content-Type", "text/html"); response.setHeader("Server", "Tomcat 8.5"); //设置响应体 //response.getWriter().println(new Date()); //response.setCharacterEncoding("gbk"); //因为该行代码由两层含义:1.设置响应体编码格式2.发送一个含有编码格式的响应头 response.setHeader("Content-Type", "text/html;charset=utf-8"); response.getWriter().println("<h1 style='color:red'>File Not Found</h1>"); response.getWriter().println("<h1 style='color:red'>文件未找到</h1>"); } } //2.发送一个含有编码格式的响应头 @WebServlet("/response1") public class ResponseServlet1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应状态码 response.setStatus(404); //设置响应头 //response.setHeader("Content-Type", "text/html"); response.setHeader("Server", "Tomcat 8.5"); //设置响应体 //response.getWriter().println(new Date()); //response.setCharacterEncoding("gbk"); //因为该行代码由两层含义:1.设置响应体编码格式2.发送一个含有编码格式的响应头 //response.setHeader("Content-Type", "text/html;charset=utf-8"); response.setContentType("text/html;charset=utf-8"); response.getWriter().println("<h1 style='color:red'>File Not Found</h1>"); response.getWriter().println("<h1 style='color:red'>文件未找到</h1>"); } } //3.通过响应体告知 //3.1.设置编码格式 3.2.告知对方我使用的编码格式 @WebServlet("/response2") public class ResponseServlet2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应状态码 response.setStatus(404); //设置响应头 response.setHeader("Server", "Tomcat 8.5"); //设置响应体 response.setCharacterEncoding("utf-8"); response.getWriter().println("<!DOCTYPE html>\n" + "<html lang=\"en\">\n" + "<head>\n" + " <meta charset=\"UTF-8\">\n" + " <title>Title</title>\n" + "</head>\n" + "<body>"); response.getWriter().println("<h1 style='color:red'>File Not Found</h1>"); response.getWriter().println("<h1 style='color:red'>文件未找到</h1>"); response.getWriter().println("\n" + "</body>\n" + "</html>"); } } ###### 13.7.输出字节数据 ###### * 利用字节数据其实也是可以输出字符的。但是字节数据最常见的使用场景还是去处理文件,去响应文件资源、二进制文件资源 @WebServlet("/stream") public class OutputStreamServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //可以设置,也可以不设置,如果不设置的话浏览器会自动帮我们设置好。 response.setContentType("image/jpg"); ServletOutputStream outputStream = response.getOutputStream(); //可以把这个当作FileOutputStram来看待,但是呢,行为应该是相同的,输出的目的地不同 //需要你将本地部署根目录下面的1.jpg 输出到客户端 //硬盘上面的文件,读取到内存中 FileInputStream来处理这一个过程 //部署根目录下面1.jpg的输入流拿到 //先拿到文件的绝对路径 String realPath = getServletContext().getRealPath("1.jpg"); FileInputStream fileInputStream = new FileInputStream(realPath); //输出到response的响应体即可 int length = 0; byte[] bytes = new byte[1024]; while ((length = fileInputStream.read(bytes)) != -1){ outputStream.write(bytes, 0, length); } fileInputStream.close(); //输出流可以关闭,也可以不关闭,如果不关闭,那么tomcat会在响应的时候关闭他们 outputStream.flush(); outputStream.close(); } } ###### 13.8.下载 ###### * 下载网页中的资源,与显示资源的代码基本一致,只需要添加一个响应头就可以了 @WebServlet("/download") public class DownloadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应头 response.setHeader("Content-Disposition","attachment;filename=1.jpg"); response.setContentType("image/jpg"); ServletOutputStream outputStream = response.getOutputStream(); //可以把这个当作FileOutputStram来看待,但是行为应该是相同的,输出的目的地不同 //需要你将本地部署根目录下面的1.jpg 输出到客户端 //硬盘上面的文件,读取到内存种 FileInputStream来处理这一个过程 //部署根目录下面1.jpg的输入流拿到 //先拿到文件的绝对路径 String realPath = getServletContext().getRealPath("1.jpg"); FileInputStream fileInputStream = new FileInputStream(realPath); //输出到response的响应体即可 int length = 0; byte[] bytes = new byte[1024]; while ((length = fileInputStream.read(bytes)) != -1){ outputStream.write(bytes, 0, length); } fileInputStream.close(); //输出流可以关闭,也可以不关闭,如果不关闭,那么tomcat会在响应的时候关闭 outputStream.flush(); outputStream.close(); } } ###### 13.9.同一个Servlet响应多个请求 ###### * 在开发中,一个网站通常会有很多子网页,同时带来很多请求,我们不能一个子网页写一个实现类,那样可能会产生成千上万个Servlet类 * 因此,我们应该用一个Servlet处理多个网页请求,尤其是类似显示资源和下载资源的具有高相似度的请求或功能,通常有如下几种方法 1. 设置不同的请求url后缀,在Servlet实现类上进行字符串匹配,并做出相应处理 2. 在注解中添加多个urlpattern,添加格式为@webServlet(\{"/download", “/stream”\}) 3. 在web.xml中配置多个urlpattern ###### 13.10.Response的一些细节 ###### * getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。 * getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 会抛异常。 * Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。 * Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
相关 ServletResponse 13.ServletResponse 13.1.介绍 用途:用于设置响应消息 同样,ServletResponse是顶级父接口,因为我们常用Http协议 悠悠/ 2023年10月04日 12:53/ 0 赞/ 9 阅读
相关 Servlet技术浅析(四)之-----ServletResponse接口和HttpServletResponse接口 ServletResponse接口 简述: 在Servlet接口的service(ServletReuqest req , ServletResponse res) 系统管理员/ 2022年07月13日 09:44/ 0 赞/ 191 阅读
相关 Java 重写ServletResponse中的内容 Java 重写ServletResponse中的内容,Java 修改response中的内容 1. 继承HttpServletResponseWrapper 重新覆 Myth丶恋晨/ 2022年06月04日 05:39/ 0 赞/ 87 阅读
相关 javaWeb_servletResponse servletResponse 封装了响应信息。 l getWriter() 返回PrintWriter对象,调用其print方法可以把print中的参数直接打印到客户的浏 梦里梦外;/ 2022年05月25日 03:43/ 0 赞/ 109 阅读
相关 ServletResponse的getOutputStream和getWriter 一直不明白,为什么reponse得到的OutputStream和PrintWriter对象可以向浏览器(理解为一个文件)输出内容,而不是其他的文件。 可以先理解为:Servl ゞ 浴缸里的玫瑰/ 2022年05月12日 07:50/ 0 赞/ 210 阅读
相关 深入理解ServletRequest与ServletResponse 请求和响应是Web交互最基本的模式,在Servlet中,分别用HttpServletRequest与HttpServletResponse来表示Http请求和响应。这两个类均来 逃离我推掉我的手/ 2021年09月28日 13:20/ 0 赞/ 208 阅读
还没有评论,来说两句吧...