一.req.getRequestDispatch()
-
使用转发方法跳转页面:req.getRequestDispatch("/b").forward(req,resp);
这是RequestDispatcher requestDispatcher = req.getRequestDispatcher("/b");requestDispatcher.forward(req,resp);的简易写法。 -
使用转发的时候是发送一次请求,例如Aservlet转发到BServlet中都是在同一个request,转发时不需要加应用的根路径。
使用转发方法的AServlet类
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//实例化user类,并且向user类中插入内容
User user = new User();
user.setId("123");
user.setName("张三");
//存入数据
req.setAttribute("massage",user);
//转发
req.getRequestDispatcher("/b").forward(req,resp);
}
}
BServlet类
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
Object attribute = req.getAttribute("massage");
out.print(attribute);
}
}
-
在使用转发进行跳转后,虽然显示的是BServlet的内容但浏览器的地址栏还是/servletdemo/a
-
转发的使用:如果在上一个Servlet中向request中绑定了数据,希望下一个servlet把request域里的数据提取出来的话,使用转发机制
二.resp.sendRedirect()
- 使用重定向:resp.sendRedirect(req.getContextPath()+"/b");
在书写需要填写根路径的方法时最好不要写死路径,可以使用req.getContextPath()获取根目录填入方法中。
重定向相比于转发来说,重定向是两次请求两次响应。使用重定向的AServlet类
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//实例化user类,并且向user类中插入内容
User user = new User();
user.setId("123");
user.setName("");
//存入数据
req.setAttribute("massage",user);
//重定向
resp.sendRedirect(req.getContextPath()+"/b");
}
}
-
使用重定向后浏览器地址栏的地址将会变成http://localhost:8081/servletdemo/b,而转发却不会,依旧会停留在http://localhost:8081/servletdemo/a。
-
使用重定向跳转后的Servlet不能获取跳转前Servlet里request绑定的数据,因为这两个Servlet不共享同一个ServletRequest对象,因此不共享请求数据。
-
编写form表单提交表单数据到数据库,如果自己设计的数据的数据表没有设定主键的话,使用重定向和转发跳转页面将会出现不同的结果,这也是他们不同机制的体现。
-
使用转发:
LoginServlet类
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
//连接数据库
Connection conn = null;
PreparedStatement ps = null;
//获取前端form表单的数据
String id = req.getParameter("userName");
String password = req.getParameter("password");
int count = 0;
try {
//建立连接,并向数据库中添加数据
conn = jdbcUtil.getConnection();
String sql = "insert into login(id,password) values(?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1,id);
ps.setString(2,password);
count = ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
jdbcUtil.close(conn,ps,null);
}
if ( count == 1){
//使用转发
req.getRequestDispatcher("/ok.html").forward(req,resp);
//resp.sendRedirect(req.getContextPath()+"/ok.html");
}else {
req.getRequestDispatcher("/error.html").forward(req,resp);
//resp.sendRedirect(req.getContextPath()+"/error.html");
}
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/servletdemo/login" method="post">
账号:<input type="text" name="userName"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="提交">
</form>
</body>
</html>
(前后端的请求方法要保持一致要不然会出现405报错)
- 浏览器呈现form表单,输入账号和密码后出现ok页面不断的点击刷新会出现反复向数据库中添加相同数据的现象。
- 而重定向却不会发生这类问题,所以日常设计数据表不要忘记添加主键,如果添加了主键那么在填写相同数据时编译器将会抛出此类异常,防止出现相同数据。
-最后在转发和重定向的使用中大多数情况都使用重定向,如果在上一个Servlet中向request中绑定了数据,希望下一个servlet把request域里的数据提取出来的话,使用转发机制。