JavaWeb-jsp、session、cookie

主要内容:

  1. JSP基础
  2. Cookie
  3. HttpSession

================================

JSP基础

  1. jsp的作用:
  • Servlet:

    缺点:不适合设置html响应体,需要大量的response.getWriter().print("")
    优点:动态资源,可以编程。

  • html:

    缺点:html是静态页面,不能包含动态信息
    优点:不用为输出html标签而发愁

  • jsp(java server pages):

    优点:在原有html的基础上添加java脚本,构成jsp页面。

  1. jsp和Servlet的分工:
  • JSP:

    作为请求发起页面,例如显示表单、超链接。
    作为请求结束页面,例如显示数据。

  • Servlet:

    作为请求中处理数据的环节。

  1. jsp的组成
  • jsp = html + java脚本 + jsp标签(指令)

  • jsp中无需创建即可使用的对象一共有9个,被称之为9大内置对象。例如:request对象、out对象

  • 3种java脚本:

    <%…%>:java代码片段(常用),用于定义0~N条Java语句!方法内能写什么,它就可以放什么!
    <%=…%>:java表达式,用于输出(常用),用于输出一条表达式(或变量)的结果。response.getWriter().print( … );这里能放什么,它就可以放什么!
    <%!..%>:声明,用来创建类的成员变量和成员方法(基本不用,但容易被考到),类体中可以放什么,它就可以放什么!

    案例:演示jsp中java脚本的使用!
    案例:演示jsp与servlet分工!

  1. jsp原理(理解)
  • jsp其实是一种特殊的Servlet

    当jsp页面第一次被访问时,服务器会把jsp编译成java文件(这个java其实是一个servlet类)
    然后再把java编译成.class
    然后创建该类对象
    最后调用它的service()方法
    第二次请求同一jsp时,直接调用service()方法。

  • 在tomcat的work目录下可以找到jsp对应的.java源代码。
  • 查看jsp对应java文件:

    java脚本
    html

  1. jsp注释
  • <%-- … --%>:当服务器把jsp编译成java文件时已经忽略了注释部分!
:html注释

=================================

Cookie

  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. Cookie的用途
  • 服务器使用Cookie来跟踪客户端状态!
  • 保存购物车(购物车中的商品不能使用request保存,因为它是一个用户向服务器发送的多个请求信息)
  • 显示上次登录名(也是一个用户多个请求)

Cookie是不能跨浏览器的!*

  1. JavaWeb中使用Cookie
  • 原始方式(了解):

    使用response发送Set-Cookie响应头
    使用request获取Cookie请求头

  • 便捷方式(精通):

    使用repsonse.addCookie()方法向浏览器保存Cookie
    使用request.getCookies()方法获取浏览器归还的Cookie

Cookie第一例:
> 一个jsp保存cookie, a.jsp
> 另一个jsp获取浏览器归还的cookie! b.jsp

  1. 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©;

// 获取
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”);
}
}
}

============================================

HttpSession(*****)

  1. HttpSession概述
  • HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
  • HttpSession是Servlet三大域对象之一(request、session、application(ServletContext)),所以它也有setAttribute()、getAttribute()、removeAttribute()方法
  • HttpSession底层依赖Cookie,或是URL重写!
  1. 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. 案例1:演示session中会话的多次请求中共享数据
  • AServlet:向session域中保存数据
  • BServlet:从session域中获取数据
  • 演示:

    第一个请求:访问AServlet
    第二个请求:访问BServlet

  1. 案例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. 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. 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. web.xml中配置session的最大不活动时间

    30

  2. URL重写(理解)

就是把所有的页面中的路径,都使用response.encodeURL("…")处理一下!

  • session依赖Cookie,目的是让客户端发出请求时归还sessionId,这样才能找到对应的session
  • 如果客户端禁用了Cookie,那么就无法得到sessionId,那么session也就无用了!
  • 也可以使用URL重写来替代Cookie

    让网站的所有超链接、表单中都添加一个特殊的请求参数,即sessionId
    这样服务器可以通过获取请求参数得到sessionId,从而找到session对象。

  • response.encodeURL(String url)

    该方法会对url进行智能的重写:当请求中没有归还sessionid这个cookie,那么该方法会重写url,否则不重写!当然url必须是指向本站的url。

  1. 一次性图形验证码
  • 编写VerifyCode,用来生成一次图形验证码
  • 编写VerfiyServlet:

    使用VerfiyCode来生成图形验证码
    把文本保存到session中
    把图片响应给客户。

  • 在login.jsp页面中

    元素请求VerfiyServlet,页面中显示图形验证码
    表单给出用户输入的验证码

  • 在LoginServlet中

    获取用户输入的验证码,请求参数!!!
    获取session中保存的真正的验证码文本,这是在打开login.jsp时已经保存到session中的
    比较用户输入的验证码与session中真正的验证码

JSP

  1. 什么是JSP
    JSP即java server pages,它是JavaWeb的动态资源。
    JSP = html + java脚本 + jsp动作标签(包含EL表达式)

  2. JSP中java脚本

  • <% … %>:代码段,Java语句
  • <%= … %>:表达式,只是表达式!表达式的值会被输出到客户端
  • <%! … %>:定义,定义成员!例如例如成员变量,方法等

<%
int a = 10;//定义变量
%>
<%
out.println(a);//输出变量
%>
<%=a%>//输出变量
<%!
private String hello = “world”;
public String sayHello() {
return hello;
}
%>
<%=sayHello()%>


  1. JSP真身
  • JSP也是Servlet
  • JSP会在第一次被请求时编码成.java,再编码成.class文件,它其实就是一个Servlet,在处理请求时执行service()方法。

查看真身可以得到,jsp中有9个对象可以无需创建即可使用,它们就是jsp九大内置对象。


  1. JSP注释
  • ,html注释,不是JSP注释,它会出现在JSP的真身中,并发送到客户端,但客户端浏览器不会显示它。
  • <%-- --%>,JSP注释,它不会出现在JSP真身中,也就不可能发送到客户端浏览器了。

================================

================================

会话跟踪

  1. 什么是会话
  • 用户拨打10086,从服务台接通后会话开始;
  • 用户发出话费查询请求,服务台响应。这是该会话中的一个请求;
  • 用户发出套餐变更请求,服务台响应。这是该会话中的又一个请求;
  • 用户挂断电话,会话结束。
  1. 会话的特性
  • 一个会话中可能包含多个请求;
  • 一个会话中发出请求的用户是唯一的;
  1. JavaWeb会话
  • 从用户打开本站第一个页面开始,会话也开始了;
  • 用户会发出0~n个请求;
  • 用户关闭浏览器会话结束了。
  1. 什么是会话跟踪技术
    HTTP是无状态协议,也就是没有记忆力的协议,每个请求之间无法共享数据。这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。这说明需要使用额外的手段来跟踪会话!
  • 在一个会话中共享数据即会话跟踪技术

Cookie

  1. 什么是Cookie
  • Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据。
  • 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来。
  • 当客户端再次请求同一服务器时,客户端会在请求头中添加该服务器保存的Cookie,发送给服务器。
  • Cookie就是服务器保存在客户端的数据!
  • Cookie就是一个键值对!!!
  1. Cookie规范
  • Cookie通过请求头和响应头在服务器与客户端之间传输;
  • Cookie大小限制在4KB之内;
  • 一台服务器在一个客户端最多保存20个Cookie;
  • 一个浏览器最多可以保存300个Cookie;

虽然Cookie规范是如此,但在今天,浏览器厂商的竞争异常激烈,所以多少会超出Cookie规则的限制。但也不会超出过多!

  1. Cookie与请求头和响应头
  • 服务器向客户端发送Cookie的响应头为Set-Cookie,例如:Set-Cookie:cookiename=cookievalue
  • 客户端向服务器发送Cookie的请求头为Cookie,例如:Cookie:cookiename=cookievalue
  1. Servlet中向客户端发送Cookie
    Cookie cookie1 = new Cookie(“test1”, “abcdefg”);
    Cookie cookie2 = new Cookie(“test2”, “ABCDEFG”);
    response.addCookie(cookie1);
    response.addCookie(cookie2);

  2. Servlet中获取客户端发送过来的Cookie

Cookie[] cs = request.getCookies();
if(cs != null) {
for(Cookie c : cs) {
System.out.println(c.getName() + “=” + c.getValue());
}
}

=============================

Cookie的细节

  1. Cookie的maxAge
    当服务器创建Cookie对象后,可以调用setMaxAge()方法设置Cookie的最大生命。
  • maxAge > 0:表示Cookie在客户端硬盘上保存的最大时间,单位为秒;
  • maxAge < 0:表示Cookie不会被浏览器保存到硬盘上,而只在浏览器内存中存活,一旦客户端关闭浏览器在,那么Cookie就消失;
  • maxAge == 0:表示删除Cookie,例如客户端硬盘已经存在名为abc的Cookie,如果服务器再向客户端发送名为abc,并且maxAge为0的Cookie,那么表示删除客户端上的名为abc的Cookie。
  1. Cookie的path
    浏览器在访问BServlet时,是否要带上AServlet保存的Cookie呢?这要看Cookie的path了。
    现有资源如下:
  • http://localhost:8080/day06_2/servlet/AServlet
  • http://localhost:8080/day06_2/servlet/BServlet,保存名为xxx的Cookie
  • http://loclahost:8080/day06_2/servlet/CServlet,保存名为yyy的Cookie
  • http://loclahost:8080/day06_2/servlet/user/DServlet, 保存名为zzz的Cookie

// 没有设置Cookie的path
AServlet {
Cookie c = new Cookie(“xxx”, “XXX”);
response.addCookie©;
}
// 设置了Cookie的path为/day06_2
CServlet {
Cookie c = new Cookie(“yyy”, “YYY”);
c.setPath="/day06_2";
response.addCookie©;
}
DServlet {
Cookie c = new Cookie(“zzz”, “ZZZ”);
resposne.addCookie©;
}

在BServlet中保存的Cookie没有设置path,那么它的path默认为当前BServlet的所在路径,即“/day06_2/servlet”。
在CServlet中保存的Cookie设置了path为/day06_2。
在DServlet中保存的Cookie没有设置path,那么它的path默认为DServlet的所在路径,即“day06_2/servlet/user”

当访问AServlet时,是否要带上xxx这个Cookie呢?因为AServlet的访问路径为/day06_2/servlet/BServlet,它包含了xxx的path,即/day06_2/servlet,所以需要带上。

当访问AServlet时,是否要带上yyy这个Cookie呢?因为AServlet的访问路径为/day06_2/servlet/BServlet,它包含了xxx的path,即/day06_2,所以需要带上。

当访问AServlet时,是否要带上zzz这个Cookie呢?因为AServlet的访问路径为/day06_2/servlet/BServlet,它不包含zzz的path,即/day06_2/servlet/user,所以不会带上。

  1. Cookie的domain
    Cookie的path是在同一主机中指定共享Cookie,如果主机不同那么就一定不能共享Cookie,无论path是什么。
    如果希望不同的二级域名中可以共享Cookie,那么就要设置Cookie的domain了。
    例如:news.baidu.com、tieba.baidu.com、zhidao.baidu.com,它们的域名不同,但百度希望它们之间可以共享Cookie,那么就要设置domain了。

1). 设置Cookie的path为“/”,例如:cookie.setPath("/");
2). 设置Cookie的domain,例如:cookie.setDomain(".baidu.com"),其中domain中没有指定域名前缀!

在news.baidu.com主机中的某个项目中保存了Cookie
在tieba.baidu.com主机中某个项目中获取Cookie

当然这需要配置两个虚拟主机才行。

  1. Cookie保存中文
    Cookie的name和value都是不能保存中文的,但可以先把中文转换成URL编码,然后在保存到Cookie的name和value中。
    String name = “姓名”;
    String value = “张三”;
    name = URLEncoder.encode(name, “utf-8”);
    value = URLEncoder.encode(value, “utf-8”);

Cookie c = new Cookie(name, value);
response.addCookie©;

在获取Cookie时,再使用URL解码即可。
Cookie[] cs = request.getCookies();
if(cs != null) {
for(Cookie c : cs) {
String name = URLDecoder.decode(c.getName(), “utf-8”);
String value = URLDecoder.decode(c.getValue(), “utf-8”);
System.out.println(name + “=” + value);
}
}

=============================

=============================

HttpSession

在JavaWeb中提供了HttpSession类,用来表示http会话。

  1. 获取HttpSession
    HttpSession session = request.getSession();
    HttpSession session = request.getSession(false);

  2. 域功能
    session是域对象,所以有setAttribute()和getAttribute()等方法
    服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。

  3. 登录案例
    请求功能:

  4. 如果登录功能,在session中保存user对象

  5. 访问index1.jsp,查看session中是否存在user对象,如果存在,说明已经登录过。

  6. 访问index2.jsp,查看session中是否存在user对象,如果存在,说明已经登录过。
    如果关闭了浏览器,那么会话结束,再打开浏览器就开始了一个新会话,那么直接访问index1.jsp或index2.jsp时,session是新的,没有保存user对象,那么表示还没有登录。

  7. session的原理
    session是依赖Cookie实现的。
    session是服务器端对象
    当用户第一次使用session时(表示第一次请求服务器),服务器会创建session,并创建一个Cookie,在Cookie中保存了session的id,发送给客户端。这样客户端就有了自己session的id了。但这个Cookie只在浏览器内存中存在,也就是说,在关闭浏览器窗口后,Cookie就会丢失,也就丢失了sessionId。
    当用户第二次访问服务器时,会在请求中把保存了sessionId的Cookie发送给服务器,服务器通过sessionId查找session对象,然后给使用。也就是说,只要浏览器容器不关闭,无论访问服务器多少次,使用的都是同一个session对象。这样也就可以让多个请求共享同一个session了。
    当用户关闭了浏览器窗口后,再打开浏览器访问服务器,这时请求中没有了sessionId,那么服务器会创建一个session,再把sessionId通过Cookie保存到浏览器中,也是一个新的会话开始了。原来的session会因为长时间无法访问而失效。
    当用户打开某个服务器页面长时间没动作时,这样session会超时失效,当用户再有活动时,服务器通过用户提供的sessionId已经找不到session对象了,那么服务器还是会创建一个新的session对象,再把新的sessionId保存到客户端。这也是一个新的会话开始了。

设置session超时时间
web.xml文件中配置如下:

30

  1. session与浏览器
    session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
    因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。也就是说,使用IE登录后,再使用FireFox访问服务器还是没有登录的状态。

而且同时打开多个相同浏览器的窗口,是在使用同一session。如果你使用的是老浏览器,例如IE6,那么就会每个窗口一个session。

  1. session的API
  • String getId():获取sessionId;
  • int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
  • void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
  • long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
  • long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
  • void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
  • boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。
  1. URL重写
    session依赖Cookie,这是因为服务器需要把sessionId保存到客户端。如果用户的浏览器关闭了Cookie功能,那么session不能使用了!
    还可以在浏览器关闭了Cookie后使用URL重写的方法保存sessionId,这需要在每个URL后面都加上sessionId!这样用户的请求中就包含了sessionId,服务器就可以通过sessionId找到对应的session对象了。
    使用response.encodeURL()方法对URL进行编码,这样URL中会智能的添加sessionId。
     当浏览器支持cookie时,response.encodeURL()方法不会在URL后追加sessionId
    当浏览器不支持cookie时,response.encodeURL()方法会在URL后追加sessionId

JSP指令

JSP指令分类
JSP有三大指令:

  • page指令
  • include指令
  • taglib指令

在JSP中没有任何指令是必须的!!!
但基本上每个JSP都是使用page指令!

==========================

page指令

page指令是最为常用的指令!

  1. page指令的常用属性:
  • import:等同与import语句
    –> <%@ page import=“java.util." %>
    –> <%@ page import="java.util.
    , java.net." %>
    –> 在一个JSP页面中可以给出多个page指令,而且import是可以重复出现的
    <%@ page import="java.util.
    ” %>
    <%@ page import=“java.next.*” %>

  • pageEncoding:指定当前页面的编码
    –> 如果pageEncoding没有指定,那么默认为contentType的值;
    –> 如果pageEncoding和contentType都没有指定,那么默认值为iso-8859-1

  • contentType:等同与调用response.setContentType(“text/html;charset=xxx”);
    –> 如果没有指定contentType属性,那么默认为pageEncoding的值;
    –> 如果contentType和pageEncoding都没有指定,那么默认值为iso-8859-1

  • errorPage:如果当前页面出现异常,那么跳转到errorPage指定的jsp页面。例如:<%@ page errorPage=“a.jsp” %>

  • isErrorPage:上面示例中指定a.jsp为错误页面,但在a.jsp中不能使用内置对象exception,保有a.jsp中使用<%@page isErrorPage=“true”%>时,才能在a.jsp中使用错误页面。

  • autoFlush:当autoFlush为true时,表示out流缓冲区满时会自动刷新。默认为true

  • buffer:指定out流的缓冲区大小,默认为8KB

  • isELIgnored:当前JSP页面是否忽略EL表达式,默认为false,表示不忽略,即支持EL表达式

  1. page指令不常用的属性:
  • language:当前JSP编译后的语言!默认为java,当前也只能选择java
  • info:当前JSP的说明信息
  • isThreadSafe:当前JSP是否执行只能单线程访问,默认为false,表示支持并发访问
  • session:当前页面是否可以使用session,默认为false,表示支持session的使用。
  • extends:指定JSP真身的父类!
  1. web.xml中对jsp的配置

    *.jsp true UTF-8 true

==========================

include指令
语法:<%@include file=“页面”%>
include指令的作用是包含指定的页面!在jsp被编译成java文件之前会把两个jsp文件合并,然后再编译成一个java文件。

注意:
<%@include file="<%=myfile%>" %>
这是不能通过编译的,因为myfile是一个变量,它的值只有在java编译成class后执行时才能确定。而include指令需要在jsp编译java时就要确定包含的是哪个页面,所以…

==========================

taglib指令
taglib指令是用来在当前jsp页面中导入第三方的标签库
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>

prefix:指定标签前缀,这个东西可以随意起名
uri:指定第三方标签库的uri(唯一标识)
当然,需要先把第三方标签库所需jar包放到类路径中。

==========================

九大内置对象

无需在jsp中声明即可使用的9个对象

  • out(JspWriter):等同与response.getWriter(),用来向客户端发送文本数据;
  • config(ServletConfig):对应“真身”中的ServletConfig;
  • page(当前JSP的真身类型):当前JSP页面的“this”,即当前对象,引用为Object类型;
  • pageContext(PageContext):页面上下文对象,它是最后一个没讲的域对象;
  • exception(Throwable):只有在错误页面中可以使用这个对象;
  • request(HttpServletRequest):即HttpServletRequest类的对象;
  • response(HttpServletResponse):即HttpServletResponse类的对象;
  • application(ServletContext):即ServletContext类的对象;
  • session(HttpSession):即HttpSession类的对象,不是每个JSP页面中都可以使用,如果在某个JSP页面中设置<%@page session=”false”%>,说明这个页面不能使用session。

pageContext对象

pageContext对象是PageContext类型

  • 域对象:只在当前jsp页面中有效的域,通常用来让jsp与当前jsp中标签之间共享数据
  • 获取其他8个内置对象:可以获取其他8个内置对象
  • 代理其他域对象:可以用pageContext来操作其他3个域。

==========================

JSP动作标签

JSP动作标签是用来替代一部分java脚本,使非java开发人员也可以向jsp中添加动态信息


jsp:include
例如:<jsp:include page=“xxx”/>,用来包含指定的页面。
例如在a.jsp中存在如下内容:<jsp:include page=“b.jsp”/>
a.jsp和b.jsp分别编码成Servlet,然后在执行Servlet时才会执行包含过程。这也是include指令与include标签的区别。

注意:<jsp:include page="<%=myfile%>">,这是可以的!因为include指令是在执行时才完成的包含,在执行时已经可以确定myfile这个变量的值。

该标签内部使用的是RequestDispatcher#include()方法完成的包含


jsp:forward
例如:<jsp:forward page=“xxx”/>,用来转发到指定页面
例如在a.jsp中存在如下内容:<jsp:fowrad page=“b.jsp”/>
a.jsp中的内容不会显示在浏览器上,而只是显示b.jsp的内容。而且在jsp:forwad标签下面的内容不会被执行。


jsp:param
该标签是jsp:include和jsp:forward的子标签,用来向其他页面传递参数。
<jsp:include page="/b.jsp">
<jsp:param value=“zhangSan” name=“username”/>
</jsp:include>
在b.jsp中可以使用request.getParameter(“username”)来获取参数值。

==========================

JavaBean

满足JavaBean规范的类就是javaBean

  • 必须有public的无参的构造器
  • 如果成员变量提供了getter/setter方法,那么称之为javabean属性。

JavaBean主要是用来通过反射操作的类!

因为需要通过Class的newInstance()方法来创建类的实例,所以要求类必须提供public的无参构造器
因为需要通过反射来操作属性,所以需要提供getter/setter方法。


内省

内省依赖反射,内省比反射简化一点点,用来操作JavaBean

把Map中的数据封装到指定类型的JavaBean中。
以有对象:Map、Class

  1. 通过Class对象获取BeanInfo
    BeanInfo info = Introspector.getBeanInfo(User.class);

  2. 通过BeanInfo获取所有属性描述符对象
    PropertyDescriptor[] pds = info.getPropertyDescriptors();

  3. PropertyDescriptor:

  • String name getName():获取当前属性名称
  • Method getReadMethod():获取get方法反射对象
  • Method getWriteMethod():获取set方法反射对象

commons-beanutils

beanutils比内省要简单很多,而且还要强大很多,它底层依赖内省。

  1. jar包
    commons-beanutils.jar、commons-logging.jar

  2. 通过反射设置Javabean
    Class clazz = User.class;
    Object user = clazz.newInstance();

BeanUtils.setProperty(user, “username”, “admin”);
BeanUtils.setProperty(user, “password”, “admin123”);

  1. 获取属性值

String username = BeanUtils.getProperty(user, “username”);

  1. 把Map数据封装到JavaBean对象中
    Map<String,String> map = new HashMap<String,String>();
    map.put(“username”, “admin”);
    map.put(“password”, “admin123”);

User user = new User();
BeanUtils.populate(user, map);

要求:map的key名称必须与User类的属性名称相同。不要无法赋值!


JSP中与JavaBean相关的标签

  • jsp:useBean
  • jsp:setProperty
  • jsp:getProperty

<jsp:useBean id=“user1” class=“cn.itcast.domain.User” />
查看page域中是否存在user1这个域属性,如果存在,那么直接获取。
如果不存在,那么创建之!

等同与:
User user1 = pageContext.getAttribute(“user1”);
if(user1 == null) {
user1 = new User();//创建user1对象
pageContext.setAttribute(“user1”, user1);//保存到page域
}


上面是操作page域,可以通过scope属性来指定操作的域

<jsp:useBean id=“user1” class=“cn.itcast.domain.User” scope=“page”/>
<jsp:useBean id=“user2” class=“cn.itcast.domain.User” scope=“request”/>
<jsp:useBean id=“user3” class=“cn.itcast.domain.User” scope=“session”/>
<jsp:useBean id=“user4” class=“cn.itcast.domain.User” scope=“applicatioin”/>


jsp:setProperty
设置属性值

<jsp:setProperty property=“username” name=“user1” value=“admin”/>

  • name:指定名为user1的JavaBean
  • property:指定要设置的属性名称
  • value:指定要设置的属性值

等同与

User user1 = (User)pageContext.getAttribute(“user1”);
user1.setUsername(“admin”);


jsp:getProperty
获取属性值

<jsp:getProperty property=“username” name=“user1”/>
输出user1这个javaBean的username属性值

等同与

User user1 = (User)pageContext.getAttribute(“user1”);
out.print(user1.getUsername());

==========================

==========================

EL表达式

EL:Expression Language,它是可以在JSP页面中直接使用的语言!
JSP页面也可以忽略EL:<@page isELIgnored=“true”%>
EL用来代替<%=…%>


格式: . . . , 例 如 : {...},例如: ...{1 + 2},会在页面上输出3


运算符:+ - * / % == != < > <= >= && ! || empty
${empty “”} --> 输出true,判断集合、数据、字符串长度是否为0

${null},不会输出!如果是null不输出!


EL内置对象

EL一共11个内置对象

EL操作四大域的内置对象:它们是Map类型
pageScope
requestScope
sessionScope
applicationScope

${pageScope.user}:输出pageContext.getAttribute(“user”)
${requestScope.user}:输出request.getAttribute(“user”);
${sessionScope.user}:输出session.getAttribute(“user”);
${applicationScope.user}:输出application.getAttribute(“user”);

${user}
依次在pageScope、requestScope、sessionScope、applicationScope中查找user
如果查找到,那么立刻停止查找。


对JavaBean的操作
对List的操作
对Map的操作


操作JavaBean
<%
User user = new User();
user.setUsername(“zhangSan”);
user.setPassword(“123”);
pageContext.setAttribute(“user”, user);
%>
${pageScope.user.username}
${pageScope.user.password}


操作List

<%
User user = new User();
user.setUsername(“zhangSan”);
user.setPassword(“123”);
List list = new ArrayList();
list.add(user);
pageContext.setAttribute(“list”, list);
%>

${pageScope.list[0].username}
${pageScope.list[0].password}


操作Map

<%
User user = new User();
user.setUsername(“zhangSan”);
user.setPassword(“123”);
Map map = new HashMap();
map.put(“u1”, user);

pageContext.setAttribute(“map”, map);
%>

${pageScope.map[‘u1’].username}
${pageScope.map[‘u1’].password}

${pageScope.map.u1.username}
${pageScope.map.u1.password}


EL操作参数内置对象:Map类型

param:Map<String,String>
paramValues:Map<String,String[]>

${param.username}:request.getParameter(“username”)
${paramValues.hobby}:request.getParameterValues(“hobby”);


EL操作请求头内置对象:Map类型

header:Map<String,String>
headerValues:Map<String,String[]>

${header.UserAgent}
${headerValues.UserAgener[0]}


应用初始化参数内置对象:Map类型
initParam:Map<String,String>

用来获取web.xml文件中的参数,例如:

web.xml

p1
v1

${initParam.p1}


与Cookie相关的内置对象:Map类型
cookie:Map<String,Cookie>,其中key是Cookie的名称,而值是Cookie对象

${cookie.jsessionid.value}:获取sessionid


pageContext内置对象:PageContext类型

${pageContext.request},等同pageContext.getRequest()
${pageContext.session},等同pageContext.getSession()

${pageContext.request.contextpath},获取项目名
${pageContext.session.id},获取sessionId


EL中最重要的就是操作四大域!

==========================

==========================

EL函数库

EL函数库,当前就是一些函数了。

使用EL函数库需要在JSP页面中导入标签库:
<%@ taglib prefix=“fn” uri=“http://java.sun.com/jsp/jstl/function”%>

<%@taglib prefix=“fn” uri=“http://java.sun.com/jsp/jstl/functions” %>

String[] strs = {“a”, “b”,“c”};
List list = new ArrayList();
list.add(“a”);
pageContext.setAttribute(“arr”, strs);
pageContext.setAttribute(“list”, list);
%>
${fn:length(arr) }

${fn:length(list) }

${fn:toLowerCase(“Hello”) }

${fn:toUpperCase(“Hello”) }

${fn:contains(“abc”, “a”)}

${fn:containsIgnoreCase(“abc”, “Ab”)}

${fn:contains(arr, “a”)}

${fn:containsIgnoreCase(list, “A”)}

${fn:endsWith(“Hello.java”, “.java”)}

${fn:startsWith(“Hello.java”, “Hell”)}

${fn:indexOf(“Hello-World”, “-”)}

${fn:join(arr, “;”)}

${fn:replace(“Hello-World”, “-”, “+”)}

${fn:join(fn:split(“a;b;c;”, “;”), “-”)}

${fn:substring(“0123456789”, 6, 9)}

${fn:substring(“0123456789”, 5, -1)}

${fn:substringAfter(“Hello-World”, “-”)}

${fn:substringBefore(“Hello-World”, “-”)}

${fn:trim(" a b c “)}

${fn:escapeXml(”")}

====================

自定义函数库

  1. 编写类
    类中只能有public static的方法,并且一定要有返回值

public class ItcastFuncations {
public static String test() {
return “传智播客自定义EL函数库测试”;
}
}

  1. 部署文件
    /WEB-INF/itcast.tld
<?xml version="1.0" encoding="UTF-8" ?>

1.0
itcast
http://www.itcast.cn/jsp/functions

test cn.itcast.el.funcations.ItcastFuncations String test()
  1. 在JSP中使用自定义

<%@ page language=“java” import=“java.util.*” pageEncoding=“UTF-8”%>
<%@ taglib prefix=“itcast” uri="/WEB-INF/itcast.tld" %>

${itcast:test() }

JSTL

  1. jstl的概述
  • apache的东西,依赖EL
  • 使用jstl需要导入jstl1.2.jar
  • 四大库:

    core:核心库,重点
    fmt:格式化:日期、数字
    sql:过时
    xml:过时

  1. 导入标签库
  • jar包
  • 在jsp页面中:<%@taglib prefix=“前缀” uri=“路径”%>

core --> c标签!

  1. out和set
  • <c:out>:输出

    value:可以是字符串常量,也可以是EL表达式
    default:当要输出的内容为null时,会输出default指定的值
    escapeXml:默认值为true,表示转义!

  • <c:set>:设置(创建域的属性)

    var:变量名
    value:变量值,可以是EL表达式
    scope:域,默认为page,可选值:page、request、session、application

  1. remove
  • :删除域变量

    var:变量名
    scope:如果不给出scope,表示删除所有域中的该名称的变量;如果指定了域,那么只删除该域的变量。

  1. url
  • value:指定一个路径!它会在路径前面自动添加项目名。
    <> <c:url value="/index.jsp"/>,它会输出/day13_1/index.jsp
  • 子标签:<c:param>,用来给url后面添加参数,例如:
    <c:url value="/index.jsp">
    <c:param name=“username” value=“张三”/>
    </c:url>
    结果为:/day13_1/index.jsp?username=%ED%2C%3F%ED%2C%3F
  • var:指定变量名,一旦添加了这个属性,那么url标签就不会再输出到页面,而是把生成url保存到域中。
  • scope:它与var一起使用,用来保存url。
  1. if:对应java中的if语句
  • <c:if test=“布尔类型”>…</c:if>,当test为值时,执行标签体内容!
  1. choose:它对应java中的if/else if/ … /else
  • 例如:
    <c:choose>
    <c:when test="">…</c:when>
    <c:when test="">…</c:when>
    <c:when test="">…</c:when>

    <c:otherwise> …</c:otherwise>
    </c:choose>
    等同与
    if(…) {
    } else if( …) {
    } else if( …) {
    } else if( …) {
    } …
    else { …}
  1. forEach
    它用来循环遍历数组、集合!
    它还可以用来计数方式来循环!

计数方式:

for(int i = 1; i <= 10; i++) {

}

<c:forEach var=“i” begin=“1” end=“10”>
${i}
</c:forEach>

属性:
* var:循环变量
* begin:设置循环变量从几开始。
* end:设置循环变量到几结束。
* step:设置步长!等同与java中的i++,或i+=2。step默认为1


用来输出数组、集合!

<c:forEach items="${strs }" var=“str”>
${str }

</c:forEach>

等同于

for(String str : strs) {

}

属性:

  • items:指定要循环谁,它可以是一个数组或一个集合
  • var:把数组或集合中的每个元素赋值给var指定的变量。

循环状态

可以使用varStatus来创建循环状态变量!

循环状态变量有如下属性:

  • count:循环元素的个数
  • index:循环元素的下标
  • first:是否为第一个元素
  • last:是否为最后一个元素
  • current:当前元素

<c:forEach items="${list }" var=“ele” varStatus=“vs”>
${vs.index} ${vs.count } ${vs.first } ${vs.last } ${vs.current }

</c:forEach>

====================================

fmt库
它是格式化库

<fmt:formatDate value="" pattern="">

value:指定一个Date类型的变量
pattern:用来指定输出的模板!例如:yyyy-MM-dd HH:mm:ss


<fmt:formatNumber value="${num1}" pattern=“0.00”>
保留小数点后2位,它会四舍五入!如果不足2位,以0补位!

<fmt:formatNumber value="${num1}" pattern="#.##">
保留小数点后2位,它会四舍五入!如果不足2位,不补位!

====================================

自定义标签

  1. 步骤
  • 标签处理类(标签也是一个对象,那么就需要先有类!)
  • tld文件,它是一个xml
  • 页面中使用<%@taglib%>来指定tld文件的位置
  1. 标签处理类
    SimpleTag接口:
  • void doTag():每次执行标签时都会调用这个方法;
  • JspTag getParent():返回父标签(非生命周期方法)
  • void setParent(JspTag):设置父标签
  • void setJspBody(JspFragment):设置标签体
  • void seetJspContext(JspContext):设置jsp上下文对象,它儿子是PageContext

其中doTag()会在其他三个方法之后被tomcat调用。

  1. 配置tld文件

tld文件一般都放到WEB-INF之下,这样保证客户端访问不到!

myTag1 指定当前标签的名称
cn.itcast.tag.MyTag1 指定当前标签的标签处理类!
empty 指定标签体的类型,我们这里使用的是空标签!

  1. 页面中指定tld文件位置

<%@ taglib prefix=“it” uri="/WEB-INF/tlds/itcast-tag.tld" %>
导标签库,就是为页面指定tld文件的位置!


进阶

标签体内容

  • empty:无标签体!
  • JSP:jsp2.0已经不在支持这个类型了!表示标签体内容可以是:java脚本,可以是标签,可以是el表达式
  • scriptless:只能是EL表达式,也可以是其他的标签!
  • tagdependent:标签体内容不会被执行,而是直接赋值标签处理类!

不在执行标签下面内容的标签!

在标签处理类中的doTag()中使用SkipPageException来结束!
  Tomcat会调用标签处理类的doTag()方法,然后Tomcat会得到SkipPageException,它会跳过本页面其他内容!


标签属性

步骤:

  1. 给你的标签处理类添加属性!
      为标签处理类添加属性,属性至少要且一个set方法!这个set方法会在doTag()方法之前被tomcat执行!所在doTag()中就可以使用属性了。

  2. 在tld文件中对属性进行配置

    test 指定属性名 true 指定属性是否为必需的 true 指定属性是否可以使用EL

==========================================

MVC
它不是java独有,所有的B/S结构的项目都在使用它!

M – model 模型(自己写代码)
V – View 视图(jsp)
C – Cotroller 控制器(Servlet)

==========================================

JavaWeb三层框架

Web层 --> 与Web相关的内容(Servlet,JSP,Servlet相关API:request、response、session、ServletContext)
业务层 --> 业务对象(Service)
数据层 --> 操作数据库(DAO Data Access Object)(所有对数据库的操作,不能跳出到DAO之外)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值