请求转发

类似于我们要电脑城购买组装一台电脑,当我们到门店的时候,和店员说,我要组装一台电脑,然后剩下的我们不管,这个电脑用到的零件,这个店家自己去组装,如果没有,他会去别的店铺找,但这个过程我们不用管,我们最后就得到了一台组装好的电脑

响应重定向

类似于,我们同样去电脑城组装一台电脑,当我们到门店的时候,和店员说,我要组装一台电脑,店员给我们组装了一下,发现零件不够,这时候店员和我们说,我给你推荐一家店,你去那里肯定能组装好,那我们就离开了这家店,去这家店推荐的店铺里完成组装购买.



解决了一次请求内不同servlet的数据共享问题,但存在重复提交数据的风险

请求转发,是服务器 的行为,请求由服务器 转发给另外一个页面处理,如何转发,何时转发,转发几次,客户端是不知道的。请求转发时,从发送第一次到最后一次请求的过程中,web容器创建一次request和response对象,新的页面继续处理同一个请求。也可以理解为服务器将request 对象在页面之间传递。请求转发实际上就是一个servlet中调用其他的servlet

特点

请求转发: 不管跳转几个页面, 都是一次请求. 通过请求对象实现

  1. > 客户端浏览器发送一次请求,剩下的由服务器进行处理
  2. 存在RRL中的数据重复提交的风险,容易造成安全问题
  3. 参与的servlet共享request和response
  4. > 只能跳转到内部资源(项目中), 不能跳转外部资源(项目外)
  5. > 可以访问受保护的资源(WEB-INF)

核心代码


req.getRequestDispatcher("转发的servlet路径").forward(req, resp);


跳转资源实现


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("进入Servlet2");
        System.out.println(req.getParameter("computer"));
        // 继续跳转到demo.html --> ok
        // req.getRequestDispatcher("demo.html").forward(req, resp);
        // 跳转到百度 --> no
        // req.getRequestDispatcher("http://www.baidu.com").forward(req, resp);
        // 跳转到受保护的资源 --> ok
        req.getRequestDispatcher("WEB-INF/test.html").forward(req, resp);
    }
}


既然是请求转发,那不可避免的就会需要传递一些信息和参数,这时候就需要使用request对象作为数据的载体,携带数据到下一个servlet

Request 作用域

一次请求转发的所有参与的servlet

可以使用req参数作为数据流的载体,将信息在参与请求转发的servlet中传递和获取

携带参数


req.setAttribute("String name","Object obj")
req.setAttribute("键(携带参数的名字)","值(需要携带参数的内容)")


获取携带参数

用下方在代码之前需要考虑一件事,就是参与的请求转发servlet会有两种情况,第一种是由上一个servlet请求转发,传过来的request肯定会有数据,但是也不可避免的出现含有下列代码的servlet被直接调用,所以用的时候要判断request是否有数据在里面


req.getAttribute("String name")
req.getAttribute("键(携带参数的名字)")



响应重定向

重定向可以解决请求转发的一个风险问题:数据重复提交

重定向,是客户端的行为,每次请求重定向都是由客户端发起的,也就是说重定向一次,就刷新request对象的属性,之前的request对象的属性值就失效了。

作用:

保护第一次的请求,避免因为用户的刷新动作频繁触发第一次请求servlet的重复执行

(因为如果是get提交的方式,使用请求转发,地址栏的地址不会发生变化且带着相关的数据,刷新页面一次,等于提交一次数据,这就存在脏数据和安全风险的问题,如何解决这一问题,这就需要使用重定向技术)

特点:

响应重定向: 通过响应对象实现, 跳转几个页面就发送几次请求

> 发送多次请求,最少两次

> 地址栏会发生改变(最后一次请求的路径)

> 参数不能一直传递, 需要手动传递(原因是不是同一次请求了)

> 既可以跳转到内部资源, 也可以跳转到外部资源

> 不能访问受保护的资源

核心代码:


resp.sendRedirect("WEB-INF/test.html");


package com.bjsxt.redirect;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Servlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("Servlet2执行...");
        System.out.println(req.getParameter("computer"));
        // 跳转页面到demo.html --> ok
        // resp.sendRedirect("demo.html");
        // 跳转到百度 --> ok
        // resp.sendRedirect("http://www.baidu.com");
        // 访问受保护的资源 --> no
        resp.sendRedirect("WEB-INF/test.html");
    }
}


重定向,是客户端的行为,每次请求重定向都是由客户端发起的,也就是说重定向一次,就刷新request对象的属性,之前的request对象的属性值就失效了。所以不能用request对象来传递共享数据,这就需要使用我们的session对象,所以就需要开启下一篇及后续的学习

于此同时,代码书写流程步骤也有了新的变化


java sse协议请求转发_重定向



请求转发实操

index.jsp


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
<form method="post" action="cookie">

    <p>
        用户名:<input type="text" name="uname" >
    </p>
    <p>
        密 码:<input type="password" name="pwd">
    </p>
    <p>
        <input type="submit" value="提交">
    </p>
</form>
</body>
</html>


web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>CR1</servlet-name>
        <servlet-class>com.lin.servlet.ServletCookie</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CR1</servlet-name>
        <url-pattern>/cookie</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>CR2</servlet-name>
        <servlet-class>com.lin.servlet.ServiceCookie2</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CR2</servlet-name>
        <url-pattern>/cookie2</url-pattern>
    </servlet-mapping>
</web-app>


servlet1


package com.lin.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServletCookie extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1 设置请求编码格式
        req.setCharacterEncoding("utf-8");
        //2 设置响应编码格式
        resp.setContentType("text/html;charset=utf-8");
        //3 获取请求信息
        String uname = req.getParameter("uname");
        String pwd = req.getParameter("pwd");
        //4 处理请求信息
        System.out.println(uname+"--"+pwd);
        //5 响应处理结果
           //6 直接响应or
     //   resp.getWriter().write("直接处理,响应完毕");
           //7 请求转发or
        req.setAttribute("tr",uname+"--"+pwd);
        req.getRequestDispatcher("/cookie2").forward(req,resp);
    }
}


servlet2


package com.lin.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class ServiceCookie2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        System.out.println("这里是Cookie2");
        String tr = (String) req.getAttribute("tr");
        System.out.println(tr);
    }
}