web应用的资源跳转
  TEZNKK3IfmPf 2023年11月13日 52 0

  - 第一种方式:转发

  - 第二种方式:重定向

2. 转发和重定向有什么区别?  30

2.1 代码上有什么区别?

2.1.1 转发

// 获取请求转发器对象

 RequestDispatcher dispatcher = request.getRequestDispatcher("/dept/list");

// 调用请求转发器对象的forward方法完成转发

dispatcher.forward(request, response);     

// 合并一行代码

 request.getRequestDispatcher("/dept/list").forward(request, response);

// 转发的时候是一次请求,不管你转发了多少次。都是一次请求。

// AServlet转发到BServlet,再转发到CServlet,再转发到DServlet,不管转发了多少次,都在同一个request当中。

// 这是因为调用forward方法的时候,会将当前的request和response对象传递给下一个Servlet

2.1.2 重定向

        // 注意:路径上要加一个项目名。为什么?

        // 浏览器发送请求,请求路径上是需要添加项目名的。

        // 以下这一行代码会将请求路径“/oa/dept/list”发送给浏览器

        // 浏览器会自发的向服务器发送一次全新的请求:/oa/dept/list

        response.sendRedirect("/oa/dept/list");

2.2 形式上有什么区别?  30

2.2.1  转发(一次请求)

      - 在浏览器地址栏上发送的请求是:http://localhost:8080/servlet10/a ,最终请求结束之后,浏览器地址栏上的地址还是这个。没变。

web应用的资源跳转

2.2.2 重定向(两次请求)

      - 在浏览器地址栏上发送的请求是:http://localhost:8080/servlet10/a ,最终在浏览器地址栏上显示的地址是:http://localhost:8080/servlet10/b

web应用的资源跳转

2.3 转发和重定向的本质区别?30

    - 转发:是由WEB服务器来控制的。A资源跳转到B资源,这个跳转动作是Tomcat服务器内部完成的。

    - 重定向:是浏览器完成的。具体跳转到哪个资源,是浏览器说了算。

3.转发和重定向应该如何选择?什么时候使用转发,什么时候使用重定向?31

  - 如果在上一个Servlet当中向request域当中绑定了数据,希望从下一个Servlet当中把request域里面的数据取出来,使用转发机制。

  - 剩下所有的请求均使用重定向。(重定向使用较多。)

- 跳转的下一个资源有没有要求呢?必须是一个Servlet吗?

  - 不一定,跳转的资源只要是服务器内部合法的资源即可。包括:Servlet、JSP、HTML.....

- 转发会存在浏览器的刷新问题。

4. 重定向举例  30

代码在com.bjpowernode.javaweb.servlet

AServlet

package com.bjpowernode.javaweb.servlet;

import com.bjpowernode.javaweb.bean.User;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

//重定向解析  30
public class AServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //创建一个对象
        User user = new User();
        user.setId("1111111");
        user.setName("杰克");

        //将用户对象存储到请求域中
        request.setAttribute("Userobj",user);

        //转发
        //request.getRequestDispatcher("/b").forward(request,response);

        // 重定向(重新定方向)
        // 重定向时的路径当中需要以项目名开始,或者说需要添加项目名。
        // response对象将这个路径:"/servlet10/b"响应给浏览器了。
        // 浏览器又自发的向服务器发送了一次全新的请求:http://localhost:8080/servlet10/b
        // 所以浏览器一共发送了两次请求:
        // 第一次请求:http://localhost:8080/servlet10/a
        // 第二次请求:http://localhost:8080/servlet10/b
        // 最终浏览器地址栏上显示的地址当然是最后那一次请求的地址。所以重定向会导致浏览
        // 器地址栏上的地址发生改变。
        response.sendRedirect(request.getContextPath()+"/b");

    }
}

BServlet

package com.bjpowernode.javaweb.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.io.PrintWriter;

//重定向解析  30
public class BServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //从请求域中取出数据
        Object userobj = request.getAttribute("Userobj");

        //输出到浏览器
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.print("请求域当中的用户对象:"+userobj);//请求域当中的用户对象:User{id='1111111', name='杰克'}
    }
}

代码在com.bjpowernode.javaweb.bean    

User
package com.bjpowernode.javaweb.bean;

import java.io.Serializable;
import java.util.Objects;

//配合研究重定向  30
//一个普通的javabean
// 一个JavaBean一般是有规范的:
// *      有无参数的构造方法
// *      属性私有化
// *      对外提供setter和getter方法
// *      重写toString()
// *      重写hashCode + equals
// *      实现java.io.Serializable接口。
public class User implements Serializable {
    private String id;
    private String name;

    public User() {
    }

    public User(String id, String name) {
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) &&
                Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

web.xml

<!--    这个AServlet配置  30-->
    <servlet>
        <servlet-name>a</servlet-name>
        <servlet-class>com.bjpowernode.javaweb.servlet.AServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>a</servlet-name>
        <url-pattern>/a</url-pattern>
    </servlet-mapping>


    <!--    这个BServlet配置-->
    <servlet>
        <servlet-name>b</servlet-name>
        <servlet-class>com.bjpowernode.javaweb.servlet.BServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>b</servlet-name>
        <url-pattern>/b</url-pattern>
    </servlet-mapping>

5. 重定向和转发细节  31

代码在com.bjpowernode.javaweb.servlet

StudentSaveServlet

package com.bjpowernode.javaweb.servlet;

import com.bjpowernode.javaweb.utils.DBUtil;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

//重定向和转发对比举例  31
public class StudentSaveServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 保存学生信息到数据库
        request.setCharacterEncoding("UTF-8");
        String no = request.getParameter("no");
        String name = request.getParameter("name");
        Connection conn = null;
        PreparedStatement ps = null;
        int count = 0;
        try {
            conn = DBUtil.getConnection();
            String sql = "insert into t_student(no,name) values(?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, no);
            ps.setString(2, name);
            count = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(conn, ps, null);
        }
        // 保存成功之后跳转到成功页面
        if (count == 1) {
            // 转发
            //request.getRequestDispatcher("/success.html").forward(request, response);

            // 重定向
            response.sendRedirect(request.getContextPath() + "/success.html");
        }else{

        }
    }
}

com.bjpowernode.javaweb.utils

工具类DButil

package com.bjpowernode.javaweb.utils;

import java.sql.*;
import java.util.ResourceBundle;

/**
 * JDBC的工具类   27
 */
public class DBUtil {

    // 静态变量:在类加载时执行。
    // 并且是有顺序的。自上而下的顺序。
    // 属性资源文件绑定
    private static ResourceBundle bundle = ResourceBundle.getBundle("resources.jdbc");
    // 根据属性配置文件key获取value
    private static String driver = bundle.getString("driver");
    private static String url = bundle.getString("url");
    private static String user = bundle.getString("user");
    private static String password = bundle.getString("password");

    static {
        // 注册驱动(注册驱动只需要注册一次,放在静态代码块当中。DBUtil类加载的时候执行。)
        try {
            // "com.mysql.jdbc.Driver" 是连接数据库的驱动,不能写死。因为以后可能还会连接Oracle数据库。
            // 如果连接oracle数据库的时候,还需要修改java代码,显然违背了OCP开闭原则。
            // OCP开闭原则:对扩展开放,对修改关闭。(什么是符合OCP呢?在进行功能扩展的时候,不需要修改java源代码。)
            //Class.forName("com.mysql.jdbc.Driver");

            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接对象
     * @return conn 连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        // 获取连接
        Connection conn = DriverManager.getConnection(url, user, password);
        return conn;
    }

    /**
     * 释放资源
     * @param conn 连接对象
     * @param ps 数据库操作对象
     * @param rs 结果集对象
     */
    public static void close(Connection conn, Statement ps, ResultSet rs){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}

student.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>学生</title>
</head>
<body>
<form action="/servlet10/save" method="get">
    学生编号<input type="text" name="no"><br>
    学生姓名<input type="text" name="name"><br>
    <input type="submit" value="保存">
</form>
</body>
</html>

success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
<h1>success page</h1>
</body>
</html>

error.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>error</title>
</head>
<body>
<h1>error page</h1>
</body>
</html>

web.xml

<!--    这个StudentSaveServlet配置  31-->
    <servlet>
        <servlet-name>save</servlet-name>
        <servlet-class>com.bjpowernode.javaweb.servlet.StudentSaveServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>save</servlet-name>
        <url-pattern>/save</url-pattern>
    </servlet-mapping>

代码在src.resources

配置文件jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bjpowernode
user=root
password=lzl
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月13日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   20天前   46   0   0 java
TEZNKK3IfmPf