本文目录:
- JSP基础
- Cookie
- HttpSession
JSP基础
JSP(Java Server Pages)是JavaWeb服务器端的动态资源。它与html页面的作用是相同的,显示数据和获取数据。
jsp和Servlet的常见分工
(jsp) request -- servlet -- (jsp) response
- JSP
- 作为请求发起页面,把来自用户的post/get等请求发送给servlet:例如页面内含有表单、超链接
- 作为请求结束页面,接受servlet的数据,显示给用户。
- Servlet
- 获取jsp发送来的请求参数
- 处理请求,得到处理后的数据
- 把结果保存到request中
- 转发到显示结果的JSP
jsp的作用
- Servlet
- 优点:动态资源(html静态页面不能包含动态信息)
- 缺点:不适合设置html代码,需要大量的response.getWriter().print("<html>")
- jsp(java server pages)
- jsp文件内容:直接在原有html代码的基础上,添加java脚本。很方便。
jsp的组成 jsp = html + java脚本 + jsp标签(指令)
JSP标签 有2种:
JSP指令元素<%@ %>
JSP动作元素<jsp: />
-
jsp的9大内置对象(无需创建即可使用的对象):
- request
- response
- out
- session
- application 和tomcat进程“共生死”
- pageContext
- config
- page
- exception
3种java脚本
<% java代码片段 %>
<!--,常用
可写0到n条Java语句
方法内能写什么,它就可以写什么
-->
<%=表达式 %>
<!--java表达式,用于输出一条表达式(或变量)的结果。-->
response.getWriter().print( ... );
<!--这里能放什么,它就可以放什么!
比如某个具有返回值的函数 func1()
-->
<%!声明 成员变量等 %>
<!--声明,用来创建类的成员变量和成员方法(基本不用,但容易被考到)
类体中可以放什么,它就可以放什么!
Class man{
成员变量
成员方法
构造器
构造代码块
静态块
内部类
}
-->
out.print()和out.write() 几乎没有区别:
String s = null;
out.print(s); // outputs the text "null" 处理空指针异常,输出字符串“null”。
out.write(s); // NullPointerException 不处理该异常。
jsp注释
<%-- 当服务器把jsp编译成java文件前就没有这些注释了! --%>
<!-- html注释会发到客户端浏览器。 -->
案例:演示jsp中java脚本的使用!
案例:演示jsp与servlet分工!
jsp原理(理解)
- 当jsp页面第一次被访问时:
- 1.服务器会把jsp编译成java文件(这个java其实是一个servlet类)
- 2.再把java编译成.class
- 3.创建该类对象
- 4.最后调用它的service()方法
- 第二次请求某jsp时,直接调用service()方法。
jsp实质是一种特殊的Servlet
在tomcat/work/Catalina目录下可以找到 jsp 对应的 .java 源代码,和生成的.class文件。
- 查看jsp对应java文件:
- .java语句,方法体的最上面,声明了9大内置对象,赋值。
- 原封不动的把程序员写的代码放到方法体下面。
- html语句,全是这样输出的:
out.wirte("字符串");
Cookie
Http协议与Cookie
- Cookie是HTTP协议制定的!
服务器保存Cookie到浏览器,再下次浏览器请求服务器时,会带上Cookie - 由服务器创建保存到客户端浏览器的一个键值对!
”key=value“
服务器保存Cookie的响应头
Set-Cookie: aaa=AAA Set-Cookie: bbb=BBB
response.addHeader("Set-Cookie", "aaa=AAA");
response.addHeader("Set-Cookie", "bbb=BBB");
- 当客户端浏览器发送request给服务器时,会带上Cookie:
Cookie: aaa=AAA; bbb=BBB
- Http协议规定(很多浏览器都会在一定范围内违反HTTP规定)
- 1个Cookie最大4KB
- 1个服务器最多向1个浏览器保存20个Cookie
- 1个浏览器最多可以保存300个Cookie
Cookie的用途
注意Cookie不跨浏览器!
- 跟踪客户端状态
- 保存购物车信息
- 只保存上次的登录名,方便登录。
JavaWeb中使用Cookie
- 原始方式(了解)
- 使用response发送Set-Cookie响应头
- 使用request获取Cookie请求头
- 便捷方式(重要!)
repsonse.addCookie()//让浏览器端保存Cookie
request.getCookies()//获取浏览器端带来的Cookie
//如果HTTP请求没有带来cookie则返回null
服务器端发送response给客户端浏览器,http响应包头中有Set-Cookie头,格式如下:
Set-Cookie: key1=value2
Set-Cookie: key1=value2
Set-Cookie: key1=value2
客户端发送request给服务器时,http请求包头里面有Cookie头,格式如下:
Cookie: key1=value1; key2=value2; key3=value3
Cookie详解
- Cookie不只有name和value两个属性
- Cookie的maxAge
- maxAge>0:Cookie的最大生命。浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值,以秒为单位。
cookie.setMaxAge(60)
- maxAge<0:Cookie只在浏览器内存中存在(浏览器进程结束,Cookie消失)
- maxAge=0:立即删除同名cookie
- maxAge>0:Cookie的最大生命。浏览器会把Cookie保存到客户机硬盘上,有效时长为maxAge的值,以秒为单位。
- Cookie的path
- Cookie的path决定:当浏览器访问服务器某个路径时,带上哪些Cookie
- Cookie的path不可能是设置这个Cookie在客户端的保存路径!
- Cookie的path由响应包response创建Cookie时设置
- 浏览器访问服务器的路径,如果包含某个Cookie的路径,那么就会带上这个Cookie。
例如:服务器端设置
aCookie.path=/day11_1/;
bCookie.path=/day11_1/aaa/;
cCookie.path=/day11_1/aaa/bbb/;
客户端浏览器
访问:域名/day11_1/anyname.jsp 时带上aCookie
访问:域名/day11_1/aaa/anyname.jsp 时带上aCookie、bCookie
访问:域名/day11_1/aaa/bbb/anyname.jsp 时带上aCookie、bCookie、cCookie
- Cookie的path默认值:当前访问路径的父路径。
如访问/day11_1/jsps/a.jsp时响应包设置了cookie,该cookie的默认path为/day11_1/jsps/
- Cookie的domain用来指定服务器设置的Cookie给哪些域名!当多个二级域中共享Cookie时才需要用
例如这些二级域名之间需要共享cookie:www.baidu.com、zhidao.baidu.com、news.baidu.com、tieba.baidu.com
服务器端:
cookie.setDomain(".baidu.com");//设置domain 直接省略掉二级域名的不同之处
cookie.setPath("/");//设置path
- 自己测试,步骤:
修改本机hosts文件
127.0.0.1 111.x.com
123.0.0.1 222.x.com在${CATALINA_HOME}/conf/server.xml中添加配置
<Host name="news.qdmmy6.com" appBase="news"
unpackWARs="true" autoDeploy="true">
</Host>
<Host name="tieba.qdmmy6.com" appBase="tieba"
unpackWARs="true" autoDeploy="true">
</Host>把tieba和news两个目录copy到${CATALINA_HOME}下
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(c);
//获取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(重点)
HttpSession概述
HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
HttpSession底层依赖Cookie或URL重写!
HttpSession是Servlet三大域对象之一
三大域对象
-
request
- 每一次请求都会创建一个request
- 请求链共享数据 可把request发给多个Servlet
-
session
- 会话是同一个用户在浏览器打开后关闭前对服务器的多次请求。
-
application(ServletContext)
- 程序存在,保存在这里的内容就一直存在
三大域对象都有方法:
void setAttribute(String name, Object value);
Object getAttribute(String name);
void removeAttribute(String name);
session是域对象,所以有setAttribute()和getAttribute()等方法
服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。
会话 会话追踪
- 会话:同一个用户在浏览器打开后关闭前对服务器的多次请求。
- 会话范围:某个用户从首次访问服务器开始,到该用户关闭浏览器结束!
- 会话方便了服务器端共享数据!对客户端浏览器只在Cookie里只有一个session的ID,服务器端在这个session中设置的一些值对用户均不可见。
- 会话跟踪技术:在一次会话中共享数据。
HTTP是无状态协议,每个请求之间无法共享数据。这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。这说明需要使用额外的手段来跟踪会话! - session缓存:服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存!
Servlet中得到session对象
HttpSession session = request.getSession();
Jsp中得到session对象
session是jsp内置对象,不用创建,直接使用!如
<%session.setAttribute("aa","bb")%>
案例1:session 多次请求中共享数据
- AServlet:向session域中保存数据
- BServlet:从session域中获取数据
- 演示:
第一个请求:访问AServlet
第二个请求:访问BServlet
案例2:session 保存用户登录信息(精通)
-
案例相关页面和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就会通过!
HttpSession原理(理解)
-
request.getSession()方法
- 获取Cookie中的JSESSIONID(唯一标识)
- 如果Cookie中没有sessionId,从url参数中获取 格式为;JsessionID=也没有时,服务器创建一个session并保存,把新创建的sessionId设置到浏览器Cookie中,这个Cookie的生命为-1,即只在浏览器内存中存在!
- 关闭浏览器前,再次请求,服务器端执行request.getSession()方法,通过客户端带Cookie的请求,得到Cookie中的sessionId,服务器的session对象与上一次请求使用的是同一session对象。
- 如果sessionId存在,但通过sessionId没有找到session对象(可能超时被服务器删除了),创建session保存到服务器,把新创建的sessionId保存到客户端浏览器的Cookie中
- 如果sessionId存在,通过sessionId查找到了session对象(不会再创建新session对象)
服务器不会马上给用户创建session,在第一次获取session时才会创建该用户的session!
session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。
//以下都是Servlet的代码:
//所有Servlet如果不写这一行,都不会自动创建session(不会给客户端Set-Cookie)
request.getSession();//如果是服务器端第一次获取Session 则向客户端设置Set-Cookie
request.getSession(false)//如果请求包的cookie带了JsessionID,则获取;如果没带来sessionid则返回null 且不创建session对象!
request.getSession(true)//有session则得到session,没有则用Set-cookie设置到浏览器
request.getSession()//和上一个方法效果相同
任何JSP页面,都会自动创建session!
HttpSession其他方法
- String getId()
- 获取sessionId
- void invalidate()
- 调用这个方法会使session让当前session失效!当session失效后,客户端再次请求,服务器会给客户端创建一个新的session在响应中给客户端Set-Cookie 新sessionId
- boolean isNew()
- 查看session是否为“New”。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端(还没有发送响应包Set-Cookie:sessionId),此时session的状态为“New”
- long getCreationTime():返回session的创建时间,返回值为当前时间的毫秒值;
- long getLastAccessedTime():返回session的最后活动时间,返回值为当前时间的毫秒值;
- int getMaxInactiveInterval()
- 获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
- void setMaxInactiveInterval(int interval):设置session允许的最大不活动时间(秒),如果设置为1秒,那么只要session在1秒内不被使用,那么session就会被移除;
request.getSession().isNew();
web.xml中配置session的最大不活动时间(分钟数)
<session-config>
<session-timeout>30</session-timeout>
</session-config>
URL重写(理解)
HttpSession底层依赖Cookie或URL重写!
session依赖Cookie,目的是让客户端发出请求时带上Cookie(含有sessionId),服务器才能找到对应的session
如果浏览器禁用所有cookie,所以服务器给浏览器Set-Cookie多少遍都没用。只能用URL重写:
让网站的所有超链接(get)、表单(post)中都添加一个名为JSESSIONID的参数,这样服务器通过获取请求参数也能得到sessionId,从而找到session对象。
URL重写,简单说实质:就是把所有的页面中的路径,都使用这条语句处理一下:
response.encodeURL(String url)
该方法会对url进行智能的重写:
当浏览器不支持cookie或支持Cookie但第一次请求时,request中的Cookie没有带sessionid,则response.encodeURL()方法会在URL后追加sessionId(比如首次访问JSP页面)
当request中的Cookie带sessionid时,response.encodeURL()方法不会在URL后追加sessionId