javaEE:day9-request和response的转发、重定向、请求包含小细节
2016-07-25 13:31
525 查看
字节输出流和字符输出流的共存问题
结论:不能共存(跟get或post方式没关系)。即在同一个servlet中字符流与字节流不能共存,两种方法单独使用都是可以的
另外:如果要用字节流输出中文,用write(byte[])方法,因为它的out.print(“晚上好!”);//500错误。内部用iso8859-1读取,已经写死了,因此中文不行
转发时,两个servlet都输出信息的问题
转发用
RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet"); rd.forward(request, response);
Tomcat对于同response,只输出一次(把缓存中的内容刷出去)。刷了(close也一样),流就关闭了,下面的转发就无法进行了,因为此时response已经提交了(整个转发链只会响应一次,即提交了) .
详细知识点见转发的第三点。
重定向 传参 访问顺序(doget还是dopost)
重定向用response.sendRedirect("/servletDemo4/servlet/Redir2Servlet");
参数带项目名,因为发给浏览器要在tomcat目录下。
在重定向第一个servlet输出会被第二个servlet输出覆盖,其实是输出了,但是跳转的时间太快,人眼不可见。
无论第一个servlet是doget还是dopost,第二个servlet都是doget。因为转发过去直接在地址栏输入路径,不会在生成表单设置post
重定向,第二个servlet和第一个servlet的request和response都不是同一个对象了,因此无法通过request.setAttribute("age", 22);
和request.getAttribute("age");
传参,并且,第二个servlet也无法通过request.getParameter("name");
从页面获取参数。
重定向情况下,如要传参,则采用地址栏的url的?后面加key=value,多个用&连接。
采用地址栏传参的方式,在浏览器地址栏能看到参数值,因此要注意隐私问题—–加密
转发只能在站内进行(路径默认在项目内)而重定向可以在站外进行(如果是在站外,路径要带”http://”开头,站内要带项目名)如果非要在项目之间(站外)进行跳转,则必须采用重定向。
转发 传参 访问顺序(doget还是dopost)
第一个servlet用dopost第二个servlet也用dopost。第一个servlet用doget第二个servlet也用doget。
第二个servlet中的response会把缓存清空,即将上个servlet的内容清空,然后将此时的servlet的内容写入缓存,刷出去,显示到页面。
tomcat对于同一个servlet只输出一次(把缓存中的内容刷出去)如果第一个servlet刷了,流就关闭了。只会对response操作会出异常,因为此时的response已经提交,不能再转发了。
为解决上面的问题,我们用传参在第一个servlet中用request.setAttribute("age", 22);
第二个servlet中用request.getAttribute("age");
通过request容器来进行读写,因为转发其实是共享同一个request和同一个response对象。在转发过程中,servlet可以对request进行多次读取参数。
请求包含 传参 访问顺序(doget还是dopost)
请求包含用
RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet"); rd.include(request, response);
请求包含的机制可以理解成函数调用,相当于把第二个servlet 中的代码拷到这里来执行。
第一个servlet用doget第二个servlet用doget;第一个servlet用dopost第二个servlet也用dopost。
对于请求包含,第二个servlet在执行完之后还会回到第一个servlet的rd.include(request, response);
之后。
请求包含与转发传参一样,也是共享同一个request和同一个response对象。不同的是,在请求包含中,如在第一个servlet关流,后面不会出异常,只是后面的不会执行了。如在第一个servlet刷即用out.flush();流不会关闭。请求包含我个人可以理解成是同一个servlet,只是包含的servlet是一个功能模块而已,所以在同一个servlet中,刷(flush)没有影响,实质还是在同一个servlet中。
本文完整代码如下:
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> </head> <body> <!-- 知识点: 1字节输出流和字符输出流的共存问题 结论:在一个servlet中字符流与字节流不能共存,两种方法单独使用都是可以的 2转发时,两个servlet都输出信息的问题 正常的后面一个会覆盖前面,具体的可以看4.2和4.3 3重定向 传参 访问顺序(doGet还是doPost ) 1>方法是:response.sendRedirect() 因为转发给浏览器,要在tomcat目录下参数要带项目名 2>在重定向第一个servlet输出后会被第二个servlet输出覆盖,其实是输出了,但是跳转时间太快,人眼不可见 3>无论第一个servlet是dopost还是doget,第二个servlet都是doget,因为转发过去直接在地址栏输入路径。不会再生成表单设置post 4>重定向第二个servlet和第一个servlet的request和response不是同一个对象,无法用过serAttribute和getAttribute传参,第二个servlet无法通过getParamer从页面获取参数 5>如要传参,采用地址栏的url的?后面加key=value 形式进行传参,多个用&连接。采用地址栏传参方式 在浏览器地址栏可以看到所传的参数,因此要注意隐私问题----加密 6>转发只能在站内进行(路径默认在项目内)而重定向可以在站外进行(如果在站外,路径要带"http://"开头,站内要带项目名) 如果非要在项目之间(站外)进行跳转,不虚采用重定向 4转发 传参 访问顺序(doGet还是doPost ) 1>转发:第一个servlet用doget第二个就是用doget;第一个用dopost第二个也用dopost; 2>第二个servlet中的response会先把缓存清空,然后将此时的servlet的内容写到缓存,刷出去显示到页面 3>tomcat对同一个response只会输出一次,如果第一个servlet刷了即out.flush() 那么流在此就关闭了,后面转发,操作response都会出异常。因为此时的response已经提交,不能再转发了 4>为了解决上面问题,我们用传参来实现:在第一个servlet中setAttribute第二个servlet中getAttribute 转发共享同一个request和同一个response对象,在servlet中可以多次读取参数 5请求包含 传参 访问顺序(doGet还是doPost ) 1> 两个servlet的输出都有效 2> request.getRequestDispatcher("").include(request,response); 因为是请求包含,还是在项目内,getRequestDispatcher("")的参数可以不带项目名 这个include(request,response)可以理解成函数调用,相当于将第二个servlet的代码拷到这里来运行。 3>第一个servlet用doget第二个servlet用doget 第一个servlet用dopost第二个servlet用dopost 4>对于请求包含 第二个servlet在执行完以后还会回到第一个servlet的include(request,response)后面。 5>传参与转发的传参一样,采用setAttribute,getAttribute 。 dopost方式第二个servlet也能从页面拿到值。 不同的是,请求包含在第一个servlet关流,后面不会出异常,在中途调用out.flush() 流不会关闭 --> <h2>1字节输出流和字符输出流的共存问题</h2> <a href="servlet/OutServlet">字节输出流和字符输出流的共存问题</a> <form action="servlet/OutServlet" method="post"> 姓名:<input type="text" name="name"/><br/> <input type="submit" value="提交"/> </form> <h2>2转发时,两个servlet都输出信息的问题</h2> <a href="servlet/OneServlet">转发时,两个servlet都输出信息的问题</a> <form action="servlet/OneServlet" method="post"> 姓名:<input type="text" name="name"/><br/> <input type="submit" value="提交"/> </form> <h2>3重定向 传参 访问顺序(doGet还是doPost )</h2> <a href="servlet/Redir1Servlet">重定向 传参 访问顺序(doGet还是doPost )</a> <form action="servlet/Redir1Servlet" method="post"> 姓名:<input type="text" name="name"/><br/> <input type="submit" value="提交"/> </form> <h2>5请求包含 传参 访问顺序(doGet还是doPost )</h2> <a href="servlet/Include1Servlet">请求包含 传参 访问顺序(doGet还是doPost )</a> <form action="servlet/Include1Servlet" method="post"> 姓名:<input type="text" name="name"/><br/> <input type="submit" value="提交"/> </form> </body> </html>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <servlet> <servlet-name>OutServlet</servlet-name> <servlet-class>cn.hncu.servlet.OutServlet</servlet-class> </servlet> <servlet> <servlet-name>OneServlet</servlet-name> <servlet-class>cn.hncu.servlet.OneServlet</servlet-class> </servlet> <servlet> <servlet-name>TwoServlet</servlet-name> <servlet-class>cn.hncu.servlet.TwoServlet</servlet-class> </servlet> <servlet> <servlet-name>Redir1Servlet</servlet-name> <servlet-class>cn.hncu.servlet.Redir1Servlet</servlet-class> </servlet> <servlet> <servlet-name>Redir2Servlet</servlet-name> <servlet-class>cn.hncu.servlet.Redir2Servlet</servlet-class> </servlet> <servlet> <servlet-name>Include1Servlet</servlet-name> <servlet-class>cn.hncu.servlet.Include1Servlet</servlet-class> </servlet> <servlet> <servlet-name>Include2Servlet</servlet-name> <servlet-class>cn.hncu.servlet.Include2Servlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>OutServlet</servlet-name> <url-pattern>/servlet/OutServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>OneServlet</servlet-name> <url-pattern>/servlet/OneServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TwoServlet</servlet-name> <url-pattern>/servlet/TwoServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Redir1Servlet</servlet-name> <url-pattern>/servlet/Redir1Servlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Redir2Servlet</servlet-name> <url-pattern>/servlet/Redir2Servlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Include1Servlet</servlet-name> <url-pattern>/servlet/Include1Servlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Include2Servlet</servlet-name> <url-pattern>/servlet/Include2Servlet</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
OutServlet
package cn.hncu.servlet; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class OutServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //字节流 // ServletOutputStream out = response.getOutputStream(); // out.println("你好!!!现在是晚上了"); //上面这种写法不行,因为不是iso8859-1格式不认识,out.println这种方法写死了 只能用iso8859-1 //我们用下面的方法可以解决中文 // out.write("你好!!!现在是晚上".getBytes("utf-8")); //字符流 PrintWriter out = response.getWriter(); out.print("你好,这是晚上写的代码"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //字节流 // ServletOutputStream out = response.getOutputStream(); // out.println("你好!!!现在是晚上了"); //上面这种写法不行,因为不是iso8859-1格式不认识,out.println这种方法写死了 只能用iso8859-1 //我们用下面的方法可以解决中文 // out.write("你好!!!现在是晚上".getBytes("utf-8")); //字符流 PrintWriter out = response.getWriter(); out.print("你好,这是晚上写的代码"); } }
OneServlet
package cn.hncu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class OneServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("1111get..."); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("现在是凌晨两点18,好累啊");//下面如果不执行flush或close,那么该句不会输出,因为到下一个servlet会把缓存清空 //out.flush();//Tomcat对于同response,只输出一次(把缓存中的内容刷出去)。刷了(close也一样),流就关闭了,下面的转发就无法进行了,因为此时response已经提交了(整个转发链只会响应一次,即提交了) //传参 request.setAttribute("name", "肖答是个傻吊"); RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet"); rd.forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); System.out.println("111post..."); out.print("现在是凌晨两点18,好累啊");//下面如果不执行flush或close,那么该句不会输出,因为到下一个servlet会把缓存清空 //out.flush();//Tomcat对于同response,只输出一次(把缓存中的内容刷出去)。刷了(close也一样),流就关闭了,下面的转发就无法进行了,因为此时response已经提交了(整个转发链只会响应一次,即提交了) //传参 request.setAttribute("name", "肖答是个傻吊"); RequestDispatcher rd = request.getRequestDispatcher("/servlet/TwoServlet"); rd.forward(request, response); } }
TwoServlet
package cn.hncu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TwoServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("2222get..."); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("现在是凌晨2.20");//第二个servlet会先把缓存中之前的内容清空,然后再把当前servlet的输出内容写入缓存,刷出去。 String nameS1 = (String) request.getAttribute("name"); String name = request.getParameter("name"); out.print("<br/>nameServlet1:"+nameS1); out.print("<br/>nameIndex:"+name); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("222post..."); request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("现在是凌晨2.20"); String nameS1 = (String) request.getAttribute("name"); String name = request.getParameter("name"); out.print("<br/>nameServlet1:"+nameS1); out.print("<br/>nameIndex:"+name); } }
Redir1Servlet
package cn.hncu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Redir1Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("1111111servletGet1111"); response.sendRedirect("/servletDemo4_jun/servlet/Redir2Servlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.print("1111111servlePostt1111"); String name = request.getParameter("name"); System.out.println("11111post-param:"+name); request.setAttribute("name", "陈威"); // response.sendRedirect("/servletDemo4_jun/servlet/Redir2Servlet"); response.sendRedirect("/servletDemo4_jun/servlet/Redir2Servlet?name=cv"); } }
Redir2Servlet
package cn.hncu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Redir2Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("2222222222Redir2 get......"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("utf-8"); String name = request.getParameter("name"); String nameRq = (String) request.getAttribute("name"); out.print("name:"+name); out.println("<br/>redir1Name:"+nameRq); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); System.out.println("2222222222Redir2 Post......"); } }
Include1Servlet
package cn.hncu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Include1Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("现在是2.59,我好困"); request.setAttribute("getName", "张三"); RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet"); rd.include(request, response); out.println("<br/>睡你妈逼起来嗨"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("现在是3.01,我好困"); request.setAttribute("postName", "李四"); RequestDispatcher rd = request.getRequestDispatcher("/servlet/Include2Servlet"); rd.include(request, response); //可以理解为函数调用。调完之后还要返回这里; out.println("<br/>睡你妈逼起来嗨"); } }
Include2Servlet
package cn.hncu.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Include2Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("这是include2 get里的内容"); String nameS1 = (String) request.getAttribute("getName"); out.println("Servlet1*---Name:"+nameS1); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); request.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); out.println("这是include2 post里的内容"); String name = request.getParameter("name"); out.print("<br/>request-paramer:"+name); String nameS1 = (String) request.getAttribute("postName"); out.println("Servlet1*---Name:"+nameS1); } }
相关文章推荐
- Win10 上 安装Arduino 驱动 和 Arduino IDE 1.6.9
- Win10 上 安装Arduino 驱动 和 Arduino IDE 1.6.9
- Longest Increasing Subsequence Arrays (组合计数)
- unique和unique_copy
- 用IntelliJ自动检查并生成serialVersionUID
- PHP $_SERVER['PHP_SELF']、$_SERVER['SCRIPT_NAME'] 与 $_SERVER['REQUEST_URI'] 之间的区别
- Handler消息传递机制(一)理解到底为什么?
- UE4 UnrealEngine4 中 实现多通道技术
- IDE的一键Build背后隐藏了什么
- Fuison 360 API: 判断一个点是否在某曲面上
- [leetcode] 374. Guess Number Higher or Lower
- iOS--UITextField的简单使用
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- UIScrollViewDelegate Protocol Reference
- 64.Which two statements are true about setting the FAST_START_MTTR_TARGET initialization parameter t
- Sustainability through Energy Load Shaping for Buildings using R
- longestIncreasingSequence最长上升子序列问题
- 63.Examine the values for the following initialization parameters: FAST_START_MTTR_TARGET = 0 LOG_CH
- UIScrollView Class Reference