天天看点

请求包含,转发,重定向的区别

当浏览器请求一个jsp,servlet时,会调用相应的service方法

注意:在同一个servlet中无法   字节流和字符流共存,服务器对于请求只响应一次给浏览器的信息,只会选择一个流一次性输出信息,获取不同流会出异常

            在输出中文时,字节流需要write(“”.getBytes("编码")),print()只能输出ISO8859-1支持的字符,其他字符出异常

                                        字符流,只要设置了协议头即可输出中文

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		//1用字节输出流向客户端写信息
		ServletOutputStream out = response.getOutputStream();//获取字节输出流
		out.print("Hello");//OK
		//out.print("晚上好!");//500错误。内部用iso8859-1读取,已经写死了,因此中文不行
		out.write("晚上好!".getBytes("utf-8"));//如果要用字节流输出中文,用write(byte[])方法
				
		
		//2用字符输出流向客户端写信息
		PrintWriter out2 = response.getWriter();
		out2.print("Hello, 晚上好!");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("post........");
		response.setContentType("text/html;charset=utf-8");
		//1用字节输出流向客户端写信息
		ServletOutputStream out = response.getOutputStream();//获取字节输出流
		out.print("Hello");//OK
		//out.print("晚上好!");//500错误。内部用iso8859-1读取,已经写死了,因此中文不行
		out.write("晚上好!".getBytes("utf-8"));//如果要用字节流输出中文,用write(byte[])方法
				
		
		//2用字符输出流向客户端写信息
		PrintWriter out2 = response.getWriter();
		out2.print("Hello, 晚上好!");
	}
           

字节输出流和字符输出流的共存问题---不能共存(跟get或post方式没关系)。即:在同一个servlet响应中,不能同时采两种输出流。

一:站外请求访问

        只能进行重定向的方式,以get方式访问:

        1)无论第一个是doGet还是doPost,第二个走的都是doGet

        2)传参:第二个servlet中的request和第一个是完全不同的对象,因此无法通过:request.setAttribute()和request.getAttribute() 实现传参。

        3)第二个servlet中是无法通过request.getParameter()的方式获取页面提交的参数数据

        4)重定向方式下,如果要进行传参,可采用:在地址栏的url后添加类似如下的格式传参:?name=Jack&age=23

                      注意,采用地址栏url传参的方式,在浏览器地址栏是能够看到的,因此要注意隐私(安全)问题---如果有隐私参数,那么要加密!!!

        5)转发只能在站内进行(路径默认在项目内,即路径不用带项目名),重定向可以在站外进行(如果是站外路径要带“http://”开头,站内路径要带项目名)。如果非要项目之间(站

         外) 进行跳转,那么必须要选择重定向。

throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("111111111111");//无效的输出
		
		response.sendRedirect("/servletDemo4/servlet/Redir2Servlet");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("111111111111");//无效的输出
		
		String name = request.getParameter("name");
		System.out.println("111para-name:"+name);
		//request.setAttribute("age", 22);//无效的属性设置
		//response.sendRedirect("/servletDemo4/servlet/Redir2Servlet");
		response.sendRedirect("/servletDemo4/servlet/Redir2Servlet?name=Jack&age=23");//只能以地址栏传输
	}
           

二:站内请求

           除了可以重定向外,还有转发及包含

       一:请求转发:

              转发:传参,访问顺序(doGet还是doPost) ---转发是共享同一个request和同一个response对象的

            1)第一个是doGet,第二个走的也是doGet

            2)第一个是doPost,第二个走的也是doPost

            3)传参:可以通过request.setAttribute()设置,通过request.getAttribute()获取 ---doGet或doPost都一样

public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("晚上好....");//下面如果不执行flush或close,那么该句不会输出,因为到下一个servlet会把缓存清空
		//out.flush();//Tomcat对于同response,只输出一次(把缓存中的内容刷出去)。刷了(close也一样),流就关闭了,下面的转发就无法进行了,因为此时response已经提交了(整个转发链只会响应一次,即提交了)
		
		//传参--设置属性(只要key不同,随便存几个)----放入request对象
		request.setAttribute("name", "Jack-Onservlet");
		
		String name2 = (String) request.getParameter("name");
		System.out.println("1111para-name"+name2);
		
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet");
		rd.forward(request, response);
	}
           

      二:请求包含

         请求包含:传参,访问顺序(doGet还是doPost)

         1)两个servlet的输出都有效!---中途调用flush,流不会关闭,后续的输出都会执行。如果在第一个servlet中执行了out.close(),那么后续的输出(无论是第一还是第二个  

           servlet)都不会执行,但程序不会出异常!!!!

         2)第一个是doGet,第二个走的也是doGet

         3)第一个是doPost,第二个走的也是doPost

         4)对于请求包含,第二个servlet在执行完之后,还会回到第一个servlet的rd.include()这行代码之后。

         5)传参方面,和转发是完全一样的,因为都是共享同一个request和同一个response.

         6)页面输出时,注意html标签不要输出冲突,如:在第一个servlet中输出了“<html><body>”和“</body></html>”,同时在第二个servlet中也输出这些标记。这样会出现html

             标记嵌套冲突!!

         ※重定向和转发:跳转之后不会回到原来的那个servlet中。

         而“请求转发”在跳转之后会回到原来servlet的“rd.include()”这句代码之后继续执行。

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.print("<html><body>");
		out.println("Include1111111..doGet...");
		
		//传参:和转发一样
		request.setAttribute("age", 25);
		
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
		rd.include(request, response);//它的机制可理解成函数调用。相当于把第二个servlet的doGet()方法中的代码拷到这里来运行。
		out.println("<br/>Include1111111..doGet...请求包含之后");
		
		out.print("</body></html>");
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		out.println("Include1111111..doPost...");
		
		//传参:和转发一样
		request.setAttribute("age", 25);
		out.flush();
		RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet");
		rd.include(request, response);
		out.println("<br/>Include1111111..doPost...请求包含之后");
	}