一.Web之间跳转和信息共享
1.为什么需要Web组件之间跳转和信息共享
之前编写的Servlet都是相互独立的,彼此之间没有任何的交互.
我们在开发的时候,从A组件跳转到B组件,在跳转的过程中需要传递数据,供组件使用.
例子需求:从ListServlet中查询出所有的学生对象(List集合),跳转到JSP页面负责显示所有的学生信息,在学生信息的列表中点击删除操作之后,又重新回到学生列表界面.
2.Web组件之间跳转
在上述例子中,我们看到了Web组件(Servlet/JSP/Filter/Listener)之间需要协同完成任务,就需要跳转和数据共享.
Web组件之间的跳转,有三种方式:
- 方式1:请求转发(forward)
- 方式2:URL重定向(redirect)
- 方式3:请求包含(include):req.getRequestDispatcher("/include/s2").include(req, resp);
1).请求转发(forward):
语法:
request对象.getRequestDispatcher(String path).forward(request,response);
如:
request.getRequestDispatcher("/WEB-INF/views/list.jsp").forward(request, response);
参数:
path:资源路径,跳转目标的地址.
注意:一定要记得调用forward方法,如果没有调用,则不能跳转.
请求转发的特点:
- 1):请求转发的时候,浏览器地址栏不会改变依然是跳转之前的地址(不会显示目标地址).
- 2):请求转发只发送了一个请求,Servlet1和Servlet2共享请求(共享请求中的数据).
Servlet1和Servlet2之间可以在同一个请求中共享数据. - 3):最终给浏览器的响应有Servlet2来决定(如此:Servlet1没必要做响应).
- 4):请求转发只能访问当前应用的资源,不能跨域访问.
- 5):请求转发可以访问WEB-INF里面的资源.
2).URL重定向(redirect):
语法:
response对象.sendRedirect(String path);
参数:
path:资源路径,跳转目标的地址.
URL重定向的特点:
- 1):URL重定向的时候,浏览器地址栏发生改变,变成了目标的地址.
- 2):URL重定向发送了两个请求,Servlet1和Servlet2的请求不同.
因为Servlet1和Servlet2不共享同一个请求,所以也不共享请求中的数据. - 3):最终给浏览器的响应有Servlet2来决定(如此:Servlet1没必要做响应).
- 4):URL重定向支持跨域访问.
- 5):URL重定向不能访问WEB-INF里面的资源.
3).请求转发和URL重定向的区别?
- 1):解释什么是请求转发,URL重定向(操作代码).
- 2):罗列各自的特点.
- 3):特点罗列完毕之后,拿相同的特点做对比--->区别.
- 4):什么时候使用请求转发/URL重定向(特点不同,用途不同).
4).如何选择
什么时候使用forward:
- 1):需要共享同一个请求中的数据.
- 2):访问WEB-INF里面的资源文件.
什么时候使用redirect: - 1):当前应用需要跨域访问.
- 2):防止表单的重复提交.
其他时候,任选.
二.Servlet的三大作用域对象
1.Servlet的三大作用域对象
Web组件在跳转的时候可以共享数据(信息共享),Web组件信息共享必须依赖作用域对象.
我们是把共享的信息先存放在共享对象中再做传递,在目标里面从共享对象中获取数据.
Servlet1 ------------>作用域对象(数据)-----------> Servlet2
根据作用域的大小分成三种:
作用域对象名称 | 对象的类型 | 对象描述 |
---|---|---|
request | HttpServletRequest | 请求对象,每次新的请求都会创建新的request. |
session | HttpSession | 会话对象,每次打开新的浏览器,再访问(可以包含多个请求). |
servletContext(application) | ServletContext | 应用对象,描述了这一个Web应用(项目),启动Tomcat创建ServletContext对象,关闭Tomcat销毁该对象.(包含多次会话) |
作用域对象如何来共享数据(把数据存放到作用域,从作用域取出数据,修改/删除数据):
所有作用域对象的操作方法都是相同的:
- 设置共享数据: 作用域对象.setAttribute(String name,Object value)
- 获取共享数据: Object val = 作用域对象.getAttribute(String name);
- 删除共享数据: 作用域对象.removeAttribute(String name);
注意:从哪一个作用域中设置共享数据,就只能从该作用域中取出共享数据.
如果需要共享请求中的数据,只能使用请求转发(forward).
在request对象中:getParameter/getAttribute分不清:
String getParameter(String name):获取用户输入的参数.
Object getAttribute(String name):获取request中的共享数据,该共享数据是程序猿设置的(setAttribute).
2.servletcontext:ServletContext接口和常用方法
1).ServletContext接口,表示Servlet的上下文(环境).
ServletContext其实表示的就是当前应用对象,在一个应用中,有且只有一个ServletContext对象,我们习惯吧该对称application.
该对象在Tomcat启动的时候就创建,在关闭Tomcat的时候该对象被销毁.
可以被所有的Web组件共享数据.
2).如何获取ServletContext对象:
- 方式1:ServletContext ctx = request对象.getServletContext();(Tomcat7才支持)
- 方式2:ServletContext ctx = request对象.getSession().getServletContext();
- 方式3:在Servlet类中: :ServletContext ctx = super.getServletContext();
getServletContext方法是ServletConfig接口中的,而ServletConfig接口是HttpServlet类的父接口.
获取的ServletContext都是相同的.
3).常用方法:
1):String getContextPath():获取当前应用的上下文路径(<Context path="XXXX"/>)
和request.getContextPath是相同的.2):String getRealPath(String path):返回当前资源名称的真实路径(绝对路径).
3):之前讲解初始化参数,是在<servlet>元素中做的配置,如此一来,该初始化参数就只能当前Servlet使用.
如果有N个Servlet有相同的初始化参数配置,就得重复配置N次,很不爽,------>全局初始化参数.
全局初始化参数:可以供所有的Web组件共享,配置如下图图.
如何获取全局初始化:就只能使用ServletContext对象.getInitParameter(String name)
三.动态网页JSP
1.JSP为何而生
JSP:Java Server Page(Java的服务网页),也是Java的动态网页.
在之前讲过Java的另外一个动态网页技术:Servlet.
使用Servlet来开发动态网页:
动态网页 = Java代码为主 + html为辅;
这种开发: 网页开发成本大,维护性很低.
使用JSP来开发动态网页:
其本质就是html页面(代码),再加上 Java代码.
动态网页 = Java代码为辅 + html为主;
开发JSP:
- 1):设置JSP文件模板的编码:UTF-8.
- 2):JSP的运行必须依赖服务器,不能直接拖拽到浏览器.
- 3):改变了JSP文件的内容,不需要重启Tomcat,直接刷新网页即可.
2.JSP的原理
JSP的本质:其实就是一个Servlet.
JSP---->翻译成Servlet类---->编译成字节码文件--->解释执行了.
所有的以.jsp结尾的资源在请求Tomcat的时候,都会被JspServlet类所接受,该类就是把JSP文件翻译成一个个Servlet类.
翻译到Tomcat根/work/Catalina/localhost/_/org/apache/jsp/目录下.
JSP输出动态网页的原理:
其实就是在JSP翻译出来的Servlet类中,依然使用输出流向外输出一个html代码片段.
这和我们自己使用Servlet做动态网页是相同的.
帮我们屏蔽了,在Servlet类中编写恶心的html代码.
3.JSP基本语法
JSP语法:
1、JSP的注释:
作用:注释Java脚本代码
语法:<%--这是注释--%>,JSP的注释不会被翻译到Servlet代码中去.
2、JSP的Java脚本表达式:
作用:输出数据到页面上
语法:<%=表达式%>(实际上就是调用输出流打印到页面上) out.print(表达式);
3、JSP中的Java脚本片段:(实际开发中,应做到JSP中不能出现一行Java脚本片段)
作用:书写Java代码逻辑
语法:<%
Java代码
%>
原理:其中的语句会原封不动的被服务器翻译到对应的Servlet的_jspService方法中。
4、JSP的声明:
作用:定义类的成员
语法:<%!
Java代码
%>
原理:其中的语句会原封不动的被服务器翻译到对应的Servlet的类中,作为成员方法和变量。
4.JSP三大指令
1).标准指令:设定JSP网页的整体配置信息
特点:
1):并不向客户端产生任何输出,
2):指令在JSP整个文件范围内有效 (每一个JSP都得设置指令)
3):为翻译阶段提供了全局信息
2).JSP三大指令: page/include/taglib指令
格式:<%@ 指令名称 属性="属性值" %>
1.page
作用:定义JSP页面的各种属性
属性:
language:指示JSP页面中使用脚本语言。默认值java,目前只支持java。
extends:指示JSP对应的Servlet类的父类。不要修改。
*import:导入JSP中的Java脚本使用到的类或包。(如同Java中的import语句)
JSP引擎自动导入以下包中的类:
javax.servlet.*
javax.servlet.http.*
javax.servlet.jsp.*
注意:一个import属性可以导入多个包,用逗号分隔。
*sessioin:指示JSP页面是否创建HttpSession对象。默认值是true,创建
*buffer:指示JSP用的输出流的缓存大小.默认值是8Kb。
autoFlush:自动刷新输出流的缓存。
isThreadSafe:指示页面是否是线程安全的(过时的)。默认是true。
true:不安全的。
false:安全的。指示JSP对应的Servlet实现SingleThreadModel接口。
*errorPage:指示当前页面出错后转向(转发)的页面。
目标页面如果以"/"(当前应用)就是绝对路径。
配置全局错误提示页面:
web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
*isErrorPage:指示当前页面是否产生Exception对象。
*contentType:指定当前页面的MIME类型。作用与Servlet中的response.setContentType()作用完全一致
*pageEncoding:通知引擎读取JSP时采用的编码(因为要翻译)
还有contentType属性的作用。
*isELIgnored:是否忽略EL表达式。${1+1}。默认值是false。
page指令最简单的使用方式:<%@ page pageEncoding="UTF-8"%>
JSP的错误页面设置:
访问当前JSP的时候,出现错误(404找不到/500代码有问题),我们可以专门提供一个错误页面. 出错之后,就跳转到错误页面,显示错误信息.
上述的errorPage属性,每一个JSP都要设置.
我们可以在web.xml中统一的设置错误页面.
2.include(静态包含,开发中能用静的不用动的)
作用:包含其他的组件。
语法:<%@include file=""%>file指定要包含的目标组件。路径如果以"/"(当前应用)就是绝对路径。
原理:把目标组件的内容加到源组件中,输出结果。
动态包含:
采用动作元素:<jsp:include page=""/>路径如果以"/"(当前应用)就是绝对路径。
3.taglib
作用:引入外部的标签
语法:<%@taglib uri="标签名称空间" prefix="前缀"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
5.JSP九大内置对象和四大作用域对象
1).JSP的九大内置对象
JSP中预先定义好的九个Java对象.
查看:JSP翻译成Servlet代码之后,_jspService方法中的九个局部变量.
对象名称 | 对象类型 | 对象描述 |
---|---|---|
pageContext | PageContext | JSP的四大作用域对象:表示当前JSP页面的作用域. |
request | HttpServletRequest | JSP的四大作用域对象:表示每一个请求对象. |
session | HttpSession | JSP的四大作用域对象:表示一个会话对象. |
application | ServletContext | JSP的四大作用域对象:表示当前Web应用对象. |
response | HttpServletResponse | 响应对象. |
config | ServleConfig | 表示Servlet的配置信息对象. |
out | JspWriter | 表示字符输出流对象. |
page | Object | 表示当前JSP翻译成Servlet的对象. |
exeception | Throwable | 异常对象(必须给当前JSP设置为:isErrorPage="true") |
2).JSP的四大作用域对象:
对象名称 | 对象类型 | 对象描述 |
---|---|---|
pageContext | PageContext | JSP的四大作用域对象:表示当前JSP页面的作用域. |
request | HttpServletRequest | JSP的四大作用域对象:表示每一个请求对象. |
session | HttpSession | JSP的四大作用域对象:表示一个会话对象. |
application | ServletContext | JSP的四大作用域对象:表示当前Web应用对象. |
6.JSP常用的动作元素
1).JSP动作元素:
<jsp:include/>
<jsp:forward/>
<jsp:param/>:在包含和转发时,利用该标签传递请求参数
2).JSP的包含操作:
可以解决JSP代码重复的问题.
包含方式:
- 方式1:使用JSP的include指令,静态包含.
- 方式2:使用JSP的include动作元素,动态包含.
区别:
- 页面包含的时机不一样.
- 静态包含:在JSP翻译成Servlet的时候,就合并在一起,只生成一个Servlet类.
- 动态包含:有几个JSP文件就翻译成几个Servlet类,也编译成几个字节码文件.
在加载进JVM,动态合并在一起.
- 动态包含,可以给被包含的页面传递参数.
7.Servlet+JSP综合
四.小结
今日面试题:
1):说说请求转发和URL重定向的区别.
2):说说forward和redirect的区别.
3):说说Servlet的三大作用域对象.
4):说说什么是JSP,说说你对JSP的理解.
5):JSP的三大指令.
6):说说JSP的注释和HTML注释的区别.
7):JSP的九大内置对象.
8):JSP的四大作用域对象.
9):静态包含和动态包含的区别.