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()%>
---------------------
4. JSP真身
* JSP也是Servlet
* JSP会在第一次被请求时编码成.java,再编码成.class文件,它其实就是一个Servlet,在处理请求时执行service()方法。
查看真身可以得到,jsp中有9个对象可以无需创建即可使用,它们就是jsp九大内置对象。
---------------------
5. JSP注释
* <!-- -->,html注释,不是JSP注释,它会出现在JSP的真身中,并发送到客户端,但客户端浏览器不会显示它。
* <%-- --%>,JSP注释,它不会出现在JSP真身中,也就不可能发送到客户端浏览器了。
================================
================================
================================
会话跟踪
1. 什么是会话
* 用户拨打10086,从服务台接通后会话开始;
* 用户发出话费查询请求,服务台响应。这是该会话中的一个请求;
* 用户发出套餐变更请求,服务台响应。这是该会话中的又一个请求;
* ...
* 用户挂断电话,会话结束。
2. 会话的特性
* 一个会话中可能包含多个请求;
* 一个会话中发出请求的用户是唯一的;
3. JavaWeb会话
* 从用户打开本站第一个页面开始,会话也开始了;
* 用户会发出0~n个请求;
* 用户关闭浏览器会话结束了。
4. 什么是会话跟踪技术
HTTP是无状态协议,也就是没有记忆力的协议,每个请求之间无法共享数据。这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。这说明需要使用额外的手段来跟踪会话!
* 在一个会话中共享数据即会话跟踪技术
------------------------------------
Cookie
1. 什么是Cookie
* Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据。
* 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来。
* 当客户端再次请求同一服务器时,客户端会在请求头中添加该服务器保存的Cookie,发送给服务器。
* Cookie就是服务器保存在客户端的数据!
* Cookie就是一个键值对!!!
2. Cookie规范
* Cookie通过请求头和响应头在服务器与客户端之间传输;
* Cookie大小限制在4KB之内;
* 一台服务器在一个客户端最多保存20个Cookie;
* 一个浏览器最多可以保存300个Cookie;
虽然Cookie规范是如此,但在今天,浏览器厂商的竞争异常激烈,所以多少会超出Cookie规则的限制。但也不会超出过多!
3. Cookie与请求头和响应头
* 服务器向客户端发送Cookie的响应头为Set-Cookie,例如:Set-Cookie:cookiename=cookievalue
* 客户端向服务器发送Cookie的请求头为Cookie,例如:Cookie:cookiename=cookievalue
4. Servlet中向客户端发送Cookie
Cookie cookie1 = new Cookie("test1", "abcdefg");
Cookie cookie2 = new Cookie("test2", "ABCDEFG");
response.addCookie(cookie1);
response.addCookie(cookie2);
5. 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。
2. 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(c);
}
// 设置了Cookie的path为/day06_2
CServlet {
Cookie c = new Cookie("yyy", "YYY");
c.setPath="/day06_2";
response.addCookie(c);
}
DServlet {
Cookie c = new Cookie("zzz", "ZZZ");
resposne.addCookie(c);
}
在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,所以不会带上。
3. 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
当然这需要配置两个虚拟主机才行。
4. 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
在JavaWeb中提供了HttpSession类,用来表示http会话。
1. 获取HttpSession
HttpSession session = request.getSession();
HttpSession session = request.getSession(false);
2. 域功能
session是域对象,所以有setAttribute()和getAttribute()等方法
服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。
3. 登录案例
请求功能:
1. 如果登录功能,在session中保存user对象
2. 访问index1.jsp,查看session中是否存在user对象,如果存在,说明已经登录过。
3. 访问index2.jsp,查看session中是否存在user对象,如果存在,说明已经登录过。
如果关闭了浏览器,那么会话结束,再打开浏览器就开始了一个新会话,那么直接访问index1.jsp或index2.jsp时,session是新的,没有保存user对象,那么表示还没有登录。
4. 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文件中配置如下:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5. session与浏览器
session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。也就是说,使用IE登录后,再使用FireFox访问服务器还是没有登录的状态。
而且同时打开多个相同浏览器的窗口,是在使用同一session。如果你使用的是老浏览器,例如IE6,那么就会每个窗口一个session。
6. 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的状态为新。
7. 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
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()%>
---------------------
4. JSP真身
* JSP也是Servlet
* JSP会在第一次被请求时编码成.java,再编码成.class文件,它其实就是一个Servlet,在处理请求时执行service()方法。
查看真身可以得到,jsp中有9个对象可以无需创建即可使用,它们就是jsp九大内置对象。
---------------------
5. JSP注释
* <!-- -->,html注释,不是JSP注释,它会出现在JSP的真身中,并发送到客户端,但客户端浏览器不会显示它。
* <%-- --%>,JSP注释,它不会出现在JSP真身中,也就不可能发送到客户端浏览器了。
================================
================================
================================
会话跟踪
1. 什么是会话
* 用户拨打10086,从服务台接通后会话开始;
* 用户发出话费查询请求,服务台响应。这是该会话中的一个请求;
* 用户发出套餐变更请求,服务台响应。这是该会话中的又一个请求;
* ...
* 用户挂断电话,会话结束。
2. 会话的特性
* 一个会话中可能包含多个请求;
* 一个会话中发出请求的用户是唯一的;
3. JavaWeb会话
* 从用户打开本站第一个页面开始,会话也开始了;
* 用户会发出0~n个请求;
* 用户关闭浏览器会话结束了。
4. 什么是会话跟踪技术
HTTP是无状态协议,也就是没有记忆力的协议,每个请求之间无法共享数据。这就无法知道会话什么时候开始,什么时候结束,也无法确定发出请求的用户身份。这说明需要使用额外的手段来跟踪会话!
* 在一个会话中共享数据即会话跟踪技术
------------------------------------
Cookie
1. 什么是Cookie
* Cookie是HTTP协议的规范之一,它是服务器和客户端之间传输的小数据。
* 首先由服务器通过响应头把Cookie传输给客户端,客户端会将Cookie保存起来。
* 当客户端再次请求同一服务器时,客户端会在请求头中添加该服务器保存的Cookie,发送给服务器。
* Cookie就是服务器保存在客户端的数据!
* Cookie就是一个键值对!!!
2. Cookie规范
* Cookie通过请求头和响应头在服务器与客户端之间传输;
* Cookie大小限制在4KB之内;
* 一台服务器在一个客户端最多保存20个Cookie;
* 一个浏览器最多可以保存300个Cookie;
虽然Cookie规范是如此,但在今天,浏览器厂商的竞争异常激烈,所以多少会超出Cookie规则的限制。但也不会超出过多!
3. Cookie与请求头和响应头
* 服务器向客户端发送Cookie的响应头为Set-Cookie,例如:Set-Cookie:cookiename=cookievalue
* 客户端向服务器发送Cookie的请求头为Cookie,例如:Cookie:cookiename=cookievalue
4. Servlet中向客户端发送Cookie
Cookie cookie1 = new Cookie("test1", "abcdefg");
Cookie cookie2 = new Cookie("test2", "ABCDEFG");
response.addCookie(cookie1);
response.addCookie(cookie2);
5. 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。
2. 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(c);
}
// 设置了Cookie的path为/day06_2
CServlet {
Cookie c = new Cookie("yyy", "YYY");
c.setPath="/day06_2";
response.addCookie(c);
}
DServlet {
Cookie c = new Cookie("zzz", "ZZZ");
resposne.addCookie(c);
}
在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,所以不会带上。
3. 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
当然这需要配置两个虚拟主机才行。
4. 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
在JavaWeb中提供了HttpSession类,用来表示http会话。
1. 获取HttpSession
HttpSession session = request.getSession();
HttpSession session = request.getSession(false);
2. 域功能
session是域对象,所以有setAttribute()和getAttribute()等方法
服务器会为每个会话创建一个session对象,所以session中的数据可供当前会话中所有servlet共享。
3. 登录案例
请求功能:
1. 如果登录功能,在session中保存user对象
2. 访问index1.jsp,查看session中是否存在user对象,如果存在,说明已经登录过。
3. 访问index2.jsp,查看session中是否存在user对象,如果存在,说明已经登录过。
如果关闭了浏览器,那么会话结束,再打开浏览器就开始了一个新会话,那么直接访问index1.jsp或index2.jsp时,session是新的,没有保存user对象,那么表示还没有登录。
4. 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文件中配置如下:
<session-config>
<session-timeout>30</session-timeout>
</session-config>
5. session与浏览器
session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。
因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。也就是说,使用IE登录后,再使用FireFox访问服务器还是没有登录的状态。
而且同时打开多个相同浏览器的窗口,是在使用同一session。如果你使用的是老浏览器,例如IE6,那么就会每个窗口一个session。
6. 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的状态为新。
7. 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