Servlet中的站内转发、重定向以及请求包含

来源:互联网 发布:淘宝助理 csv excel 编辑:程序博客网 时间:2024/06/05 11:07

知识点:
1、servlet中的两个输出流:字节流(response.getOutputStream()) 和字符流(response.getWriter())

  1. 用字节流输出时,中文要采用out.write(“中文”.getBytes())。
    对于字节流,用response.setCharacterEncoding(“utf-8”)设了也不行
  2. 用字符流输出时,无论中英文都是:out2.print();
    //用response.setCharacterEncoding(“utf-8”)只是设置传输编码,并没有告诉浏览器采用什么编码来解析,因此也可能乱码。应该用response.setContentType(“text/html;charset=utf-8”);//该句既可设传输又可告诉浏览器采用什么编码来解析。
  3. ※※※两种流不能共存(无论是GET或POST方式提交): 用了字节流就不能同时用字符,反之亦然!

2、转发时,两个servlet都输出信息的问题: 转发是通过request进行—-助理解是呼叫转移, 转发时,路径不要带项目名
1. 第一个servlet的输出信息只是保存到缓存中,会被第2个servlet清空。因此第1个servlet中的内容无法输出
1. 如果在第1个servlet中调用“out.flush();或out.close();”,那么第1个servlet中的信息会输出,而第2个不会输出。不但如此,第1个servlet中的转发都会出异常,因为:
刷缓存就是要Tomcat帮我们输出信息。而同一个请求,Tomcat只会输出一次,因此输出之后流就关闭了,无法再转发。
1. 该方式下,地址栏中始终显示的是第1个的访问地址

3、转发时(共享同一个request和response),两个servlet的访问顺序,传参:

1. 访问顺序: 第1个GET方式,第2个走的是doGet()。 第1个POST方式,第2个走的是doPost()。2. 在第1个servlet转发代码之后,不能再调用类似 转发或重定向的代码。否则会500异常,因为转发之后,不能再回到此处进行跳转到别的页面 3. 读取页面参数:由于是共享同一个request,请求页面的参数在两个servlet当中都可以读取出来。---请求页面中,GET方式的参数是在地址栏中通过"?name=Jack&age=22"上传,POST方式是通过<input>组件上传的。4 . 两个servlet之间传参:    在第1个中request.setAttribute(),在第2个中request.getAttribute();

4、重定向(两个不同的request和response),两个servlet的访问顺序,传参:

  1. 重定向是通过response实现的: response.sendRedirect() //重定向时的路径一定要带项目名称
  2. 第1个servlet中的内容会输出,但瞬间就会被第2个覆盖。因为浏览器接收到第1个的响应时,立刻会自动发起第2次请求,进而接收并显示第2次请求的响应结果。
  3. 在第1个servlet重定向代码之后,不能再调用类似 转发或重定向 的代码。否则会500异常,因为转发之后,不能再回到此处进行跳转到别的页面
  4. 访问顺序: 无论第1个是GET方式还是POST方式,第2个走的是doGet()。—-该方式下,地址栏中最终会显示成第2个的访问地址
  5. 读取页面参数: 由于是不同的request,请求页面的参数在第1个servlet当中能够读取出来,而x第2个servlet中不能读取出来。
  6. 两个servlet之间传参: “无法”通过 在第1个中request.setAttribute(),在第2个中request.getAttribute(); —-通过attribute的路中走不通的
    如果非要传参,可以通过:在第1个servlet当中给重定向地址添加“?name=Jack&age=25”实现—该方式下地址栏会显示参数信息,明文传输信息,因此敏感数据要加密。
    站外跳转 只能通过重定向来实现,而且地址必须以“http://”开头,否则会被识别成站内。

5、请求包含(共享同一个request和response ,类似函数调用中的传参)

  1. 通过request实现,与转发一样是通过RequestDispatcher,只是前者是rd.forward(req,resp),后者是rd.include(req,resp);
  2. 在第1个servlet中out.flush(),对两个servlet的输出都没有影响。但如果在第1个servlet中out.close(),则第1个之后的输出以及第2个servlet中的输出都无效(不会输出),注意,后面的rd.include()仍然有效即第2个servlet虽然不能输出但仍会执行,且没有异常报出!
  3. )由于该方式和转发一样是共享同一个request和response,因此有关页面参数读取和两个servlet之间的传参特性,同转发!
  4. 访问顺序(同转发): 第1个GET方式,第2个走的是doGet()。 第1个POST方式,第2个走的是doPost()。
  5. 一个小细节:被包含servlet中的所有输出信息(包括等标记内容)都会原样输出。因此要注意,两个servlet之间的输出内容不要出现标记嵌套冲突! ( 如:… )
  6. )页面内容输出顺序:
    servlet1..包含之前的输出…
    servlet2…..(被包含的servlet输出)
    servlet1..包含之后的输出…

知识点演示代码

知识点一演示:

public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {//      用于设置 进来的请求的编码:request.getParameter(paramString)        request.setCharacterEncoding("utf-8");//      用来设置 输出去的流的编码:网络传输都是字节流---        response.setCharacterEncoding("utf-8");//      告诉浏览器用什么编码读取服务器传过去的流        response.setContentType("text/html;charset=utf-8");        OutputStream out = response.getOutputStream();        out.write("你好,胡龙华1".getBytes("utf-8"));        out.write("你好,胡龙华2".getBytes());    }

这里写图片描述

//      用于设置 进来的请求的编码:request.getParameter(paramString)        request.setCharacterEncoding("utf-8");//      用来设置 输出去的流的编码:只对字符流有用---        response.setCharacterEncoding("utf-8");  《1》//      告诉浏览器用什么编码读取服务器传过去的流        response.setContentType("text/html;charset=utf-8");《2》        PrintWriter out = response.getWriter();        out.println("你好,夏天");

《1》 《2》两句同时写了才能保证页面不出现中文乱码,
这里写图片描述

        PrintWriter out1 = response.getWriter();        out1.println("你好,夏天");        OutputStream out2 = response.getOutputStream();        out2.write("你好,胡龙华".getBytes("utf-8"));

两个流同时存在时,出现异常!
这里写图片描述

知识点二演示:
演示一:从第一个Servlet向前端页面发送一个信息后,再转发到第二个Servlet
Servlet1

public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        out.println("GET方式---1---");        System.out.println("GET方式---1---");        request.getRequestDispatcher("ForwardServletTwo").forward(request, response);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        System.out.println("POST方式---1---");        out.println("POST方式---1---");        request.getRequestDispatcher("ForwardServletTwo").forward(request, response);    }

Servlet2

public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();        out.println("GET方式---2---");//      先输出文字信息,再转发到ForwardServletOne        System.out.println("GET方式---2---");    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        System.out.println("POST方式---2---");        out.println("POST方式---2---");    }

前端页面
这里写图片描述

后台系统输出结果
这里写图片描述

结果说明:Servlet1想前端页面发送的消息未发送成功,转发到Servlet2成功,Servlet2并成功像系统输出信息。

在Servlet1页面中强行加一句out.flush(); 刷缓存其他不变,

response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        out.println("GET方式---1---");        System.out.println("GET方式---1---");        out.flush();        request.getRequestDispatcher("ForwardServletTwo").forward(request, response);

前端页面输出了Servlet1发送的信息,转发到Servlet二失败
这里写图片描述
这里写图片描述

总结:服务器对于浏览器的一次request请求只做一次回应,当输出信息的时候,就代表回应了一次。就没办法再转发了。

转发时候:request、response是共享的!!! 所有的转发中用的是同一个request和response。

下面演示重定向。
Servlet1代码

public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        out.println("GET方式---1---");        System.out.println("GET方式---1---");        response.sendRedirect("ForwardServletTwo");//      request.getRequestDispatcher("ForwardServletTwo").forward(request, response);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        System.out.println("POST方式---1---");        out.println("POST方式---1---");        response.sendRedirect("ForwardServletTwo");//      request.getRequestDispatcher("ForwardServletTwo").forward(request, response);    }

Servlet2代码

public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();        out.println("GET方式---2---");//      先输出文字信息,再转发到ForwardServletOne        System.out.println("GET方式---2---");    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();//      先输出文字信息,再转发到ForwardServletOne        System.out.println("POST方式---2---");        out.println("POST方式---2---");    }

两次通过不同的方式提交
第一次Get方式提交:结果两次都是进入GET方式
这里写图片描述
第一次Get方式提交:结果第一次是进入POST方式,第二次是GET方式
这里写图片描述

总结:重定向是第二次是浏览器重新请求,提交方式无论前一次是GET还是POST,第二次都是GET方式。 并且request和resp都不是共享的。

请求包含—
servlet1..包含之前的输出…
servlet2…..(被包含的servlet输出)
servlet1..包含之后的输出…