✅作者简介:热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:JAVA开发者成长之路
✨特色专栏:国学周更-心性养成之路
🥭本文内容:Servlet转发与重定向
更多内容点击👇
Servlet应用(Request+response对象)
本文目录
- 转发
- 【1】页面跳转
- 【2】数据传递
- 【3】转发特点
- 【4】转发过程
- 重定向
- 【1】页面跳转
- 【2】数据传递
- 【3】重定向特点
- 【4】重定向过程
- 转发和重定向总结
转发
转发的作用在服务器端,将请求发送给服务器上的其它资源,以共同完成一次请求的处理。
【1】页面跳转
在调用业务逻辑的Servlet中,服务器端跳转主要通过 RequestDispatcher 接口来实现:
- 获取接口:+getRequestDispatcher(“String path”):RequestDispatcher
- 跳转方法:+forward(ServletRequest request,ServletResponse response):void
示例代码一:
package cn.lqgx.www;
import entity.Student;
import service.StudentService;
import service.impl.StudentServiceImpl;
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;
import java.io.PrintWriter;
import java.util.List;
@WebServlet("/show")
public class StudentShow extends HttpServlet {
StudentService studentService=new StudentServiceImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Student> studentList = studentService.selectAllStudents();
req.setAttribute("students",studentList);
req.getRequestDispatcher("/StudentAllServlet").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
使用forward跳转时,是在服务器内部跳转,地址栏不发生变化,属于同一次请求。
【2】数据传递
forward表示一次请求,是在服务器内部跳转,可以共享同一次request作用域中的数据。
- request作用域:拥有存储数据的空间,作用范围是一次请求有效(一次请求可以多次转发)
- 可以将数据存入request后,在一次请求过程中的任何位置进行获取
- 可传递任何数据类型(基本数据类型、对象、数组、集合等)
- 存数据:request.setAttribute(key,value);
- 以键值对形式存储在request作用域中。key为String类型,value为Object类型
- 取数据:request.getAttribute(key);
- 通过String类型的key获取Object类型的value
示例代码二:根据 示例代码一 传递的数据,在显示层获取数据并显示。
package cn.lqgx.www;
import entity.Student;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
@WebServlet(name = "StudentAllServlet", value = "/StudentAllServlet")
public class StudentAllServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Student> studentList=(List<Student>)request.getAttribute("students");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter printWriter=response.getWriter();
response.setContentType("text/html;charset=UTF-8");
printWriter.write("<html lang=\"en\">");
printWriter.write("<head>");
printWriter.write("<meta charset=\"UTF-8\">");
printWriter.write("<title>Title</title>");
printWriter.write("<style>");
printWriter.write("td{width:200px;height:45px;line-height:45px;text-align:center;}");
printWriter.write("table tr:nth-child(odd){background:green;}");
printWriter.write("table tr:nth-child(even){background:#FE5F97;}");
printWriter.write("th{height:40px;line-height:40px;text-align:center;background:white;}");
printWriter.write("caption{height:45px;line-height:45px;text-align:center;}");
printWriter.write("</style>");
printWriter.write("</head>");
printWriter.write("<body>");
printWriter.write("<table border=\"1\" width=\"100%\" cellspacing=\"0\">");
printWriter.write("<caption align=\"top\">所有学生信息</caption>");
printWriter.write("<thead>");
printWriter.write("<tr>");
printWriter.write("<th>学号</th>");
printWriter.write("<th>姓名</th>");
printWriter.write("<th>年龄</th>");
printWriter.write("<th>性别</th>");
printWriter.write("<th>地址</th>");
printWriter.write("<th>电话号码</th>");
printWriter.write("</tr>");
printWriter.write("</thead>");
printWriter.write("<tbody>");
for (int i = 0; i < studentList.size(); i++) {
printWriter.write("<tr>");
printWriter.write("<td>"+studentList.get(i).getSid()+"</td>");
printWriter.write("<td>"+studentList.get(i).getSname()+"</td>");
printWriter.write("<td>"+studentList.get(i).getSage()+"</td>");
printWriter.write("<td>"+studentList.get(i).getSsex()+"</td>");
printWriter.write("<td>"+studentList.get(i).getSaddress()+"</td>");
printWriter.write("<td>"+studentList.get(i).getSphoneNum()+"</td>");
printWriter.write("</tr>");
}
printWriter.write("</tbody>");
printWriter.write("</table>");
printWriter.write("</body>");
printWriter.write("</html>");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
【3】转发特点
- 转发是服务器行为
- 转发是浏览器只做了一次访问请求
- 转发两次跳转之间传输的信息不会丢失,多以可以通过request进行数据的传递
- 转发只能将请求转发给同一个Web应用中的组件
【4】转发过程
- 浏览器向服务器发送请求
- 服务器接收请求并处理请求
- 这时服务器发现有转发代码存在,
- 直接跳转到新的资源(注意:这个过程是连续的,在这个过程中session可以跟随传递)
- 网页显示返回结果,地址栏不会变化
重定向
重定向作用在客户端,客户端将请求发送给服务器中,服务器响应给客户端一个新的请求地址,客户端重新发送新请求。
【1】页面跳转
在调用业务逻辑的Servlet中,编写以下代码:
response.sendRedirect(“目标URI”);
URI:统一资源标识符(Uniform Resource Identifier),用来表示服务器中定位一个资源,资源在Web项目中的路径(、project/source)
使用redirect跳转时,是在客户端跳转,地址栏发生变化,属于多次请求
示例代码三:
package cn.lqgx.Servlet;
import cn.lqgx.entity.Book;
import cn.lqgx.service.BookService;
import cn.lqgx.service.Impl.BookServiceImpl;
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(name = "ServletUpdateTrue", value = "/ServletUpdateTrue")
public class ServletUpdateTrue extends HttpServlet {
BookService bookService=new BookServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//通过response输出在控制台
int bid= Integer.parseInt(request.getParameter("bid"));
String isbn= request.getParameter("isbn");
String name= request.getParameter("name");
String author= request.getParameter("author");
String press= request.getParameter("press");
double price= Double.parseDouble(request.getParameter("price"));
String classification= request.getParameter("classification");
Book book=new Book(bid,isbn,name,author,press,price,classification);
//先查询要添加的数据是否存在数据库中
int num =bookService.updateBook(book);
if(num>0){
//重新显示所有信息
response.sendRedirect("ServletShow");
}else {
// printWriter.println("<h1>修改失败!</h1>");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
【2】数据传递
sendRedirect跳转时、地址栏改变,代表客户端重新发送的请求。属于两次请求。
- response没有作用域,两次request请求中的数据无法共享
- 传递数据:通过URI的拼接进行数据传递(“WebProject/b?username=zhangsan”);
【3】重定向特点
- 重定向是客户端行为
- 重定向是浏览器做了至少两次的访问请求
- 重定向浏览器地址改变
- 重定向两次跳转之间传输的信息会丢失(request范围)
- 重定向可以指向任何的资源,包括当前应用程序中的其它资源、同一个站点上的其它应用程序中的资源、其它站点的资源
【4】重定向过程
- 浏览器向服务器发送请求
- 服务器接收请求并处理请求
- 这时服务器发现有重定向代码存在
- 服务器会立即通知浏览器,告诉它,你去访问这个资源
- 这时浏览器会对新资源重新发起访问(这个过程是断开的,中间不连续)
- 地址栏产生相应的变化
转发和重定向总结
当两个Servlet需要传递数据时,选择forward转发,不建议使用sendRedirect进行传递。二者区别如下:
- 转发地址栏不会变化,重定向会变化。
- 转发是一次请求,而重定向是两次。
- 转发速度较快,重定向较慢(因为浏览器要重新发起请求)。
- 由于重定向是重新对资源发起访问,而浏览器默认访问方式为get,所以对应的新响要换成get,当然这是默认情况。注意一下即可。
- 转发不会造成信息丢失,而重定向则会造成信息丢失。
- 转发只能将请求转发给同一个WEB应用中的组件,重定向可以指向任何的资源,包括当前应用程序中的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源。
码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识,点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。