Jsp&cookie & session一.jsp

1. jsp的先容

JSP全名为Java Server Pages,中文名叫java做事器页面,实质是一个简化的Servlet设计,它是由Sun Microsystems公司倡导、许多公司参与一起建立的一种动态网页技能标准。
JSP技能有点类似ASP技能,它是在传统的网页HTML文件(.htm,.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(.jsp)。
用JSP开拓的Web运用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。

它实现了Html语法中的java扩展(以 <%, %>形式)。
JSP与Servlet一样,是在做事器端实行的。
常日返回给客户真个便是一个HTML文本,因此客户端只要有浏览器就能浏览。

jsp连接数据库JavaWeb11jspcookiesession HTML

jsp的浸染:将内容的天生和显示进行分离

组成:html+java代码+jsp分外标签

用JSP技能,Web页面开拓职员可以利用HTML或者XML标识来设计和格式化终极页面,并利用JSP标识或者小脚本来天生页面上的动态内容

2. jsp的事理

jsp事理

上图描述的是一个jsp页面hello.jsp在做事器中处理的过程。

创建web工程day10,创建一个hello.jsp页面。

1.在浏览器中输入 http://localhost/day10/hello.jsp

2.做事器得到要求,会通过jsp引擎查找到hello.jsp页面

3.做事器将查找到的hello.jsp页面翻译成hello_jsp.java(实在质便是一个servlet)

4.jvm会将hello_jsp.java文件编译成hello_jsp.class

5.做事器运算hello_jsp.class文件

6.做事器天生相应结果

jsp实行事理

1.浏览器发送要求

2.做事器接管要求 处理要求

3.找到对应的jsp文件,然后将其转成java文件(hello_jsp.java)

4.jvm将java文件编译成class文件

5.做事器运行class文件,天生动态的内容,

6.将天生的内容转给做事器,做事器将相应信息返回给浏览器

7.浏览器解析

jsp对应java文件剖析

上述是我们对付一个jsp运行的事理的大略剖析,我们可以通过查看hello.jsp文件翻译后的.java文件来理解详细内容,天生的hello.jsp页面的java源文件存在于tomcat/work目录 下。

hello.jsp页面源代码

<%@ page language=\公众java\"大众 import=\"大众java.util.\公众 pageEncoding=\"大众utf-8\公众%>

<!DOCTYPE HTML PUBLIC \公众-//W3C//DTD HTML 4.01 Transitional//EN\公众>

<html>

<head>

<title>hello.jsp</title>

</head>

<body>

hello jsp

</body>

</html>

hello_jsp.java文件源代码

package org.apache.jsp;

import javax.servlet.;

import javax.servlet.http.;

import javax.servlet.jsp.;

import java.util.;

public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase

implements org.apache.jasper.runtime.JspSourceDependent {

private static final javax.servlet.jsp.JspFactory _jspxFactory =

javax.servlet.jsp.JspFactory.getDefaultFactory();

private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

private javax.el.ExpressionFactory _el_expressionfactory;

private org.apache.tomcat.InstanceManager _jsp_instancemanager;

public java.util.Map<java.lang.String,java.lang.Long> getDependants() {

return _jspx_dependants;

}

public void _jspInit() {

_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();

_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());

}

public void _jspDestroy() {

}

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)

throws java.io.IOException, javax.servlet.ServletException {

final javax.servlet.jsp.PageContext pageContext;

javax.servlet.http.HttpSession session = null;

final javax.servlet.ServletContext application;

final javax.servlet.ServletConfig config;

javax.servlet.jsp.JspWriter out = null;

final java.lang.Object page = this;

javax.servlet.jsp.JspWriter _jspx_out = null;

javax.servlet.jsp.PageContext _jspx_page_context = null;

try {

response.setContentType(\公众text/html;charset=utf-8\"大众);

pageContext = _jspxFactory.getPageContext(this, request, response,

null, true, 8192, true);

_jspx_page_context = pageContext;

application = pageContext.getServletContext();

config = pageContext.getServletConfig();

session = pageContext.getSession();

out = pageContext.getOut();

_jspx_out = out;

out.write(\公众\r\n\"大众);

out.write(\公众<!DOCTYPE HTML PUBLIC \\公众-//W3C//DTD HTML 4.01 Transitional//EN\\公众>\r\n\"大众);

out.write(\"大众<html>\r\n\"大众);

out.write(\"大众 <head> \r\n\"大众);

out.write(\"大众 <title>hello.jsp</title>\r\n\"大众);

out.write(\"大众 </head>\r\n\公众);

out.write(\公众 \r\n\"大众);

out.write(\"大众 <body>\r\n\"大众);

out.write(\"大众 hello jsp\r\n\"大众);

out.write(\"大众 </body>\r\n\"大众);

out.write(\"大众</html>\r\n\"大众);

} catch (java.lang.Throwable t) {

if (!(t instanceof javax.servlet.jsp.SkipPageException)){

out = _jspx_out;

if (out != null && out.getBufferSize() != 0)

try { out.clearBuffer(); } catch (java.io.IOException e) {}

if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);

else throw new ServletException(t);

}

} finally {

_jspxFactory.releasePageContext(_jspx_page_context);

}

}

}

通过上面的内容,大家会创造在jsp页面中的所有的html代码,终极都会被流写回到浏览器端,以是我们可以在浏览器上查看到jsp页面上的html内容

3. jsp的脚本与注释

jsp中三种脚本元素

有三个基本的脚本元素,浸染是使JAVA代码可以直接插入到HTML代码中

声明标签

格式:<%! int a = 1; %>

浸染:声明的变量在类的成员位置上

脚本片断

格式:<% int a = 1; out.println(a); %>

浸染:内容会天生在_jspService()方法中

脚本表达式(输出脚本)

格式:<%=\"大众hello \"大众 + a%>

浸染:它就相称于是out.println()将内容直接输出到页面中,内容会天生在_jspService()方法中把稳表达式不能以分号结尾

jsp中的注释

在jsp页面中可以利用三种注释

可以利用html中注释

<!-- html的注释 -->在java源码和html源文件中都有

可以对jsp脚本内容利用java注释

//单行注释 / 多行注释 / / 文档注释 / 在java源码中有,在html源文件中没有

可以利用jsp注释(推举)

<%-- jsp注释 --%>在Java源码和html源文件中都没有

4. jsp与servlet的结合利用

Jsp实现登录案例

把昨天的登录操作利用jsp实现一下,流程稍稍改变一下:

创建数据库与表

CREATE DATABASE day10;

USE day10;

CREATE TABLE USER(

id INT PRIMARY KEY AUTO_INCREMENT,

username VARCHAR(20),

PASSWORD VARCHAR(20),

email VARCHAR(50),

sex VARCHAR(20),

telephone VARCHAR(20),

introduce VARCHAR(200)

)

INSERT INTO USER VALUES(NULL,\"大众tom\"大众,\公众123\公众,\"大众tom@itcast.cn\"大众,\"大众男\"大众,\"大众13888888888\"大众,\公众good boy\"大众);

导入mysql驱动jar包

创建JdbcUtils工具类及jdbc.properties配置文件

创建User类

public class User {

private int id;

private String username;

private String password;

private String email;

private String sex;

private String telephone;

private String introduce;

get/set方法省略

login.jsp页面

<%@ page language=\公众java\公众 import=\"大众java.util.\"大众 pageEncoding=\"大众utf-8\"大众%>

<!DOCTYPE HTML PUBLIC \"大众-//W3C//DTD HTML 4.01 Transitional//EN\"大众>

<html>

<head>

<title>上岸窗口</title>

</head>

<body>

<%=request.getAttribute(\公众loginmsg\"大众) %>

<form action=\"大众/day10/login\公众 method=\公众post\公众>

USERNAME:<input type=\"大众text\"大众 name=\"大众username\公众><br>

PASSWORD:<input type=\"大众password\"大众 name=\公众password\"大众><br>

<input type=\"大众submit\"大众 value=\公众上岸\"大众>

</form>

</body>

</html>

LoginServlet类

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 1.获取要求参数 username password

String username = request.getParameter(\"大众username\"大众);

String password = request.getParameter(\公众password\"大众);

// 2.调用UserOperation类中的login方法

UserOperation uo = new UserOperation();

User user = uo.login(username, password);

//3.判断user是否为null来确定是否上岸成功

if(user==null){

//上岸失落败,要求转发到login.jsp页面

request.setAttribute(\"大众loginmsg\公众, \公众上岸失落败\公众);

request.getRequestDispatcher(\"大众/login.jsp\"大众).forward(request, response);

}else{

//上岸成功,重定向到success.jsp

response.sendRedirect(\"大众/day10/success.jsp\"大众);

}

}

UserOperation操作类

public User login(String username, String password) {

User user = null;

// 1.定义sql语句

String sql = \公众select from user where username=? and password=?\"大众;

// 2.查找数据库操作

Connection con = null;

PreparedStatement pst = null;

ResultSet rs = null;

try {

// 2.1获取Connection工具

con = JdbcUtils.getConnection();

// 2.2 获取实行sql语句的PreparedStatement工具

pst = con.prepareStatement(sql);

// 2.3对占位符赋值

pst.setString(1, username);

pst.setString(2, password);

// 2.4实行sql获取ResultSet

rs = pst.executeQuery();

// 2.5操作ResultSet

if (rs.next()) {

user = new User();

user.setId(rs.getInt(\"大众id\"大众));

user.setEmail(rs.getString(\公众email\公众));

user.setUsername(rs.getString(\公众username\公众));

user.setPassword(rs.getString(\"大众password\公众));

user.setSex(rs.getString(\"大众sex\公众));

user.setTelephone(rs.getString(\公众telephone\"大众));

user.setIntroduce(rs.getString(\公众introduce\公众));

}

} catch (SQLException e) {

e.printStackTrace();

} finally {

// 2.6关闭资源

JdbcUtils.closeResource(con,pst,rs);

}

return user;

}

success.jsp页面

<%@ page language=\公众java\"大众 import=\"大众java.util.\"大众 pageEncoding=\"大众utf-8\"大众%>

<!DOCTYPE HTML PUBLIC \"大众-//W3C//DTD HTML 4.01 Transitional//EN\"大众>

<html>

<head>

<title>上岸成功窗口</title>

</head>

<body>

<h1>上岸成功</h1>

</body>

</html>

首次进入登录页面的时候创造最上面显示为null,须要先判断一下loginmsg是否为空,在输出.这段代码用el表达式(来日诰日讲)实现起来特殊大略.

EL 全名为Expression Language

语法:${标识符}

常用功能:获取各种域中存储的数据

jsp写法:<%=request.getAttribute(\"大众loginmsg\"大众);>

el写法:${requestScope.loginmsg}

修正之后的login.jsp

<%@ page language=\公众java\"大众 import=\"大众java.util.\"大众 pageEncoding=\"大众utf-8\"大众%>

<!DOCTYPE HTML PUBLIC \"大众-//W3C//DTD HTML 4.01 Transitional//EN\"大众>

<html>

<head>

<title>上岸窗口</title>

</head>

<body>

${requestScope.loginmsg}

<form action=\"大众/day10/login\"大众 method=\"大众post\"大众>

USERNAME:<input type=\"大众text\"大众 name=\"大众username\公众><br>

PASSWORD:<input type=\公众password\"大众 name=\公众password\"大众><br>

<input type=\公众submit\公众 value=\"大众上岸\"大众>

</form>

</body>

</html>

二.会话技能

会话的先容:

会话可大略理解为:用户开一个浏览器,点击多个超链接,访问做事器多个web资源,然后关闭浏览器,全体过程称之为一个会话

会话的浸染:

每个用户与做事器进行交互的过程中,各自会有一些数据,程序要想办法保存每个用户的数据。

例如:用户点击超链接通过一个servlet购买了一个商品,程序该当保存用户购买的商品,以便于用户点结帐servlet时,结帐servlet可以得到用户商品为用户结帐

会话技能会为两类

Cookie

Cookie是客户端技能,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。
当用户利用浏览器再去访问做事器中的web资源时,就会带着各自的数据去。
这样,web资源处理的便是用户各自的数据了。

Session

Session是做事器端技能,利用这个技能,做事器在运行时可以为每一个用户的浏览器创建一个其独享的session工具,由于session为用户浏览器独享,以是用户在访问做事器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问做事器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户做事。

三.cookie

1. cookie的先容

什么是cookie

Cookie最早是网景公司的前雇员Lou Montulli在1993年3月的发明。

Cookie是由做事器端天生,发送给User-Agent(一样平常是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次要求同一网站时就发送该Cookie给做事器(条件是浏览器设置为启用cookie)。
Cookie名称和值可以由做事器端开拓自己定义,对付JSP而言也可以直接写入jsessionid,这样做事器可以知道该用户是否合法用户以及是否须要重新登录等,做事器可以设置或读取Cookies中包含信息,借此掩护用户跟做事器会话中的状态。

cookie与http

cookie与http协议关系

Cookie是Http协议制订的,并不是Java措辞独占的,PHT、.NET中也利用了cookie技能,因此只假如和HTTP协议干系,那么就可以利用cookie技能。

我们知道cookie是做事器创建的一个键值对,并保存在浏览器端。
那么做事器是如何将cookie发送给浏览器的呢?

在做事器端先创建cookie,如 Cookie cookie=new Cookie(String name,String value),个中Cookie可以在javaeeAPI中查到的,详情可参考java_ee API。
然后再通过response工具将cookie信息作为相应头发送到浏览器端。
我们可以通过HttpWatch抓包工具查看相应信息,可以创造cookie是基于一个Set-Cookie相应头事情的,由于Set-Cookie相应头可以有多个,以是我们可以通过response.addHeader(String name,String value)方法发送Set-Cookie相应头,例如,有两个cookie,分别为one=aaa,two=bbb,个中one、two是cookie的名称,aaa、bbb是cookie的值。
发送相应头如下所示:

response.addHeader(“Set-Cookie”,”one=aaa”);

response.addHeader(“Set-Cookie”,”two=bbb”);

当浏览器再次访问做事器时,会将cookie清偿给做事器。
那么浏览器是如何将cookie带给做事器的呢?实在通过Cookie要求头通报过去的。
要求头Cookie与相应头Set-Cookie有差异,多个cookie对应多个Set-Cookie相应头,但是只对应一个Cookie要求头,格式为:Cookie:one=aaa; two=bbb。
即多个cookie之间用分号和空格隔开。

须要把稳的是:cookie是不能跨浏览器的。
例如,张三首先利用IE浏览器访问做事器,做事器发送了一个cookie,这个cookie只会保存在IE浏览器,如果再利用火狐浏览器访问做事器,做事器会再发送一个cookie个火狐浏览器,在火狐浏览器中不能获取IE浏览器中的cookie,同理IE浏览器也获取不到火狐浏览器中的cookie。

http协议规定

Http协议对Cookie做了一些规定,如下所示:

a. 一个Cookie的大小,最大为4KB;

b. 一个做事器最多向一个浏览器保存20个Cookie;

c. 一个浏览器最多可以保存300个Cookie。

我们知道,浏览器将做事器发送过来的cookie保存在本地磁盘,如果cookie过多,一定会加大浏览器的压力,因此Http协议对Cookie做了以上规定。

但是,目前浏览器之间由于竞争,很多都在一定范围内违反了Http规定,例如,一个浏览器最多保存的Cookie个数超过300个。
但是也不会涌现浏览器许可一个Cookie的大小超过4GB。

2. cookie常用api及其事理

cookie是由做事器天生,通过相应回去的. set-cookie:akey=avalue

浏览器再次访问做事器的时候,通过一定的规则携带不同的cookie 要求头: cookie: akey=avalue

javax.servlet.http.Cookie类用于创建一个Cookie,response接口中也定义了一个addCookie方法,它用于在其相应头中增加一个相应的Set-Cookie头字段。
同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。

布局方法

Øpublic Cookie(String name, String value):布局带指定名称和值的 cookie。

Cookie cookie= newCookie(String key,String value);

写到浏览器

response.addCookie(Cookie cookie);

获取cookie

Cookie [] cookies=request.getCookies();

成员方法

Øpublic String getName():返回(获取) cookie 的名称(key)

Øpublic String getValue():返回(获取) cookie 的值。

Øpublic void setMaxAge(int expiry):设置 cookie 的最大生存韶光,以秒为单位(持久化cookie)

Øpublic void setPath(String uri):指定客户端该当返回 cookie 的路径。
(设置路径)

代码实现

案例:看下cookie是如何利用的.

在day10工程下创建一个CookieDemo1Servlet,写入以下代码:

//1.创建cookie

Cookie cookie=new Cookie(\"大众cookieName\公众,\公众cookieValue\公众);

//2.通过response工具将cookie相应到浏览器

response.addCookie(cookie);

然后通过抓包工具看下:

当在浏览器上访问http://localhost/day10/cookieDemo1时,抓取到的http要求与相应信息如下:

要求信息:

GET /day10/cookieDemo1 HTTP/1.1

Accept: text/html, application/xhtml+xml, /

Accept-Language: zh-CN

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Accept-Encoding: gzip, deflate

Host: localhost

Connection: Keep-Alive

相应信息

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Set-Cookie: cookieName=cookieValue

Content-Length: 0

Date: Tue, 12 May 2015 05:26:53 GMT

再次访问此页面

要求信息:

GET /day10/cookieDemo1 HTTP/1.1

Accept: text/html, application/xhtml+xml, /

Accept-Language: zh-CN

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Accept-Encoding: gzip, deflate

Host: localhost

Connection: Keep-Alive

Cookie: cookieName=cookieValue

通过以上剖析,我们通过下面图进行总结:

实行流程:

浏览器第一次访问做事器

做事器天生cookie,通过相应信息返回浏览器 键值对

浏览器再次访问做事器的时候,通过一定的规则携带不同的cookie 要求头携带

把稳:

cookie不能跨浏览器

cookie默认浏览器关闭的时候消亡

cookie不支持中文

3. cookie的持久化

持久化

如果创建了一个cookie,并将他发送到浏览器,默认情形下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。

若希望浏览器将该cookie存储在磁盘上,则须要利用Cookie类的setMaxAge方法,并给出一个以秒为单位的韶光。

setMaxAge(int expiry)以秒为单位的韶光

0代表的是删除持久cookie,把稳,删除cookie时,path路径必须同等,否则不会删除

-1代表的是浏览器关闭后失落效.

路径:

Cookie的路径是在做事器创建Cookie时设置的,它的浸染是决定浏览器访问做事器的某个资源时,须要将浏览器端保存的那些Cookie归还给做事器,可以通过Cookie类的setPath方法来设置cookie的路径.

关于路径包含关系

setPath(path):根据路径的不同携带不同cookie

把稳:路径必须以\"大众/\"大众开始,以\"大众/\"大众结尾

默认的路径:

从项目名称开始,到访问的页面(serlvet)结束之间的末了一个\公众/\"大众结束

例如:

http://localhost/day11/remplus

cookie的默认路径: /day11/

http://localhost/day11/a/b/c/d.jsp

cookie的默认路径为:/day11/a/b/c/

练习:

例如,浏览器中保存如下几个cookie,它们的路径分别是:

aCookie.path=/day10/

bCookie.path=/day10/jsps/

cCookie.path=/day10/jsps/cookie/

访问路径是:http://localhost:8080/day10/index.jsp

浏览器发送给做事器的cookie有:aCookie;

访问路径是:http://localhost:8080/day10/jsps/a.jsp

浏览器发送给做事器的cookie有:aCookie,bCookie;

访问路径是:http://localhost:8080/day10/jsps/cookie/b.jsp

浏览器发送给做事器的cookie有:aCookie,bCookie,cCookie。

4. 案例--记录上次访问韶光

功能描述

当访问day10工程下的某一个servlet时,会显示出上一次访问这个资源的韶光。

案例剖析

利用到的知识点剖析

Cookie cookie=new Cookie(); 创建cookie

response.addCookie() 将cookie添加到http相应中

request.getCookies(); 获取所有的cookie

代码实现(1)

VisitServlet

public class VisitServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//1.得到系统当前韶光

Date date=new Date();

//2.创建一个cookie

Cookie cookie=new Cookie(\"大众time\公众,date.getTime()+\"大众\公众);

//3.将 cookie通过response相应到浏览器端

response.addCookie(cookie);

}

}

ShowTimeServlet

public class ShowTimeServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//设置相应编码

response.setContentType(\"大众text/html;charset=utf-8\"大众);

//1.得到名称叫time的cookie

Cookie[] cs = request.getCookies();

//2.遍历cs,得到cookie

for(Cookie c:cs){

if(\"大众time\"大众.equals(c.getName())){//判断cookie的名称是否有叫time

long time=Long.parseLong(c.getValue()); //得到名称叫time的cookie的value

Date date=new Date(time); //布局出新的韶光

response.getWriter().write(date.toLocaleString());

return;

}

}

response.getWriter().write(\"大众第一次访问:\公众+new Date().toLocaleString());

}

}

上面的代码已经实现了我们的需求,但是欠妥的地方是还得须要单独访问一下才知道上次的韶光.我们完备可以把两个合二为一

public class ShowCurrentTimeServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

// 1.设置相应编码

response.setContentType(\公众text/html;charset=utf-8\"大众);

// 2.获取一个名称叫time的cookie.

Cookie cookie = findCookieByName(\"大众time\"大众, request.getCookies());

Date now = new Date();

if (cookie == null) {

// 解释第一次访问

response.getWriter().write(\"大众第一次访问韶光是:\公众 + now.toLocaleString());

} else {

// 不是第一次访问

long time = Long.parseLong(cookie.getValue());

response.getWriter().write(\公众上次访问韶光是:\公众 + new Date(time).toLocaleString());

}

// 须要将这时访问的韶光存储到cookie中。

cookie = new Cookie(\"大众time\"大众, now.getTime() + \"大众\"大众);

//持久化cookie

//cookie.setMaxAge(6060247);

cookie.setMaxAge(0);//删除cookie

response.addCookie(cookie);

}

// 根据名称查找cookie

private Cookie findCookieByName(String name, Cookie[] cs) {

if (cs == null || cs.length == 0) {

return null;

}

for (Cookie c : cs) {

if (name.equals(c.getName())) {

return c;

}

}

return null;

}

}

代码实现(2)

RemServlet

package cn.itcast.cookie.b_rem;

import java.io.IOException;

import java.util.Date;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

/

记录韶光

@author Administrator

/

public class RemSerlvet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//0.设置编码

response.setContentType(\公众text/html;charset=utf-8\"大众);

//1.天生cookie

Cookie c=new Cookie(\"大众lastTime\公众, new Date().getTime()+\公众\"大众);

//1.1设置生存韶光

c.setMaxAge(3600);

//2.写回去

response.addCookie(c);

//3.提示信息

response.getWriter().print(\"大众韶光已记录\"大众);

}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

}

ShowServlet

package cn.itcast.cookie.b_rem;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Date;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

/

展示remservlet末了一次访问韶光

@author Administrator

/

public class ShowServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//0.设置编码

response.setContentType(\"大众text/html;charset=utf-8\"大众);

PrintWriter w = response.getWriter();

//1.获取指定的cookie

Cookie[] cookies=request.getCookies();

if(cookies!=null){

for (Cookie c : cookies) {

if(\"大众lastTime\"大众.equals(c.getName())){

//3.提示信息

//3.1.有cookie提示信息

//获取值

String value = c.getValue();

//转成long

long l = Long.parseLong(value);

//写信息

w.print(\公众您上次访问的韶光为:\公众+new Date(l).toLocaleString());

return;

}

}

}

//3.2没有cookie 提示信息

w.print(\公众您还没有访问过remservlet\"大众);

}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

}

两个合二为一

Cookie工具类

package cn.itcast.util;

import javax.servlet.http.Cookie;

/

cookie工具类

@author Administrator

/

public class CookieUtils {

/

从数组中获取指定名称的cookie

@param name cookie名称

@param cookies cookie数组

@return cookie

/

public static Cookie getCookieByName(String name,Cookie[] cookies){

//判读cookie是否为空

if(cookies!=null){

//不为空

for (Cookie c : cookies) {

if(name.equals(c.getName())){

return c;

}

}

}

return null;

}

}

两个Servlet合二为一

package cn.itcast.cookie.c_rem_plus;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Date;

import javax.servlet.ServletException;

import javax.servlet.http.Cookie;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import cn.itcast.util.CookieUtils;

public class RemPlusServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//0.设置编码

response.setContentType(\"大众text/html;charset=utf-8\"大众);

PrintWriter w = response.getWriter();

//1.获取指定cookie

Cookie c=CookieUtils.getCookieByName(\公众lastTime\公众, request.getCookies());

//2.判断cookie

if(c==null){

//2.1cookie为空 提示第一次访问

w.print(\"大众您是第一次访问!\"大众);

}else{

//2.2cookie不为空 把当前韶光打印到页面上

w.print(\"大众您上一次访问的韶光为:\"大众+(new Date(Long.parseLong(c.getValue())).toLocaleString()));

}

//3.将当前韶光记录下

c=new Cookie(\"大众lastTime\"大众, new Date().getTime()+\"大众\"大众);

c.setMaxAge(3600);

//写回浏览器

response.addCookie(c);

}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

}

5. 案例--查看历史记录

功能描述

做一个商品页面,当我们访问后,在页面上点击查看商品浏览记录后,可以查看到以前浏览过的商品信息

案例剖析

利用到的知识点剖析

超连接带参数 <a href=”/day10/book?id=1”>

获取要求参数 request.getParameter()

创建Cookie cookie=new Cookie()

获取所有cookie request.getCookies()

将cookie相应到浏览器端 response.addCookies()

代码实现

book.jsp

<a href=\公众/day10/book?id=1\"大众>西游记</a><br>

<a href=\"大众/day10/book?id=2\公众>水浒传</a><br>

<a href=\公众/day10/book?id=3\公众>红楼梦</a><br>

<a href=\公众/day10/book?id=4\"大众>三国演义</a><br>

<hr>

<a href=\公众/day10/bookHistory.jsp\公众>查看浏览商品记录</a>

BookServlet

public class BookServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType(\"大众text/html;charset=utf-8\公众);

// 1.得到商品的id

String id = request.getParameter(\"大众id\"大众);

// 2.将id值保存到cookie的名称叫ids这个cookie中。

Cookie cookie = CookieUtils.findCookieByName(\"大众ids\"大众,

request.getCookies());

if (cookie == null) { // 第一次没有ids,就得到null

cookie = new Cookie(\"大众ids\"大众, id);

} else { // 不是第一次,就得到的不是null.

// 3.得到cookie的value值。

String ids = cookie.getValue();

// 判断id是否重复

List<String> list = Arrays.asList(ids.split(\"大众-\公众)); //将数组转换成凑集。

if (!list.contains(id)) {

ids = ids + \"大众-\"大众 + id;

}

cookie = new Cookie(\公众ids\"大众, ids);

}

response.addCookie(cookie);

response.getWriter().write(\"大众商品展示成功,<a href='/day10/book.jsp'>连续浏览</a>\公众);

}

}

bookHistory.jsp

<%

String[] books = { \"大众西游记\公众, \"大众水浒传\"大众, \"大众红楼梦\公众, \"大众三国演义\"大众 };

//1.得到所有的cookie,得到名称叫ids的cookie

Cookie[] cs = request.getCookies();

Cookie c = CookieUtils.findCookieByName(\"大众ids\公众, cs);

if (c == null) {

//没有浏览记录

out.print(\"大众无浏览记录\"大众);

} else {

//有浏览记录

//2.得到cookie的value

out.print(\"大众浏览记录如下:<br>\公众);

String ids = c.getValue(); //1-2-4

String[] id = ids.split(\"大众-\"大众);

for (int i = 0; i < id.length; i++) {

int bookid = Integer.parseInt(id[i]) - 1;

out.print(books[bookid] + \公众<br>\公众);

}

}

%>

四.session

1. session的先容

首先,HttpSession是javax.servlet.http包下的一个接口。
从名字来看,我们可以知道HttpSession与Http协议有一定的关系,但是它并不是由Http协议定义的,而是由Javaweb供应。
我们可以在JavaEE api中查看它的详细信息。

其次,HttpSession是用来进行会话跟踪的接口,我们之前也学过其余一个与会话干系的技能Cookie。
在Cookie先容中我们理解到,Cookie是由Http协议制订的,在要求信息和相应信息等分别对应了Cookie要求头和Set-Cookie相应头,并且Cookie是由做事器创建,保存在客户端。
而HttpSession工具也是由做事器创建,但是与Cookie不同的是,它保存在做事器端。

HttpSession工具是Servlet的三大域工具之一,其他两个域工具是HttpServletRequest和ServletContext。
这三个域中,request的域范围最小,它的域范围是全体要求链,并且只在要求转发和包含时存在;session域工具的域范围是一次会话,而在一次会话中会产生多次要求,因此session的域范围要比request大;application的域范围是最大的,由于一个web运用只有唯一的一个application工具,只有当web运用被移出做事器或做事器关闭它才去世亡,它的域范围是全体运用。

2. session常用api,生命周期及其事理

session底层是依赖Cookie的,如果浏览器禁用Cookie则session会依赖URL重写。
详情我们会在后面先容。
如何获取HttpSession工具?在做事器端,例如在Servlet中,我们通过request工具的getSession()方法获取做事器为当前用户创建的session工具,即:HttpSession session=request.getSession()。
而在jsp中,session是jsp的内置工具,不用获取就可以直策应用。

session的常用api

我们知道每一个域工具都会有以下三个方法,HttpSession也不例外:

Øvoid setAttribute(String name,Object value):向域中添加域属性;

ØObject getAttribute(String name):从域中获取指定名称的属性值;

ØVoid removeAttribute(String name):移出域中指定名称的域属性

接下来,咱们来做个案例看下session是如何利用的.

在day10工程下创建一个SessionDemo1Servlet,写入以下代码:

// 1.获取session

HttpSession session = request.getSession();

// 2.向session中存储数据据

session.setAttribute(\"大众name\公众, \"大众tom\公众);

在day10工程下创建一个SessionDemo2Servlet,写入以下代码:

// 1.获取session

HttpSession session = request.getSession();

// 2.获取session中信息

String name = (String) session.getAttribute(\公众name\"大众);

System.out.println(name);

接下来利用抓包工具看下:

打开浏览器访问http://localhost/day10/sessionDemo1

要求信息:

GET /day10/sessionDemo1 HTTP/1.1

Accept: text/html, application/xhtml+xml, /

Accept-Language: zh-CN

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Accept-Encoding: gzip, deflate

Host: localhost

Connection: Keep-Alive

相应信息:

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Set-Cookie: JSESSIONID=2021FCEFDF31A6DAC8E7CC201F7AF404; Path=/day10/; HttpOnly

Content-Length: 0

Date: Tue, 12 May 2015 21:58:39 GMT

再次访问http://localhost/day10/sessionDemo2:

要求信息:

GET /day10/sessionDemo2 HTTP/1.1

Accept: text/html, application/xhtml+xml, /

Accept-Language: zh-CN

User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)

Accept-Encoding: gzip, deflate

Host: localhost

Connection: Keep-Alive

Cookie: JSESSIONID=2021FCEFDF31A6DAC8E7CC201F7AF404

相应信息

HTTP/1.1 200 OK

Server: Apache-Coyote/1.1

Content-Length: 0

Date: Tue, 12 May 2015 22:00:46 GMT

程序实行完成后,在掌握台上打印出tom.

session工具的创建剖析

如果要求时,cookie中有jsessionid这个cookie,那么我们通过request.getSession()时,

就会根据jsessionid值查找session的id,如果查找到,会利用已有的,如果没有查找到,会创建。

如果要求时,cookie中没有jsessionid这个cookie,那么request.getSession()就会创建一个新的session工具.

session工具的销毁剖析

浏览器关闭了,session工具不会销毁的,session的销毁与关闭浏览器无关.

session工具销毁办法:

1.关闭做事器

2.默认超时

在tomcat/conf/web.xml文件中设置了session默认超时时间

<session-config>

<session-timeout>30</session-timeout>

</session-config>

默认30分钟超时

3.可以设置session超时时间(以秒为单位)

void setMaxInactiveInterval(int interval)

4.销毁session

invalidate();

session的事理

第一次访问,要求中不存在jsessionid值,这时发送要求到做事器端就会创建HttpSession工具.工将session的id值存储到cookie中相应到浏览器端

当下一次在要求时,这时会在要求中存在jsessionid值,到做事器端后,就会根据jsessionid值,查找指定id的session工具。

如果查找到,就直策应用,而不会重新创建。
如果没有查找到,会重新创建.

HttpSession session=request.getSession();

扩展

HttpSession session=request.getSession(true/false);

如果值是true与无参数一样.

如果是false,它不会重新创建session工具,会返回null值。
(用的很少)

3. 案例--购物车

功能描述

有一个商品页面,可以点击超连接将商品添加到购物车,并可以查看购物车中商品信息

案例剖析

利用到的知识点剖析

购物车利用的数据构造 Map<String,Integer>

获取session request.getSession()

办理要求参数乱码 new String(name.getBytes(“iso8859-1”),”utf-8”)

代码实现

Productlist.jsp

<table border='1' width=\"大众65%\公众>

<tr>

<td>商品名称</td>

<td>操作</td>

</tr>

<tr>

<td>洗衣机</td>

<td><a href=\"大众/day10/addProductToCart?name=洗衣机\公众>添加到购物车</a></td>

</tr>

<tr>

<td>电视机</td>

<td><a href=\"大众/day10/addProductToCart?name=电视机\"大众>添加到购物车</a></td>

</tr>

<tr>

<td>缝纫机</td>

<td><a href=\"大众/day10/addProductToCart?name=缝纫机\公众>添加到购物车</a></td>

</tr>

<tr>

<td>打火机</td>

<td><a href=\"大众/day10/addProductToCart?name=打火机\公众>添加到购物车</a></td>

</tr>

</table>

AddProductToCartServlet

public class AddProductToCartServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doPost(request, response);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType(\"大众text/html;charset=utf-8\"大众);

// 1.获取商品名称

String name = request.getParameter(\"大众name\公众);

// 2.办理乱码

name = new String(name.getBytes(\"大众iso8859-1\公众), \"大众utf-8\公众);

// 3.获取购物车

HttpSession session = request.getSession();

Map<String, Integer> cart = (Map<String, Integer>) session

.getAttribute(\公众cart\公众);

// 4.判断购物车是否存在

Integer count = null; //代表的是商品数量

if (cart == null) {

cart = new HashMap<String, Integer>();

// cart.put(name, 1);

count = 1;

} else {

// 如果购物车存在,我们须要考虑商品在购物车中是否存在。

count = cart.get(name);

if (count == null) {

// 解释购物车中无此商品

count = 1;

} else {

// 如果有此商品,将数量加1

count += 1;

}

}

cart.put(name, count);

// 5.将购物车存储到session中.

session.setAttribute(\公众cart\"大众, cart);

response.getWriter().write(\"大众添加成功,<a href='/day10/productlist.jsp'>连续购物</a>,<a href='/day10/cart.jsp'>查看购物车</a>\"大众);

}

}

cart.jsp

<table border='1' width=\"大众65%\公众>

<tr>

<td>商品名称</td>

<td>商品数量</td>

</tr>

<%

//1.得到session

HttpSession mysession = request.getSession();

//2.得到购物车

Map<String, Integer> cart = (Map<String, Integer>) mysession

.getAttribute(\"大众cart\公众);

//3.判断购物车是否存在

if (cart == null || cart.size() == 0) {

out.print(\"大众购物车中无商品<br>\"大众);

} else {

//4.遍历cart

for (String name : cart.keySet()) {

out.print(\"大众<tr><td>\公众 + name + \公众</td><td>\"大众 + cart.get(name)

+ \公众</td></tr>\"大众);

}

}

%>

</table>

4. 案例--验证码

5. url重写

url重写先容

如果浏览器不支持Cookie或用户阻挡了所有Cookie,可以把会话ID附加在HTML页面中所有的URL上,这些页面作为相应发送给客户。
这样,当用户单击URL时,会话ID被自动作为要求头的一部分而不是作为头行发送回做事器。
这种方法称为URL重写(URL rewriting)。

url重写浸染

当客户机不接管cookie时,server就利用URL重写作为会话跟踪的基本办法.URL重写,添加了附加数据(会话ID)到要求的URL路径上.

会话ID必须被编码作为该URL字符串中的路径参数。
该参数的名称为jsessionid,

大略说便是cookie禁用了jsessionid就不能携带,那么每次要求,都是一个新的session工具。

如果想要利用同一个session工具,可以利用url重写.

url重写实现

response. encodeRedirectURL(java.lang.String url)

用于对sendRedirect方法后的url地址进行重写。

response. encodeURL(java.lang.String url)

用于对表单action和超链接的url地址进行重写

修正jsp文件的默认字符编码

修正文件的打开办法

配套学习视频等IT资源关注【Java帮帮】QQ空间和【Java帮帮】微信"大众号