1.资源跳转可以通过两种方式在web应用程序中完成:30
-第一种方式:转发
-第二种方法:重定向
2.转发和重定向有什么区别?302.1代码有什么区别?2.1.1转发///获得转发器对象的请求
RequestDispatcherdispatcher=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形式有什么区别?302.2.转发(一次请求)-在浏览器地址栏上发送的请求是:http://localhost:8080/servlet10/a,最终请求结束后,浏览器地址栏上的地址仍然是这样。没有改变。
2.2.2重定向(两次请求)-在浏览器地址栏上发送的请求是:http://localhost:8080/servlet10/a,浏览器地址栏上显示的最终地址是:http://localhost:8080/servlet10/b
2.3转发与重定向的本质区别?30-转发:由WEB服务器控制。A资源跳转到B资源,由Tomcat服务器内部完成。
-重定向:由浏览器完成。浏览器有最终决定权跳转到哪些资源。
3.如何选择转发和重定向?什么时候使用转发,什么时候使用重定向?31-如果将数据绑定到上一个Servlet中的request域,则希望从下一个Servlet中取出request域中的数据,并使用转发机制。
-所有剩余请求均采用重定向。(重定向使用较多。)
-下一个跳转资源有什么要求吗?一定是Servlet吗?
-不一定,只要跳转资源是服务器内部的合法资源。包括:Servlet、JSP、HTML...
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;///重定向分析 30public 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.beanUser
package com.bjpowernode.javaweb.bean;import java.io.Serializable;import java.util.Objects;//配合研究重定向 30///普通javabean/// Javabean通常是标准的:// * 构造方法是否有参数/// * 属性私有化//////// * 为外界提供setter和getter方法/// * tostring()////// * hashCode重写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.重定向和转发细节311com中的代码.bjpowernode.javaweb.servletStudentSaveServlet
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;///重定向和转发比例 31public 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类时执行。加载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代码.resourcesjdbc配置文件.properties
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/bjpowernodeuser=rootpassword=lzl