Web---字节输出流和字符输出流的共存问题、转发、重定向、请求包含知识点讲解(2)

简介: Web---字节输出流和字符输出流的共存问题、转发、重定向、请求包含知识点讲解

3、重定向:传参,访问顺序(doGet还是doPost)

index.jsp:

<a href="servlet/RedirOneServlet">重定向时,两个servlet都输出信息的问题、传参问题、访问顺序问题</a><br /> 
    <form action="servlet/RedirOneServlet" method="post">
        <input type="text" name="name" /><br /> 
        <input type="submit"value="提交" />
    </form>


web.xml:

<servlet>
    <servlet-name>RedirOneServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.RedirOneServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>RedirTwoServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.RedirTwoServlet</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>RedirOneServlet</servlet-name>
    <url-pattern>/servlet/RedirOneServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>RedirTwoServlet</servlet-name>
    <url-pattern>/servlet/RedirTwoServlet</url-pattern>
  </servlet-mapping>


RedirOneServlet.java:

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 RedirOneServlet 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("11111111111");//这是一个无效的输出,我们看不到!!
        response.sendRedirect("/myServletDemo4/servlet/RedirTwoServlet");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("11111111111");//这是一个无效的输出,我们看不到!!
        //out.flush();
        //如果刷了,后面就不能故去了。
        String name = request.getParameter("name");
        System.out.println("11111para-name:"+name);//这个也只有这里能接收到,如果想要传过去,得通过 地址栏+?+name= 的方式,如最后一行
        request.setAttribute("age", 23);//这一句是没用的,对方收不到!
        //response.sendRedirect("/myServletDemo4/servlet/RedirTwoServlet");
        response.sendRedirect("/myServletDemo4/servlet/RedirTwoServlet?name="+name+"&age=23");
    }
}

RedirTwoServlet.java:

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 RedirTwoServlet 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("doget........22222222<br/>");
        String name = request.getParameter("name");
        out.print("2222para-name:"+name);
        String age = request.getParameter("age");
        out.print("<br/>2222para-age:"+age);
        //得到地址栏?号后的属性值
        Integer age2 = (Integer) request.getAttribute("age");
        out.print("<br>attr-age:"+age2);//null. web.xml 中没有设置
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("doget........22222222<br/>");
    }
}

RedirTwoServlet.java:

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 RedirTwoServlet 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("doget........22222222<br/>");
        String name = request.getParameter("name");
        out.print("2222para-name:"+name);
        String age = request.getParameter("age");
        out.print("<br/>2222para-age:"+age);
        //得到地址栏?号后的属性值
        Integer age2 = (Integer) request.getAttribute("age");
        out.print("<br>attr-age:"+age2);//null. web.xml 中没有设置
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("doget........22222222<br/>");
    }
}

小总结:


两个servlet都输出信息的问题,这里和转发的情况其实可以理解是相同的,你第一个servlet如果out调用flush(),一样的,不会再重定向到后面的第二个servlet中去了。


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

(可以理解成:通过地址栏访问的)

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


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


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


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

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

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

index.jsp:

<a href="servlet/IncludeOneServlet">请求包含时,两个servlet都输出信息的问题、传参问题、访问顺序问题</a><br /> 
    <form action="servlet/IncludeOneServlet" method="post">
        <input type="text" name="name" /><br /> 
        <input type="submit"value="提交" />
    </form>

web.xml:

 <servlet>
    <servlet-name>IncludeOneServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.IncludeOneServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>IncludeTwoServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.IncludeTwoServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>IncludeOneServlet</servlet-name>
    <url-pattern>/servlet/IncludeOneServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>IncludeTwoServlet</servlet-name>
    <url-pattern>/servlet/IncludeTwoServlet</url-pattern>
  </servlet-mapping>    

IncludeOneServlet.java:

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 IncludeOneServlet 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("<html><body>");
        out.print("Include111111..doGet...");
        //传参,和转发时一样的!
        request.setAttribute("age", 25);
        RequestDispatcher rd = request.getRequestDispatcher("/servlet/IncludeTwoServlet");
        rd.include(request, response);
        //它的机制可理解成函数调用。相当于把第二个servlet的doGet()方法中的代码拷到这里来运行。
        //后面的还可以继续运行!!!
        out.print("<br/>Include11111...daGet...请求包含之后!");
        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.print("<html><body>");
        out.print("Include111111..doPost...");
        //传参,和转发时一样的!
        request.setAttribute("age", 25);
        RequestDispatcher rd = request.getRequestDispatcher("/servlet/IncludeTwoServlet");
        rd.include(request, response);
        //它的机制可理解成函数调用。相当于把第二个servlet的doPost()方法中的代码拷到这里来运行。
        //后面的还可以继续运行!!!
        out.print("<br/>Include11111...doPost...请求包含之后!");
        out.print("</body></html>");
    }
}

IncludeTwoServlet.java

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 IncludeTwoServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //因为上一个servlet已经设过,这里可以不设
        PrintWriter out = response.getWriter();
        //out.print("<html><body>");
        out.print("<br/>Include222222中文...doGet");
        //接参
        Integer age = (Integer) request.getAttribute("age");
        out.print("<br/>Include222222...doGet...:"+age);
        //下面这两句会导致无穷递归
        //RequestDispatcher rd = request.getRequestDispatcher("/servlet/IncludeOneServlet");
        //rd.include(request, response);
        //out.print("</body></html>");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //因为上一个servlet已经设过,这里可以不设
        PrintWriter out = response.getWriter();
        //
        out.print("<br/>Include222222中文...doPost");
        //接参
        Integer age = (Integer) request.getAttribute("age");
        out.print("<br/>Include222222...doPost...:"+age);
    }
}

小总结:


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()”这句代码之后继续执行。


演示:

image.png

可以看到,客户端只请求了一次!!!转发是请求两次的。

如果2个服务器都向客户端输出了<html><body> </body></html>

会出现:

image.png


目录
相关文章
|
5月前
|
开发框架 缓存 .NET
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
并发请求太多,服务器崩溃了?试试使用 ASP.NET Core Web API 操作筛选器对请求进行限流
244 0
|
4月前
|
SQL 存储 安全
Web安全-CSRF跨站请求伪造
Web安全-CSRF跨站请求伪造
112 4
|
3月前
|
监控 安全 Apache
构建安全的URL重定向策略:确保从Web到App平滑过渡的最佳实践
【10月更文挑战第2天】URL重定向是Web开发中常见的操作,它允许服务器根据请求的URL将用户重定向到另一个URL。然而,如果重定向过程没有得到妥善处理,可能会导致安全漏洞,如开放重定向攻击。因此,确保重定向过程的安全性至关重要。
161 0
|
5月前
|
Web App开发 安全 JavaScript
【Azure 应用服务】App Service 通过配置web.config来添加请求返回的响应头(Response Header)
【Azure 应用服务】App Service 通过配置web.config来添加请求返回的响应头(Response Header)
|
5月前
|
API
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
|
7月前
|
JSON 前端开发 Java
一文读Web开发 之接口后端接口、类与前端请求、拦截器编写
一文读Web开发 之接口后端接口、类与前端请求、拦截器编写
243 6
|
7月前
|
运维 Java 测试技术
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
60 3
|
3月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
184 3
|
1月前
|
前端开发 安全 JavaScript
2025年,Web3开发学习路线全指南
本文提供了一条针对Dapp应用开发的学习路线,涵盖了Web3领域的重要技术栈,如区块链基础、以太坊技术、Solidity编程、智能合约开发及安全、web3.js和ethers.js库的使用、Truffle框架等。文章首先分析了国内区块链企业的技术需求,随后详细介绍了每个技术点的学习资源和方法,旨在帮助初学者系统地掌握Dapp开发所需的知识和技能。
2025年,Web3开发学习路线全指南
|
2月前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
208 45