• Servlet的学习之Response响应对象(3)


      本篇来说明响应对象HttpServletResponse对象的最后一点内容。

      首先来看响应对象控制浏览器定时刷新,在我的web应用【myservlet】中创建Servlet,在该Servlet中设置响应头,定时刷新的代码很简单:

    response.setHeader("refresh", "3 ");    //3秒刷新一次

    就可告知浏览器3秒刷新一次网页。当然“Refresh”响应头还是可以定时跳转到指定页面,如下代码:

    response.setHeader("refresh", "3;url='/myservlet/index.jsp'");

    将会在访问我这个Servlet的3秒后访问我的【myservlet】web应用下的index.jsp资源。

      之前说过,使用<meta>标签可以模拟响应头,同样在这里可以使用Servlet向客户端写数据时将<meta>标签写入响应数据实体,由浏览器解析后再来控制:

    1 String data = "银魂";
    2 response.setContentType("text/html;charset=UTF-8");
    3 response.getWriter().write("<meta http-equiv='refresh' content='3;url=/myservlet/index.jsp' >");
    4 response.getWriter().write(data);

      这里请注意:在向响应对象写入任何数据之前,请先设置好使用的编码表,如果在写入数据之后再设置编码表则无效,例如下面代码:

    1 String data = "银魂";
    2 response.getWriter().write(data);
    3 response.setContentType("text/html;charset=UTF-8");

    通过查看HttpWathch可以知道,编码表并没有设置成功:

      

    把设置编码表的代码放置在向响应对象写入数据也是不行的,如下:

    1 String data = "银魂";
    2 response.getWriter().write("<meta http-equiv='refresh' content='3;url=/myservlet/index.jsp' >");
    3 response.setContentType("text/html;charset=UTF-8");
    4 response.getWriter().write(data);

    这样也会设置编码表无效,造成中文乱码问题,所以在向响应对象写入任何数据之前请确保先将编码表设置好。

      请求重定向:之前在http协议中学习了响应码302和“Location”响应头可以设置请求重定向。

    一个简单的代码示例(web工程名为【myservlet】):

    1   response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);  //302状态码
    2   response.setHeader("location", "/myservlet/index.jsp");

    对于不太熟悉HTTP协议的编程人员来说,当然还有更快捷的方式:

    1 response.sendRedirect("/myservlet/index.jsp");

    验证:在浏览器中的地址栏中键入该Servlet的地址,浏览器则是会跳转至该web目录下的index.jsp,这个可以从浏览器地址栏上看出。

      关于请求重定向中的细节:

      一次请求重定向会向服务器发送两次请求。也就是说会产生两次response响应对象和request请求对象;同时浏览器的地址栏是会发生变化的,URL将跳转到重定向后的页面地址。这点和转发不同(在《Servlet的学习(五)》中说过)。

      最后再回到response响应对象的getOutputStream方法和getWriter方法,这两个方法在《Servlet的学习(七)》中已经详细介绍了解决中文乱码问题,那么现在我们还需要注意的是:getOutputStream方法和getWriter方法这两个方法相互排斥,不能同时使用。否则会出现如下问题:

      

    也许大家会瞧不起这个问题,认为不就是在一个Servlet中不要同时使用字节流和字符流嘛,注意下就好了。

      问题当然不会这么简单,比如在转发中使用不同的IO流还是会出现这种问题的:

      假设我的【myservlet】这个web工程中有两个Servlet:ServletResponse1和ServletResponse2。

    在ServletResponse1中的代码为:

    1     response.getWriter();
    2     RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/WEB-INF/classes/ServletResponse2");
    3     dispatcher.forward(request, response);

    在ServletResponse2中的代码为:

    1     response.getOutputStream();

    那么结果是直接部署出错:

      

    在ServletResponse1中将Response对象传递给ServletResponse2中,本身Response就已经调用了获取Writer对象的方法,因此不能再在ServletResponse2中获取OutputStream对象,所以在做转发时要特别注意获得IO流对象。

      而将Servlet调用getOutputStream()方法后再转发给JSP文件也是会出错的

    比如在ServletResponse1中代码为:

    1     OutputStream out = response.getOutputStream();
    2     RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/index.jsp");
    3     dispatcher.forward(request, response);

    而访问这个Servlet会看到:

      

    这是因为在Servlet向JSP中写入数据时默认使用了getWriter()方法获取字符流,然后向JSP中写入数据,这时如果我们在转发JSP之前的Servlet再使用getOutputStream必然会产生冲突。如果想向JSP中传入的必须是使用字节流才能传输的数据,请查验相关解决方案。

  • 相关阅读:
    IntelliJ IDEA 2017 反向代理工具新方法激活
    如何去掉idea里mybatis的.xml文件 sql 语句背景色
    eclipse、idea切换大小写的快捷键
    pageHelper没有分页效果的问题
    springboot使用thymeleaf 解析异常
    SpringBoot发送简单文本邮件
    IDEA中使用git详细步骤
    解决 git branch -a 无法全部显示远程的分支,只显示master分支
    git常用命令
    异常处理
  • 原文地址:https://www.cnblogs.com/fjdingsd/p/4854855.html
Copyright © 2020-2023  润新知