1.1 Servlet
1.1.1 什么是Servlet
Servlet是JavaWeb三大组件之一(Servlet、Filter、Listener)
Servlet是用来处理客户端请求的动态资源
Servlet的任务有:
获取请求数据
处理请求
完成响应
- Servlet接口方法:
servlet 中的方法大多数不由我们调用,而是由 tomcat 调用,并且 servlet 对象也不由我们创建,由 tomcat 创建
> void init(ServletConfig) 它会在servlet对象创建之后马上执行,并只执行一次
> void service(ServletRequest,ServletResponse) 它会被调用多次 , 每次处理请求都是在调用这个方法
> void destory() 它会在servlet被销毁之前调用,只会被调用一次 [留遗言]
以上三个方法都为生命周期方法
> ServletConfig getServletConfig() 用来获取 servlet 配置信息
> String getServletInfo() 获取 servlet 信息
1.1.2 实现Servlet的方式
实现Servlet接口(不方便)
继承GenericServlet类(不方便)
继承 HttpServlet 类(方便)
1.1.3 Servlet第一例
写一个类cn.itcast.MyServlet,实现Servlet接口
实现service()方法,在其中给出System.out.println("hello servlet!");
在web.xml文件中指定Servlet的访问路径为:/myservlet
<servlet>
<servlet-name>xxx</servlet-name>
<servlet-class>cn.itcast.MyServlet</servlet-class> 将路径和类绑在一起,此处为包名
</servlet>
<servlet-mapping>
<servlet-name>xxx</servlet-name>
<url-pattern>/myservlet</url-pattern> 此处为路径
</servlet-mapping>
注意!两处的 servlet-name 要一致
- servletConfig 方法&功能:servletConfig 是接口
当用户在地址栏中访问:http://localhost:8080/day04_1/myservlet时,会执行System.out.println("hello servlet!");
1). 服务器创建Servlet:
当 Servlet 第一次被请求时,或服务器启动时,服务器会创建 Servlet 实例。
- 服务器默认是在servlet第一次被请求时创建Servlet实例,如果希望服务器启动时就创建Servlet实现需要在web.xml中配置
服务器只为一个类型的 Servlet 创建一个实例对象,所以 Servlet 是单例的;
2). 服务器初始化Servlet:
当服务器创建Servlet实例后会马上调用Servlet的init(ServletConfig)方法,完成对Servlet的初始化;
init(ServletConfig)只会被调用一次
服务器会在调用init()方法时传递ServletConfig参数
3). 服务器使用Servlet处理请求:
当Servlet被请求时,服务器会调用Servlet的service(ServletRequest,ServletResponse)方法
service(ServletRequest,ServletResponse)方法每处理一次请求,就会被调用一次,所以它可能会被调用N次
因为 Servlet 是单例的,所以可能在同一时刻一个 Servlet 对象会被多个请求同时访问,所以这可能出现线程案例问题
Servlet 不是线程案例的,这有助与提高效率,但不能让 Servlet 具有状态,以免多个线程争抢数据
4). 服务器销毁Servlet
服务器通常不会销毁 Servlet ,通常只有在服务器关闭时才会销毁 Servlet
服务器会在销毁Servlet之前调用Servlet的destory()方法
可以在destory()方法中给出释放Servlet占有的资源,但通常Servlet是没什么可要释放的,所以该方法一般都是空的
1.1.4 ServletConfig
ServletConfig是Servlet中的init()方法的参数类型,服务器会在调用init()方法时传递ServletConfig对象给init()方法。
ServletConfig 对象封装了 Servlet 在 web.xml 中的配置信息,它对应 <servlet> 元素。
ServletConfig类的功能有:
String getServletName():获取 Servlet 配置名,即 <servlet-name> 的值;
ServletContext getServletContext():获取 ServletContext 对象
String getInitParameter(String name):获取初始化参数
Enumeration getInitParameterNames():获取所有初始化参数的名称
在web.xml文件中,配置<servlet>时可以为<servlet>配置0~N个初始化参数
1.1.5 GenericServlet
GenericServlet是Servlet接口的实现类,但它是一个抽象类,它唯一的抽象方法就是 service() 方法
GenericServlet实现了Servlet方法:
实现了String getServletInfo()方法
实现了void destory()方法,空实现
实现了void init(ServletConfig)方法,用来保存ServletConfig参数
实现了ServletConfig getServletConfig()方法
GenericServlet实现了ServletConfig接口:
实现了ServletContext getServletContext()方法
实现了String getInitParameter()方法
实现了String getServletName()方法
实现了Enumeration getInitParameterNames()方法
GenericServlet添加了init()方法:
该方法会被init(ServletConfig)方法调用
如果希望对Servlet进行初始化,那么应该覆盖init()方法,而不是init(ServletConfig)方法
service 方法中也可以使用 servletconfig 成员 , 只要在 init 方法之前就可以
不可贸然覆盖init方法,其中有config对象
可以覆盖init()无参函数
1.1.6 HttpServlet
HttpServlet是GenericServlet的子类,它专注HTTP请求
HttpServlet类的方法:
- 实现了void service(ServletRequest,ServletResponse)方法,实现内容是:
> 把ServletRequest强转成HttpServletRequest
> 把ServletResponse强转成HttpServletResponse
> 调用本类添加的void service(HttpServletRequest,HttpServletResponse)方法
- 添加了void service(HttpServletRequest,HttpServletResponse)方法,内容是:
> 调用request的getMethod()获取请求方式
> 如果请求方式为GET,那么调用本类添加的doGet(HttpServletRequest,HttpServletResponse)方法
> 如果请求方式为POST,那么调用本类添加的doPost(HttpServletRequest,HttpServletResponse)方法
添加了doGet(HttpServletRequest,HttpServletResponse)方法,内容是响应405,表示错误,所以我们应该去覆盖这个方法
添加了doPost(HttpServletRequest,HttpServletResponse)方法,内容是响应405,表示错误,所以我们应用去覆盖这个方法
如果是通过继承HttpServlet类来自定义Sevlet的话,那么:
不要去覆盖void service(ServletRequest,ServletResponse)
不要去覆盖void service(HttpServletRequest, HttpServletResponse)
而应该去覆盖doGet()或doPost()方法。
1.1.7 web.xml
servlet创建两种方式,
1.servlet第一次收到请求创建
2.服务器在启动时就创建
1.1.8 defaultServlet
default优先级最低,如果一个请求没有处理,那么它来处理,显示404
url-pattern 匹配的是 /
当访问路径不存在时,会执行defaultServlet,其实在访问index.html时也是在执行这个servlet
1.1.9 jspServlet
访问jsp页面时,会调用jspServlet,通过将动态资源转为静态资源,然后用response进行响应
1.1.10 session-config
session过期时间
1.2 MIME 多功能网际邮件扩充协议
多用途扩展类型,包含jpeg gif等,在这里定义了类型:
xml类型
txt类型
jpg/jpeg类型
doc类型
docx
1.2.1 什么是MIME-Type
首先,我们要了解浏览器是如何处理内容的。在浏览器中显示的内容有 HTML、有 XML、有 GIF、还有 Flash ……那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME Type,也就是该资源的媒体类型。
媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type 来表示的,
例如:Content-Type: text/HTML
表示内容是 text/HTML 类型,也就是超文本文件。为什么是“text/HTML”而不是“HTML/text”或者别的什么?MIME Type 不是个人指定的,是经过 ietf 组织协商,以 RFC 的形式作为建议的标准发布在网上的,大多数的 Web 服务器和用户代理都会支持这个规范 (顺便说一句,Email 附件的类型也是通过 MIME Type 指定的)。
通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的格式,一般只能以 application/x- 开头。
XHTML 正是一个获得广泛应用的格式,
因此,在 RFC 3236 中,说明了 XHTML 格式文件的 MIME Type 应该是application/xHTML+XML。
当然,处理本地的文件,在没有人告诉浏览器某个文件的 MIME Type 的情况下,浏览器也会做一些默认的处理,这可能和你在操作系统中给文件配置的 MIME Type 有关。
比如在 Windows 下,打开注册表的“HKEY_LOCAL_MACHINESOFTWAREClassesMIMEDatabaseContent Type”主键,你可以看到所有 MIME Type 的配置信息。
1.2.2 <url-pattern>
<url-pattern>是<servlet-mapping>的子元素,用来绑定Servlet的访问路径
可以在一个<servlet-mapping>中给出多个<url-pattern>,也就是说一个Servlet可以有多个访问路径:
<servlet-mapping>
<servlet-name>xxx</servlet-name>
<url-pattern>/helo1<url-pattern>
<url-pattern>/hello2<url-pattern>
</servlet-mapping>
还可以在<url-pattern>中使用通配符,即“*”。
<url-pattern>/*<url-pattern>:表示匹配任何路径
<url-pattern>/do/*<url-pattern>:表示匹配以/do开头的任何路径
<url-pattern>*.do<url-pattern>:表示匹配任何以“.do”结尾的路径
注意:
通配符要么在开头,要么在结尾,不能在中间,例如:/*.do就是错误的使用。
如果不使用通配符,那么<url-pattern>必须以“/”开头,例如:<url-pattern>abc</url-pattern>就是错误的
1.2.3 welcome-file-list
设置欢迎界面
1.3 ServletContext
ServletContext是Servlet三大域对象之一
ServletContext在服务器启动时创建,在服务器关闭时销毁,一个JavaWeb应用只创建一个ServletContext对象
一个项目只有一个ServletContext对象
1.3.1 ServletContext概述
服务器会为每个应用创建一个ServletContext对象:
ServletContext对象的创建是在服务器启动时完成的;
ServletContext对象的销毁是在服务器关闭时完成的。
ServletContext对象的作用是在整个Web应用的动态资源之间共享数据!例如在AServlet中向ServletContext对象中保存一个值,然后在BServlet中就可以获取这个值,这就是共享数据了。
不能用AServlet调用BServlet方法,会使耦合过紧
1.3.2 ServletContext的功能分类:
存取数据
读取web.xml中的应用初始化参数
读取应用资源
1.3.3 获取ServletContext对象
在HttpServlet中可以通过以下方法来获取ServletContext对象
ServletContext sc = this.getServletContext()
ServletContext sc = this.getServletConfig().getServletContext()
servletConfig.getServletContext(); 也可获取
HttpSession 也可获取
ServletContextEvent
在void init(ServletConfig config)中:
ServletContext context = config.getServletContext();
ServletConfig类的getServletContext()方法可以用来获取ServletContext对象;
在GenericeServlet或HttpServlet中获取ServletContext对象:
GenericServlet类有getServletContext()方法,所以可以直接使用this.getServletContext()来获取;
1.3.4 存取数据
因为在一个JavaWeb应用中,只有一个ServletContext对象,所以在ServletContext中保存的数据可以共整个JavaWeb应用中的动态资源共享
ServletContext是Servlet三大域对象之一,域对象内部有一个Map,用来保存数据
域对象的功能****(****用来在多个****servlet****中传递数据****)
ServletContext是JavaWeb四大域对象之一:
PageContext;
ServletRequest;
HttpSession;
ServletContext;
1. 存数据
- void setAttribute(String name, Object value):用来添加或替换ServletContext域数据
> servletContext.setAttribute("xxx", "XXX"),添加域数据
> servletContext.setAttribute("xxx", "XXXX"),覆盖域数据,因为在域中已经存在了名为xxx的数据,所以这次就是覆盖了
2. 取数据
Object getAttribute(String name):通过名称来获取域数据
void removeAttribute(String name):通过名称移除域数据
Enumeration<String> getAttributeNames():获取所有ServletContext域数据的名称
1.3.5 读取web.xml中配置的应用初始化参数
Servlet也可以获取初始化参数,但它是局部的参数;也就是说,一个Servlet只能获取自己的初始化参数,不能获取别人的,即初始化参数只为一个Servlet准备!
可以配置公共的初始化参数,为所有Servlet而用!这需要使用ServletContext才能使用!
<context-param>
<param-name>p1</param-name>
<param-value>v1</param-value>
</context-param>
<context-param>
<param-name>p2</param-name>
<param-value>v2</param-value>
</context-param>
servletContext.getInitParameter("p1"),返回v1
servletContext.getInitParameter("p2"),返回v2
servletContext.getInitParameterNames(),返回Enumeration<String>,包含p1和p2
1.3.6 获取项目资源
需要动态获取地址,引入
- String getRealPath(String path):获取资源的真实名称
String path = servletContext.getRealPath("/WEB-INF/a.jpg");
返回值为/WEB-INF/a.jpg真实路径,即磁盘路径:C:/tomcat6/wabapps/hello/WEB-INF/a.jpg
如:
- InputStream getResourceAsStream(String path):获取资源的输入流
InputStream in = servletContext.getResourceAsStream("/WEB-INF/a.jpg");
返回的是a.jpg的输入流对象,可以从流中得到a.jpg的数据
- Set<String> getResourcePaths(String path):获取指定目录下的所有资源路径
Set<String> paths = servletContext.getResourcePaths("/WEB-INF");
返回的Set中包含如下字符串:
> /WEB-INF/lib/
> /WEB-INF/classes/
> /WEB-INF/web.xml
> /WEB-INF/a.jpg
1.3.7 获取类路径资源
可以通过Class类的对象来获取类路径下的资源,对应JavaWeb应用的类路径就是classes目录下的资源
例如:
InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("a.jpg");
获取的是:/WEB-INF/classes/cn/itcast/servlet/a.jpg,即与MyServlet.class同目录下的资源
例如:
InputStream in = cn.itcast.servlet.MyServlet.class.getResourceAsStream("/a.jpg");
获取的是:/WEB-INF/classes/a.jpg,即类路径的根目录下的资源,类路径的根目录就是/classes目录
IOUtils 输入出流工具类,可以转换为字符串
练习:统计网站访问量
一个项目中所有的资源被访问都要对访问量进行累加!
创建一个int类型的变量,用来保存访问量,然后把它保存到ServletContext的域中,这样可以保存所有的Servlet都可以访问到!
最初时,ServletContext中没有保存访问量相关的属性;
当本站第一次被访问时,创建一个变量,设置其值为1;保存到ServletContext中;
当以后的访问时,就可以从ServletContext中获取这个变量,然后在其基础之上加1。
获取ServletContext对象,查看是否存在名为count的属性,如果存在,说明不是第一次访问,如果不存在,说明是第一次访问;
第一次访问:调用Servletcontext的setAttribute()传递一个属性,名为count,值为1;
第2~N次访问:调用ServletContext的getAttribute()方法获取原来的访问量,给访问量加1,再调用Servletcontext的setAttribute()方法完成设置。
1.3.8 参数(parameter)和属性(Attribute)的区别
区别:
- 来源不同:
参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中
提供的,若是POST方法是从请求体(request body)中提供的;
属性(attribute)是服务器端的组件(JSP或者Servlet)利用requst.setAttribute()设置的
- 操作不同:
参数(parameter)的值只能读取不能修改,读取可以使用request.getParameter()读取;
属性(attribute)的值既可以读取亦可以修改,读取可以使用request.setAttribute(),设置可使用request.getAttribute()
- 数据类型不同:
参数(parameter)不管前台传来的值语义是什么,在服务器获取时都以String类型看待,并且客户端的参数值只能是简单类型的值,不能是复杂类型,比如一个对象。
属性(attribute)的值可以是任意一个Object类型。
共同点
二者的值都被封装在request对象中。
1.4 Cookie
1.4.1 Http协议与Cookie(了解)
Cookie是HTTP****协议制定的!先由服务器保存Cookie到浏览器,再下次浏览器请求服务器时把上一次请求得到Cookie再归还给服务器
由服务器创建保存到客户端浏览器的一个键值对!服务器保存 Cookie 的响应头:Set-Cookie: aaa=AAA Set-Cookie: bbb=BBB
response.addHeader("Set-Cookie", "aaa=AAA");
response.addHeader("Set-Cookie", "bbb=BBB");
当浏览器请求服务器时,会把该服务器保存的Cookie随请求发送给服务器。浏览器归还 Cookie 的请求头:Cookie: aaa=AAA; bbb=BBB
Http协议规定(保证不给浏览器太大压力):
> 1 个 Cookie 最大 4KB
> 1 个服务器最多向 1 个浏览器保存 20 个 Cookie
> 1 个浏览器最多可以保存 300 个 Cookie
- 浏览器大战:因为浏览器竞争很激烈,所以很多浏览器都会在一定范围内违反HTTP规定,但也不会让一个Cookie为4GB!
1.4.2 Cookie的用途
服务器使用Cookie来跟踪客户端状态!
保存购物车(购物车中的商品不能使用request保存,因为它是一个用户向服务器发送的多个请求信息)
显示上次登录名(也是一个用户多个请求)
********** Cookie 是不能跨浏览器的! ***********
1.4.3 JavaWeb中使用Cookie
-
原始方式(了解):
> 使用response发送Set-Cookie响应头
> 使用request获取Cookie请求头
- 便捷方式(精通):
> 使用repsonse.addCookie()方法向浏览器保存Cookie
> 使用request.getCookies()方法获取浏览器归还的Cookie(* 判断 null) *
Cookie第一例:
> 一个jsp保存cookie, a.jsp
> 另一个jsp获取浏览器归还的cookie! b.jsp
1.4.4 Cookie详解
Cookie不只有name和value两个属性
Cookie的maxAge(掌握):Cookie的最大生命,即Cookie可保存的最大时长。以秒为单位,例如:cookie.setMaxAge(60)表示这个Cookie会被浏览器保存到硬盘上60秒
> maxAge>0:浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值决定。
> maxAge<0:Cookie只在浏览器内存中存在,当用户关闭浏览器时,浏览器进程结束,同时Cookie也就死亡了。
> maxAge=0:浏览器会马上删除这个Cookie!
- Cookie的path(理解):
> Cookie的path并不是设置这个Cookie在客户端的保存路径!!!
> Cookie的path由服务器创建Cookie时设置
> 当浏览器访问服务器某个路径时,需要归还哪些Cookie给服务器呢?这由Cookie的path决定。
> 浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会归还这个Cookie。
例如:
<> aCookie.path=/day11_1/; bCookie.path=/day11_1/jsps/; cCookie.path=/day11_1/jsps/cookie/;
<> 访问:/day11_1/index.jsp时,归还:aCookie
<> 访问:/day11_1/jsps/a.jsp时,归还:aCookie、bCookie
<> 访问:/day11_1/jsps/cookie/b.jsp时,归还:aCookie、bCookie、cCookie
Cookie的path默认值:当前访问路径的父路径。例如在访问/day11_1/jsps/a.jsp时,响应的cookie,那么这个cookie的默认path为/day11_1/jsps/
- Cookie的domain(了解)
> domain用来指定Cookie的域名!当多个二级域中共享Cookie时才有用。
> 例如;www.baidu.com、zhidao.baidu.com、news.baidu.com、tieba.baidu.com之间共享Cookie时可以使用domain
> 设置domain为:cookie.setDomain(".baidu.com");
> 设置path为:cookie.setPath("/");
Cookie中不能存在中文!!!
// 保存
Cookie c = new Cookie("username", URLEncoder.encode("张三", "utf-8"));//出错!
response.addCookie(c);
// 获取
Cookie[] cs = request.getCookies();
if(cs != null) {
for(Cookie c : cs){
if("username".equals(c.getName())) {
String username = c.getValue();
username = URLDecoder.decode(username, "utf-8");
}
}
}
============================================
1.5 HttpSession
1.5.1 HttpSession概述
HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
HttpSession是Servlet三大域对象之一(request、session、application(ServletContext)),所以它也有setAttribute()、getAttribute()、removeAttribute()方法
HttpSession底层依赖Cookie,或是URL重写!
1.5.2 HttpSession的作用
- 会话范围:会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
会话:一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器!
- 服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存!
Servlet中得到session对象:HttpSession session = request.getSession();
Jsp中得到session对象:session是jsp内置对象之下,不用创建就可以直接使用!
- session域相关方法:
> void setAttribute(String name, Object value);
> Object getAttribute(String name);
> void removeAttribute(String name);
1.5.3 HttpSession原理(理解)
- request.getSession()方法:
> 获取Cookie中的JSESSIONID:
<> 如果sessionId不存在,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
<> 如果sessionId存在,通过sessionId查找session对象,如果没有查找到,创建session,把session保存起来,把新创建的sessionId保存到Cookie中
<> 如果sessionId存在,通过sessionId查找到了session对象,那么就不会再创建session对象了。
<> 返回session
如果创建了新的session,浏览器会得到一个包含了sessionId的Cookie,这个Cookie的生命为-1,即只在浏览器内存中存在,如果不关闭浏览器,那么Cookie就一直存在。
下次请求时,再次执行request.getSession()方法时,因为可以通过Cookie中的sessionId找到session对象,所以与上一次请求使用的是同一session对象。
服务器不会马上给你创建session,在第一次获取session时,才会创建!request.getSession();
request.getSession(false)、request.getSession(true)、request.getSession(),后两个方法效果相同,
第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象。
1.5.4 HttpSession其他方法:
String getId():获取sessionId;
int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
1.5.5 web.xml中配置session的最大不活动时间
<session-config>
<session-timeout>30</session-timeout>
</session-config>
1.5.6 案例1:演示session中会话的多次请求中共享数据
AServlet:向session域中保存数据
BServlet:从session域中获取数据
演示:
> 第一个请求:访问AServlet
> 第二个请求:访问BServlet
1.5.7 案例2:演示保存用户登录信息(精通)
- 案例相关页面和Servlet:
> login.jsp:登录页面
> succ1.jsp:只有登录成功才能访问的页面
> succ2.jsp:只有登录成功才能访问的页面
> LoginServlet:校验用户是否登录成功!
- 各页面和Servlet内容:
> login.jsp:提供登录表单,提交表单请求LoginServlet
> LoginServlet:获取请求参数,校验用户是否登录成功
<> 失败:保存错误信息到request域,转发到login.jsp(login.jsp显示request域中的错误信息)
<> 成功:保存用户信息到session域中,重定向到succ1.jsp页面,显示session域中的用户信息
> succ1.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息
> succ2.jsp:从session域获取用户信息,如果不存在,显示“您还没有登录”。存在则显示用户信息
只要用户没有关闭浏览器,session就一直存在,那么保存在session中的用户信息也就一起存在!那么用户访问succ1和succ2就会通过!
1.6 JSP
1.6.1 JSP三大指令
一个jsp页面中,可以有0~N个指令的定义!
- page --> 最复杂:%@page language="java" info="xxx"...%
- pageEncoding和contentType:
> pageEncoding:它指定当前jsp页面的编码,只要不说谎,就不会有乱码!在服务器要把jsp编译成.java时需要使用pageEncoding!
> contentType:它表示添加一个响应头:Content-Type!等同与response.setContentType("text/html;charset=utf-8");
> 如果两个属性只提供一个,那么另一个的默认值为设置那一个。
> 如果两个属性都没有设置,那么默认为iso
import:导包!可以出现多次
errorPage和isErrorPage
> errorPage:当前页面如果抛出异常,那么要转发到哪一个页面,由errorPage来指定
> isErrorPage:它指定当前页面是否为处理错误的页面!当该属性为true时,这个页面会设置状态码为500!而且这个页面可以使用9大内置对象中的exception!
<error-page>
<error-code>404</error-code>
<location>/error/errorPage.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/errorPage.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/index.jsp</location>
</error-page>
- autoFlush和buffer
autoFlush:指定jsp的输出流缓冲区满时,是否自动刷新!默认为true,如果为false,那么在缓冲区满时抛出异常!
buffer:指定缓冲区大小,默认为8kb,通常不需要修改!
isELIgnored:是否忽略el表达式,默认值为false,不忽略,即支持!
基本没有:
language:指定当前jsp编译后的语言类型,默认值为java。
info:信息!
isThreadSafe:当前的jsp是否支持并发访问!
session:当前页面是否支持session,如果为false,那么当前页面就没有session这个内置对象!
extends:让jsp生成的servlet去继承该属性指定的类!
- include --> 静态包含
与RequestDispatcher的include()方法的功能相似!
<%@include%> 它是在jsp编译成java文件时完成的!他们共同生成一个java(就是一个servlet)文件,然后再生成一个class!
RequestDispatcher的include()是一个方法,包含和被包含的是两个servlet,即两个.class!他们只是把响应的内容在运行时合并了!
作用:把页面分解了,使用包含的方式组合在一起,这样一个页面中不变的部分,就是一个独立jsp,而我们只需要处理变化的页面。
- taglib --> 导入标签库
- 两个属性:
prefix:指定标签库在本页面中的前缀!由我们自己来起名称!
uri: 指定标签库的位置!
<%@taglib prefix="s" uri="/struts-tags"%> 前缀的用法<s:text>
=========================================
1.6.2 JSP九大内置对象
out --> jsp的输出流,用来向客户端响应
page --> 当前jsp对象! 它的引用类型是Object,即真身中有如下代码:Object page = this;
config --> 它对应真身中的ServletConfig对象!
pageContext --> 一个顶9个!
request --> HttpServletRequest
response --> HttpServletResponse
exception --> Throwable
session --> HttpSession
application --> ServletContext
- pageContext
一个顶9个!
Servlet中有三大域,而JSP中有四大域,它就是最后一个域对象!
ServletContext:整个应用程序
session:整个会话(一个会话中只有一个用户)
request:一个请求链!
pageContext:一个jsp页面!这个域是在当前jsp页面和当前jsp页面中使用的标签之间共享数据!
域对象
代理其他域:pageContext.setAttribute("xxx", "XXX", PageContext.SESSION_SCOPE);
全域查找:pageContext.findAttribute("xxx");从小到大,依赖查找!
获取其他8个内置对象:
=========================================
1.6.3 JSP动作标签
这些jsp的动作标签,与html提供的标签有本质的区别。
* 动作标签是由tomcat(服务器)来解释执行!它与java代码一样,都是在服务器端执行的!
* html由浏览器来执行!
<jsp:forward>:转发!它与RequestDispatcher的forward方法是一样的,一个是在Servlet中使用,一个是在jsp中使用!
<jsp:include>:包含:它与RequestDispatcher的include方法是一样的,一个是在Servlet中使用,一个是在jsp中使用!
%@include和<jsp:include>有什么不同!
- <jsp:param>:它用来作为forward和include的子标签!用来给转发或包含的页面传递参数!
=========================================
1.7 JavaBean
1.7.1 JavaBean的规范:
必须要有一个默认构造器
提供get/set方法,如果只有get方法,那么这个属性是只读属性!
属性:有get/set方法的成员,还可以没有成员,只有get/set方法。属性名称由get/set方法来决定!而不是成员名称!
方法名称满足一定的规范,那么它就是属性!boolean类型的属性,它的读方法可以是is开头,也可以是get开头!
1.7.2 内省:
内省类 --> Bean信息 --> 属性描述符 --> 属性的get/set对应的Method! --- > 可以反射了!
commons-beanutils,它是依赖内省完成!
- 导包:
commons-beanutils.jar
commons-logging.jar
BeanUtils.getProperty(Object bean, String propertyName)
BeanUtils.setProperty(Object bean, String propertyName, String propertyValue)
BeanUtils.populate(Map map, Object bean)
CommontUtils.toBean(Map map, Class class)
注意导包的时候后面写.*
1.7.3 javaBean导航
<%
Address address = new Address();
address.setCity("北京");
address.setStreet("西三旗");
Employee emp = new Employee();
emp.setName("李小四");
emp.setSalary(123456);
emp.setAddress(address);
request.setAttribute("emp", emp);
%>
1.7.4 jsp中与javaBean相关的标签
<jsp:useBean>
--> 创建或查询 bean<jsp:useBean id="user1" class="cn.itcast.domain.User" scope="session"/>
在 session 域中查找名为user1的bean,如果不存在,创建之<jsp:useBean id="user1" class="cn.itcast.domain.User" scope="session"/>
创建<jsp:useBean id="user1" class="cn.itcast.domain.User" scope="session"/>
查找<jsp:setProperty>
›4<jsp:setProperty property="username" na=me="user1" value="admin"/>
设置名为user1的这个javabean的username属性值为admin<jsp:getProperty>
<jsp:getProperty property="username" name="user1"/>
获取名为user1的javabean的名为username属性值
=========================================
1.8 EL表达式
1.8.1 EL基本概念
EL是JSP内置的表达式语言!
jsp2.0开始,不让再使用java脚本,而是使用el表达式和动态标签来替代java脚本!
EL替代的是<%= ... %>,也就是说,EL只能做输出!
1.8.2 EL表达式读取四大域
- ${xxx} ,全域查找名为 xxx 的属性,如果不存在,输出空字符串,而不是 null。
* ${pageScope.xxx}、${requestScope.xxx}、${sessionScope.xxx}、${applicationScope.xxx},指定域获取属性!
<h3>使用el获取request域的emp</h3>
${requestScope.emp.address.street }<!-- request.getAttribute("emp").getAddress().getStreet() --><br/>
1.8.3 EL表达式与内置对象
EL可以输出的东西都在11个内置对象中!11个内置对象,其中10个是Map!pageContext不是map,它就是PageContext类型,1个项9个。
我们已经学习了四个
param:对应参数,它是一个Map,其中key参数名,value是参数值,适用于单值的参数。
paramValues:对应参数,它是一个Map,其中key参数名,value是多个参数值,适用于多值的参数。
header:对应请求头,它是一个Map,其中key表示头名称,value是单个头值,适用于单值请求头
headerValues:对应请求头,它是一个Map,其中key表示头名称,value是多个头值,适用于多值请求头
initParam:获取<context-param>内的参数!
<context-param>
<param-name>xxx</param-name>
<param-value>XXX</param-value>
</context-param>
<context-param>
<param-name>yyy</param-name>
<param-value>YYY</param-value>
</context-param>
${initParam.xxx}
cookie:Map<String,Cookie>类型,其中key是cookie的name,value是cookie对象。 ${cookie.username.value}
pageContext:它是PageContext类型!${pageContext.request.contextPath}
=========================================
1.8.4 EL函数库(由JSTL提供的)
- 导入标签库:
<%@ tablib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
String toUpperCase(String input):把参数转换成大写
String toLowerCase(String input):把参数转换成小写
int indexOf(String input, String substring):从大串,输出小串的位置!
boolean contains(String input, String substring):查看大串中是否包含小串
boolean containsIgnoreCase(String input, String substring):忽略大小写的,是否包含
boolean startsWith(String input, String substring):是否以小串为前缀
boolean endsWith(String input, String substring):是否以小串为后缀
String substring(String input, int beginIndex, int endIndex):截取子串
String substringAfter(String input, String substring):获取大串中,小串所在位置后面的字符串
substringBefore(String input, String substring):获取大串中,小串所在位置前面的字符串
String escapeXml(String input):把input中“<”、">"、"&"、"'"、""",进行转义
String trim(String input):去除前后空格
String replace(String input, String substringBefore, String substringAfter):替换
String[] split(String input, String delimiters):分割字符串,得到字符串数组
int length(Object obj):可以获取字符串、数组、各种集合的长度!
String join(String array[], String separator):联合字符串数组!
=========================================
1.8.5 EL自定义函数库
写一个java类,类中可以定义0~N个方法,但必须是static,而且有返回值的!
在WEB-INF目录下创建一个tld文件
<function>
<name>fun</name>
<function-class>cn.itcast.fn.MyFunction</function-class>
<function-signature>java.lang.String fun()</function-signature>
</function>
- 在jsp页面中导入标签库
<%@ taglib prefix="it" uri="/WEB-INF/tlds/itcast.tld" %>
- 在jsp页面中使用自定义的函数:
${it:fun() }