请求转发和重定向

request除了可以作为请求对象之外,还可以作为域对象,但是该域对象的取值范围,是一次请求范围之内(浏览器地址栏没有发生跳转访问别的资源)

作用:将servlet中的数据通过request对象带到jsp页面;

请求转发

  1. 通过请求对象获取请求转发对象

    RequestDispatcher requestDispatcher = req.getRequestDispatcher("资源相对路径");
  2. 定位具体资源

    requestDispatcher.forward(req,resp);

实现内部资源的跳转:通过浏览器发起访问,工程中的资源会从一个地址跳转到另外一个地址,但浏览器端的地址不会发生改变。

请求对象req还可以作为与对象存放数据,因为请求转发方式是不会发生地址的跳转的,所以在req的作用范围(一次请求范围)之内,因此可以在跳转的资源中获取到存放的数据。

@WebServlet("/hello01")
public class HelloServlet extends HttpServlet { @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //往域中存放数据
req.setAttribute("username","jack");
req.setAttribute("password","123456"); //获取请求转发对象 参数是另一个资源的相对路径
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/hello02"); //调用forward 定位具体资源
requestDispatcher.forward(req,resp); }
}
@WebServlet("/hello02")
public class HelloServlet02 extends HttpServlet { @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //取出域中的数据
Object username = req.getAttribute("username");
Object password = req.getAttribute("password");
System.out.println(username);
System.out.println(password); }
}

输出结果:

jack
123456

在访问这个地址后,地址栏的地址没有发生跳转,但是访问的资源已经到了/hello02,通过后端控制台打印就可看到获取到了数据。

请求重定向

可以完成内部资源的跳转,而且浏览器的地址是会发生改变的,这种情况下,不能取到request域中的数据

hello03后端资源:

@WebServlet("/hello03")
public class HelloServlet03 extends HttpServlet { @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //往域中存放数据
req.setAttribute("key","value"); //请求重定向 是响应对象
//参数是绝对路径
resp.sendRedirect("http://localhost:8080/servlet/hello04"); }
}

hello04后端资源:

@WebServlet("/hello04")
public class HelloServlet04 extends HttpServlet { @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //取出数据
Object key = req.getAttribute("key");
System.out.println("----"+key+"----"); }
}
  1. 通过浏览器方法hello03资源

  2. 浏览器端地址跳转

  3. 控制台打印key值

    因为发生了重定向是要发生地址跳转的,超出了req与对象的作用范围(一次请求)内,所以在hello04资源中是获取不到hello03资源的req的数据的。

请求重定向到静态html页面

hello05:

@WebServlet("/hello05")
public class HelloServlet05 extends HttpServlet { @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /*//获取转发对象 相对路径 前端资源/代表web文件夹下
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/html/test.html"); //定位到具体资源
requestDispatcher.forward(req,resp);*/ //请求重定向
resp.sendRedirect("http://localhost:8080/servlet/html/test.html"); }
}

test.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
</head>
<body>
成功访问了前端静态资源 </body>
</html>

浏览器访问结果:

总结:

存放在ServletContext域对象中的数据,不管是通过重定向还是请求转发都是可以在跳转的资源中的获取到的。

存放在请求域对象request中的数据,如果是通过请求转发,没有地址的跳转,是可以在另一资源中获取到的;相反,若干是重定向,有地址的跳转,那么不可以在另一个资源中获取到访问资源request中存放的数据。

JSP模板引擎

html是前端中静态的资源,是不能直接获取到后端的资源的。jsp模板引擎,可以动态渲染后端数据到前端,jsp中的el表达式可以取出后端域中的数据。

格式:

${域对象的key}
@WebServlet("/hello06")
public class HelloServlet06 extends HttpServlet { @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { User user1=new User("jack1","132");
User user2=new User("jack2","132");
User user3=new User("jack3","132");
ArrayList<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3); //获取ServletContext域对象
ServletContext servletContext = getServletContext();
servletContext.setAttribute("users",users); //重定向
resp.sendRedirect("http://localhost:8080/servlet/jsp/test.jsp");
}
}

test.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>Title</title></head><body>    ${users}</body></html>

浏览器访问结果:

重定向有地址的跳转

JSP

JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,并能与服务器上的其它Java程序共同处理复杂的业务需求。JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。

JSP是一个前端的模板引擎,用于渲染后端数据,底层本质是一个Servlet程序。JSP可以动态的获取到后端的数据,由于底层是servlet,servlet底层是java,所以可以在代码脚本中去编写java代码

EL表达式

可以在后端资源中的域对象ServletContext中设置属性,然后在跳转的JSP文件中通过EL表达式获取到属性值。可以用request请求域对象和ServletContext域对象来设置属性和值,这基于方式是请求转发方式还是请求重定向方式,如果是请求转发方式,那么可以用request请求域对象或者ServletContext域对象来setAttribute,因为请求转发方式不会发生地址的跳转,request请求域对象也可以进行传递值;如果是重定向方式,那么就只能用ServletContext域对象来setAttribute,因为其作用范围广,地址跳转,仍然能够存取数据;

1、重定向方式

case2Servlet

@WebServlet("/case2Servlet")public class case2Servlet extends HttpServlet {    @Override    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        resp.setContentType("text/html;charset=UTF-8");        ArrayList<User> users = Jdbc.selectDB();        //采用重定向方式        ServletContext servletContext = getServletContext();        servletContext.setAttribute("users",users);        resp.sendRedirect("http://localhost:8080/servlet/jsp/case2Jsp01.jsp");    }}

case2Jsp01.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>Title</title></head><body>    ${users}</body></html>

浏览器访问:

2、请求转发方式

JSP脚本

  • 声明脚本的格式:<%!声明java代码%>
  • 表达式脚本的格式:<%=表达式%>
  • 代码脚本的格式:<%java语句%>
<%@ page import="java.util.ArrayList" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><%--jsp代码脚本--%><%    String name="Tom";    Integer age=50;    Object o=new Object();    System.out.println(name+" "+age+" "+o);    for (int i=0;i<10;i++)        System.out.println(i);    ArrayList<Object> objects = new ArrayList<>();//会自动导包	ArrayList<User> users = new ArrayList<>();    users.add(new User(12,"jack1","123456"));    users.add(new User(12,"jack2","123456"));    users.add(new User(12,"jack3","123456"));    users.add(new User(12,"jack4","123456"));%><%--声明脚本--%><%!    private Integer i=5;%><html><head>    <title>test</title></head><body>    <%--表达式脚本--%>    <%=age%>    <%=name%>    <%=users.get(0).getUsername()%></body></html>

JSP九大内置对象:

JSP程序在执行的时候,底层会生成对应的源代码和字节码文件,在源代码中,会封装9大内置对象,包括字符流对象、异常对象、域对象

  1. request
  2. response
  3. pageContext
  4. exception
  5. application
  6. out
  7. page
  8. session
  9. servletConfig

JSP四大域对象:

域对象是都可以存取值的

  1. pageContext

    JSP内置的文本域对象,取值范围是当前的JSP页面,出了该页面的数据就无法访问

  2. request

    是一个请求域对象,取值范围是一次请求范围之类,浏览器只要地址不发生改变,则可以访问到数据

  3. session

    是一个会话域对象,取值范围是浏览器的开启到关闭,对应的生命周期也是浏览器的开启到关闭

  4. application

    实际上就是一个ServletContext对象,取值范围是整个web工程

下面根据代码的栗子来说明不同的取值范围:

  1. 首先在test04.jsp文件 JSP代码脚本各种域对象存放数据,然后在body部分进行取出数据

test04.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%--声明一个jsp脚本--%><%    //存放数据到域中    request.setAttribute("key1","value1");    request.setAttribute("key2","value2");    request.setAttribute("key3","value3");    pageContext.setAttribute("pageContext","pageContext");    request.setAttribute("request","request");    session.setAttribute("session","session");    application.setAttribute("application","application");%><html><head>    <title>test</title></head><body>    <%--用表达式脚本取出域中的数据--%>    <%=request.getAttribute("key1")%><br>    <%=request.getAttribute("key2")%><br>    <%=request.getAttribute("key3")%><br>    pageContext的value值为:<%=pageContext.getAttribute("pageContext")%><br>    request的value值为:<%=request.getAttribute("request")%><br>    session的value值为:<%=session.getAttribute("session")%><br>    application的value值为:<%=application.getAttribute("application")%><br></body></html>
  1. 浏览器端

​ 可以看到4个域对象现在都能访问到其中存取的数据

  1. 在同一工程下新建一个test05.jsp,用于取出域对象中的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>test</title></head><body>    pageContext的value值为:<%=request.getAttribute("pageContext")%><br>    request的value值为:<%=request.getAttribute("request")%><br>    session的value值为:<%=session.getAttribute("session")%><br>    application的value值为:<%=application.getAttribute("application")%><br></body></html>
  1. 浏览器端访问

​ 可以发现pageContext和request域对象的值已经获取不到了,因为pageContext的取值范围是当前JSP文件,request的取值范围是一次请求范围之内。访问的JSP文件改变,访问地址改变,明显超出了这两者的取值范围。

  1. 关闭浏览器,重新打开浏览器,再次访问test05.jsp页面

    可以发现session域对象的值也获取不到了,因为session域对象的取值范围是浏览器的开启到关闭。而application是一直可以获取到的,因为它的取值范围是整个web工程,只要web工程运行,就可以随时在任何地方都能访问到值。

JavaWeb 请求转发重定向的更多相关文章

  1. 20160326 javaweb 请求转发和请求包含

    (1)请求转发: this.getServletContext().getRequestDispatcher("").forward(request,response); requ ...

  2. JavaWeb中请求转发和请求重定向的区别

    针对于JavaWeb中请求与重定向的一个cheatsheep: 1.转发 1)完成一次转发,用户浏览器发送一次请求 2)转发之后,浏览器URL地址栏不改变(服务器帮忙完成) 3)请求域中数据不丢失 4 ...

  3. javaweb之Servlet,http协议以及请求转发和重定向

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 一直用的框架开发,快连Servlet都忘了,此文旨在帮自己和大家回忆一下Servlet主要知识点.话不多说开始吧 用idea构建Servlet项 ...

  4. Java 请求转发和重定向的区别以及JavaWeb三大作用域

    三大作用域以及转发和重定向 学习总结 1. 转发和重定向 转发 重定向 转发和重定向的区别: 什么时候用转发什么时候用重定向 三大作用域 作用域类型 作用域方法 如何选择作用域 总结 学习总结 1. ...

  5. javaweb中重定向和请求转发(response.sendRedirect()和request.getRequestDispatcher(rul).forward(request,response)))的区别

    先来两张图,方便理解: 可以看出,重定向时,是服务器向游览器重新发送了一个response命令,让游览器再次向url2发送请求,以获取url2的资源 而请求转发时,类似于是服务器自己向自己发了一个跳转 ...

  6. javaWeb中request请求转发和response重定向

    1.访问资源 运用forward方法只能重定向到同一个Web应用程序中的一个资源. 而sendRedirect方法可以让你重定向到任何URL.  2.request.get Forward代码中的&q ...

  7. ServletRequest HttpServletRequest 请求方法 获取请求参数 请求转发 请求包含 请求转发与重定向区别 获取请求头字段

      ServletRequest 基本概念 JavaWeb中的 "Request"对象  实际为   HttpServletRequest  或者  ServletRequest, ...

  8. HTTP协议基础与web服务的重定向,跳转以及请求转发

    JavaWeb中,HttpServletRequest与HttpServletResponse几乎是处理各种请求与操作必备的参数,与原始的ServletRequest/ServletResponse相 ...

  9. spring mvc 请求转发和重定向(转)

    spring mvc controller间跳转 重定向 传参 url:http://zghbwjl.blog.163.com/blog/static/12033667220137795252845/ ...

随机推荐

  1. Billu_b0x内网渗透-vulnhub

    个人博客:点我 本次来试玩一下vulnhub上的Billu_b0x,只有一个flag,下载地址. 下载下来后是 .ova 格式,建议使用vitualbox进行搭建,vmware可能存在兼容性问题.靶场 ...

  2. 【数学】快速傅里叶变换(FFT)

    快速傅里叶变换(FFT) FFT 是之前学的,现在过了比较久的时间,终于打算在回顾的时候系统地整理一篇笔记,有写错的部分请指出来啊 qwq. 卷积 卷积.旋积或褶积(英语:Convolution)是通 ...

  3. Beta实际开发与初始计划的比较

    零.说明 本篇博客为Beta阶段开始十天后,实际开发工作与初始计划的比较 截止至本篇博客发布为止,团队所有成员已完成计网考试,将在本周日进行充分的接口测试 一.比较 1.与初始计划对比 初始计划 实际 ...

  4. logstash处理多行日志-处理java堆栈日志

    logstash处理多行日志-处理java堆栈日志 一.背景 二.需求 三.实现思路 1.分析日志 2.实现,编写pipeline文件 四.注意事项 五.参考文档 一.背景 在我们的java程序中,经 ...

  5. rabbitmq死信队列和延时队列的使用

    死信队列&死信交换器:DLX 全称(Dead-Letter-Exchange),称之为死信交换器,当消息变成一个死信之后,如果这个消息所在的队列存在x-dead-letter-exchange ...

  6. Linux C语言链表详细分析

    链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用.链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节 ...

  7. Jenkins MultiJob

    前提:项目有十几个服务每次发版/更新服务需要一个个去编译 目的:希望能够建立一个任务一次构建可以批量编译很多服务,并且需要输入一个参数指定编译的分支 需要插件: MultiJob 安装插件 1.在Je ...

  8. CSP2020-儒略历

    大家可以在洛谷提交: 题目描述 为了简便计算,天文学家们使用儒略日(Julian day)来表达时间.所谓儒略日,其定义为从公元前 4713 年 1 月 1 日正午 12 点到此后某一时刻间所经过的天 ...

  9. 羽夏看Win系统内核——SourceInsight 配置 WRK

    写在前面   此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...

  10. 使用Netty和动态代理实现一个简单的RPC

    RPC(remote procedure call)远程过程调用 RPC是为了在分布式应用中,两台主机的Java进程进行通信,当A主机调用B主机的方法时,过程简洁,就像是调用自己进程里的方法一样.RP ...