1.request实现转发跳转,数据传递
现有问题:
在之前案例中,调用业务逻辑和显示结果界面都在同一个Servlet里,就会产生设计问题
- 不符合单一职能原则,各司其职的思想
- 不利于后缀的维护
应该将业务逻辑和显示结果分离开
问题:业务逻辑和显示结果分离,如何跳转到显示结果的Servlet?
业务逻辑得到的数据结果怎么传递给显示结果的Servlet?
转发
转发的作用在服务器端,将请求发送给服务器上的其他资源,共同完成一次请求的处理。
页面跳转
在调用业务逻辑的servlet中,编写以下代码
req.getRequestDispatcher("/目标URL-pattern").forward(req,resp);
使用forward跳转时,是在服务器内部跳转,地址栏不发生变化,属于同一次请求。
数据传递
forward表示一次请求,是在服务器内部跳转,可以共享同一次request作用域中的数据。
- request作用域:拥有存储数据的空间,作用范围是一次请求有效(一次请求可以经过多次转发)
- 可以将数据存入request后,在一次请求过程中的任何位置进行获取
- 可以传递任何数据(基本数据类型,对象,数组,集合等)
- 存数据:request.setAttribute(key,value);
- 以键值对形式存储在request作用域中,key为String类型,value为Object类型
- 取数据:request.getAttribute(key);
- 通过String类型的key访问Object类型的value
转发特点
- 转发是服务器行为
- 转发是浏览器只做了一次访问请求
- 转发浏览器地址不变
- 转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递
- 转发只能将请求转发给同一个web应用中的组件
2.response实现重定向
重定向
重定向作用在客户端,客户端将请求发送给服务端后,服务器响应给客户端一个新的请求地址,客户端重新发送新请求。
页面跳转
在调用业务逻辑的servlet中,编写以下代码
response.sendRedirect("目标URL");
URL:统一资源标识符(Uniform Resource Identifier),用来表示服务器中定位一个资源,资源在web项目中的路径。
数据传递
sendRedirect跳转时,地址栏改变,代表客户端重新发送的请求,属于两次请求。
- response没有作用域,两次request请求中的数据无法共享
- 传递数据:通过URL的拼接进行数据传递("/webProject/b?username="tom");
- 获取数据:request.getParameter("username");
重定向特点:
- 重定向是客户端行为
- 重定向是浏览器做了至少两次的访问请求
- 重定向浏览器地址改变
- 重定向两次跳转之间传输的信息会丢失(request范围)
- 重定向可以指向任何的资源,包括当前应用程序中的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源。
ShowAllAdminController.java
package com.newer.servletProject.servlet.controller;
import com.newer.servletProject.entity.Admin;
import com.newer.servletProject.entity.Manager;
import com.newer.servletProject.service.AdminService;
import com.newer.servletProject.service.impl.AdminServiceImpl;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
@WebServlet(value = "/showallController")
public class ShowAllAdminController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//通过HttpSession完成权限控制
/* HttpSession session= req.getSession();
Manager mgr=(Manager)session.getAttribute("mgr");*/
/* if (mgr!=null){*/
//只负责调用业务逻辑
AdminService adminService = new AdminServiceImpl();
List<Admin> adminList = adminService.showAllAdmin(); //调用业务逻辑层
//request作用域
req.setAttribute("admins",adminList);
//通过转发,跳转到显示结果servlet
req.getRequestDispatcher("/showalljsp").forward(req,resp);
/* }else {
resp.sendRedirect("/day01web1_war_exploded/loginMgr.html");
}*/
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
ShowAllAdminJSP.java(显示所有用户界面)
package com.newer.servletProject.servlet.jsp;
import com.newer.servletProject.entity.Admin;
import com.newer.servletProject.entity.Manager;
import com.newer.servletProject.service.AdminService;
import com.newer.servletProject.service.impl.AdminServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet(value = "/showalljsp")
public class ShowAllAdminJSP extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
HttpSession session=req.getSession();
Manager mgr=(Manager)session.getAttribute("mgr") ;
//将拿到的值强转为List类型
List<Admin> adminList = (List) req.getAttribute("admins");
PrintWriter printWriter = resp.getWriter();
if (adminList != null) {
printWriter.println("<html>");
printWriter.println("<head>");
printWriter.println("<meta charset='UTF-8'>");
printWriter.println("<title>显示所有</title>");
printWriter.println("</head>");
printWriter.println("<body>");
printWriter.println("<h1>欢迎你:"+mgr.getUsername()+"</h1>");
printWriter.println("<table border='1'>");
printWriter.println(" <tr>");
printWriter.println(" <td>username</td>");
printWriter.println(" <td>password</td>");
printWriter.println(" <td>phone</td>");
printWriter.println(" <td>address</td>");
printWriter.println(" </tr>");
for (Admin admin : adminList) {
printWriter.println(" <tr>");
printWriter.println(" <td>" + admin.getUsername() + "</td>");
printWriter.println(" <td>" + admin.getPassword() + "</td>");
printWriter.println(" <td>" + admin.getPhone() + "</td>");
printWriter.println(" <td>" + admin.getAddress() + "</td>");
printWriter.println(" </tr>");
}
printWriter.println("</table>");
printWriter.println("</body>");
printWriter.println("</html>");
} else {
printWriter.println("<html>");
printWriter.println("<head>");
printWriter.println("<meta charset='utf-8'>");
printWriter.println("<title>结果页面</title>");
printWriter.println("</head>");
printWriter.println("<body>");
printWriter.println("<h3>当前没有用户数据</h3>");
printWriter.println("</body>");
printWriter.println("</html>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
为了更好理解转发跳转及重定向,A,B例子如下
AServlet.java
package com.newer.servletProject.servlet;
/**
* 转发与重定向
*/
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(value = "/a")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* //通过request作用域做数据的存储
req.setAttribute("username", "gavin");
req.getRequestDispatcher("/b").forward(req, resp); //页面跳转*/
//重定向----传递的数据必须是明文形式,而且是字符串类型
resp.sendRedirect("/day01web1_war_exploded/b?username=tom");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
BServlet.java
package com.newer.servletProject.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(value = "/b")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* String s = (String) req.getAttribute("username");
System.out.println(s);*/
String username=req.getParameter("username");
System.out.println("重定向......"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
3.转发,重定向总结
当两个Servlet需要传递数据时,选择forward转发,不建议使用sendRedirect进行传递