JSP&Servlet--Servlet(2)

来源:互联网 发布:巴克利职业生涯数据 编辑:程序博客网 时间:2024/06/07 01:22

1.处理Cookie

HTTP协议的无连接性要求出现一种保存C/S间状态的机制

HTTP的无连接性(客户端的浏览器可以通过输入网址连接网站服务器,当客户端从服务器上拿到内容之后,该连接就断开了,例如购物网站再一个网址选择东西之后,服务器将信息反馈给客户端,当去另一个页面结账时就会不知道你买了什么),解决办法:可以利用Cookie先将信息保存在客户端,只允许写文本文档,客户端可以阻止服务器写内容,只能拿自己webapp写入的东西。cookie分两种:属于窗口/子窗口;属于文本。

Cookie:保存到客户端的一个文本文件,与特定客户相关。


乱码的解决:

生成cookie:

java.sql中的方法 String username =URLEncoder.encoder(request.getParmeter("username"),"utf-8");

写在上述方法的最前面:

request.setCharacterEncoder("utf-8");

解析cookie:c  cookie c:cookies

request.setCharacterEncoder("utf-8");

username = URLDecoder.decoder(c.getValue(),"utf-8");

Cookie以"名-值"对的形式保存数据,创建Cookie:new Cookie(name,value),可以使用Cookie的setXXX方法来设定一些相应的值:

seName(String name)/getName()

setValue(String value)/getValue()

setMaxAge(int age)/getMaxAge()

利用HttpServletResponse的addCookie(Cookie)方法将它设置到客户端

利用HttpServletRequest的getCookie()方法来读取客户端的所有Cookie,返回一个Cookie数组

如下例:

首先写一个设置Cookie的文件

public class SetCookie extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        // 向客户端写入Cookie,共6个        for (int i = 0; i < 3; i++) {            // 3个没有设置时间的Cookie(或者设置成-1),属于本窗口及其子窗口            Cookie cookie = new Cookie("Session-Cookie-" + i, "Cookie-Value-S" + i);            response.addCookie(cookie);            // 以下3个Cookie设置了时间(3600秒,1小时),属于文本,别的窗口也可以访问到这些Cookie            cookie = new Cookie("Persistent-Cookie-" + i, "Cookie-Value-P" + i);            cookie.setMaxAge(3600);            response.addCookie(cookie);        }        response.setContentType("text/html;charset=gb2312");        PrintWriter out = response.getWriter();        String title = "Setting Cookies";        out.println("<html><head><title>设置Cookie</title></head>"                + "<body>" + title + "<br>"                + "There are six cookies associates with this page.<br>"                + "to see them,visit the <a href='ShowCookie'>\n"                + "<code>ShowCookie</code> servlet</a>"                + "</body></html>");    }}

然后读取Cookie

public class ShowCookie extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        response.setContentType("text/html;charset=gb2312");        PrintWriter pw = response.getWriter();        String title = "Active Cookies";        pw.println("init");        pw.println("<html><head><title>读取客户端</title></head>"                + title                + "\n" + "<table border=1 align=center>\n"                + "<TH>Cookie Name<TH>Cookie Value" + "<br>");        // 读取客户端的所有Cookie        Cookie[] cookies = request.getCookies();        if (cookies != null) {            Cookie cookie;            for (int i = 0; i < cookies.length; i++) {                cookie = cookies[i];                pw.println("<tr>\n" + "<td>" + cookie.getName() + "</td>\n"                        + "<td>" + cookie.getValue() + "</td></tr>\n");            }        }        pw.println("</table>\n<body><html>");    }}

然后在浏览器上输入http://localhost:8080/TestHTTP/servlet/SetCookie就设置了cookie到客户端,点击ShowCookieservlet 便可读取cookie

如果现在在开一个ShowCookieservlet只能看见Persistentcookie,因为在该cookie中session是没有设置生存周期,跟第一个开的网页是同步的,而persistent是有生存周期的,被存在内存中,其他网页可以读取。但是如果在第一个showcookieservlet中ctrl+n(new一个新网页),此时会显示session的内容,因为这种方式的打开是存在一种父子关系。

在内存中储存的cookie的内容:



1.如果把ShowCookie的web.xml文件的url-pattern改成/ShowServlet,意味着ShowCookie比SetCookie高一个等级,此时先访问servlet/SetCookie,在访问ShowCookie,此时ShowCookie上什么都没有。

 2.如果把SetCookie的web.xml文件的url-pattern改成/SetServlet,此时先访问SetCookie,在访问servlet/ShowCookie,可以访问到cookie

结论:一个servlet/JSP设置的cookie能够被同一个路径下面或者是子路径下面的servlet/jsp读到(路径=URL,路径!=真实的文件路径)

2.Session

也是用来记录一系列的状态,记录在服务器端,cookie记录在客户端(可以随便改,删,不稳定)。在某段时间一连串客户端与服务器端的交易。

当访问服务器端时,服务器端会给你开一块内存,就是session,而这块内存是和浏览器的窗口或子窗口关联在一起,服务器端会给浏览器创建一个独一无二的号码,一一对应。

session两种实现方法一个通过cookie实现。二:在Jsp/Servlet中,如果浏览器不支持cookie,可以通过URL重写来实现,就是将一些额外数据追加到表示会话的每一个URL末尾,服务器在该标识符与其存储的有关的该会话的数据之间建立关联。如hello.jsp?jsessionid=1234。

规则:

如果浏览器支持cookie,创建session的时候会把session保存在cookie里

如果不支持cookie,必须自己编程使用URL重写的方式实现session,

response.encodeURL()  转码 URL后面加sessionID

session不像Cookie拥有路径访问的问题,同一个Application下的Servlet/jsp可以共享同一个session,前提是同一个客户端窗口。

可以通过程序来终止一个会话,如果客户端在一定时间内没有操作,服务器会自动终止会话。

HttpServletRequest中session的管理方法

getRequestedSessionId();返回随客户端请求到来的会话ID,可能与当前会话ID相同,也可能不同。

getSession(booleanisNew);如果会话已经存在,则返回一个HttpSession,如果不存在并且isNew为true,则会新建一个HttpSession

isRequestedSessionIdFromCookie();当前的SessionID如果是从cookie获得,为true

isRequestedSessionIdFromURL();当前的Session ID如果是从URL获得,为true

isRequestedSessionIdValid();如果客户端的会话ID代表的是有效会话,则返回true。否则(比如,会话过期或根本不存在),返回flase。

HttpSession的常用方法:

 getAttribute(String)/getAttributeNames()//得到名为String的值
getCreationTime() //返回session的创建时间
getId() //拿到该session的ID号
getMaxInactiveInterval()//获得session的最大存活时间,默认是1800秒!就是说你不动浏览器,在三十分钟后它会自动消毁

isNew() //是不是新创建的
setAttribute(String, Object) //设置一个名-值对
setMaxInactiveInterval(int interval)//设置最大存活时间秒数,负值表示一直存在
getLastAccessedTime() //返回最近的一次访问时间

 

先设置一个SessionInfoServlet来创建session:

public class SessionInfoServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        HttpSession mySession = request.getSession(true);        //什么时候创建一个session,flase就是要拿这个session,如果没有不会创建,true如果没有创建一个,如果有就拿这个session        response.setContentType("text/html");        PrintWriter out = response.getWriter();        String title = "Session Info Servlet";        out.println("<html>");        out.println("<head>");        out.println("<title>Session Info Servlet</title>");        out.println("</head>");        out.println("<body>");        out.println("<h3>Session Infomation</h3>");        out.println("New Session:" + mySession.isNew() + "<br>");        out.println("Session Id:" + mySession.getId() + "<br>");        out.println("Session Create Time:" + new Date(mySession.getCreationTime()) + "<br>");        out.println("Session Last Access Time:" + new Date(mySession.getLastAccessedTime()) + "<br>");        out.println("<h3>Request Infomation</h3>");        out.println("Session Id From Request:" +request.getRequestedSessionId() + "<br>");        // 返回随客户端请求到来的会话ID        out.println("Session Id Via Cookie:" +request.isRequestedSessionIdFromCookie() + "<br>");        // 当前的Session ID如果是从cookie获得,为true        out.println("Session Id Via URL:" +request.isRequestedSessionIdFromURL() + "<br>");        // 当前的Session ID如果是从URL获得,为true        out.println("Valid Session Id:" +request.isRequestedSessionIdValid() + "<br>");        out.println("</body></html>");        out.close();    }}

网页内容:Session Infomation
New Session:true
Session Id:64164718FF1A9286F6496F7939CA5433
Session Create Time:Sun May 03 17:54:02 GMT+08:00 2015
Session Last Access Time:Sun May 03 17:54:02 GMT+08:00 2015
Request Infomation
Session Id From Request:null
Session Id Via Cookie:false
Session Id Via URL:false
Valid Session Id:false

访问showCookie时,会出现cookie,说明创建session时,会把sessionID存在cookie中,当窗口关闭后该session就不存在了,当再起其他的窗口,sessionID不会相同。

当阻止所有cookie时,打开后每次刷新都会设置一个新的SessionID

 

如果在 out.println("《/body》《/html》");前加上out.println("《a href=" +response.encodeURL("SessionInfoServlet") +"》refresh《/a》");此时不允许Cookie的情况下,点击refresh刷新session就不会变。但在URL地址变成http://localhost:8080/TestHTTP/servlet/SessionInfoServlet;jsessionid=3021C03B1E8159DB27BC8B919F0DF104这便是所谓的URL重写。

session过期:一个Session存在的时长,在web.xml中设置session

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

 ShowSession例子程序:

public class ShowSession extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        response.setContentType("text/html;charset=gb2312");        PrintWriter out = response.getWriter();        String str = "Session Tracking Example";        String heading;        // 如果会话已经存在,则返回一个HttpSession;否则创建一个新的        HttpSession session = request.getSession(true);        // 从当前session中读取属性accessCount的值        Integer accessCount = (Integer) session.getAttribute("accessCount");        if (accessCount == null) {            accessCount = new Integer(0);            heading = "Welcome newUser";        } else {            heading = "Welcome Back";            accessCount = new Integer(accessCount.intValue() + 1);        }        // 向当前session中插入键(key,属性)值(value)对        session.setAttribute("accessCount", accessCount);        out.println("<html><head><title>Session追踪</title></head>"                + "<body>" + heading + "<br>"                + "Information on Your Session"                + "\n" + "<table border=1 align=center>\n"                + "<TH>Info Type<TH>Value" + "<br>"                + "<tr>\n" + "<td>ID</td>\n"                + "<td>" + session.getId() + "</td></tr>\n"                + "<tr>\n" + "<td>CreatTime</td>\n"                + "<td>" + new Date(session.getCreationTime()) + "</td></tr>\n"                //返回值是long,就是一个数值,new data将其转化成日期                + "<tr>\n" + "<td>LastAccessTime</td>\n"                + "<td>" + new Date(session.getLastAccessedTime()) + "</td></tr>\n"                + "<tr>\n" + "<td>Number of Access</td>\n"                + "<td>" + accessCount + "</td></tr>\n"                + "</body></html>");    }}


刷新,数字会逐一增加,当新起一个窗口显示的是0次,因为一个新的窗口就是一个新的session

修改servlet/SessionInfoServlet和/ShowSession,先用sessioninfoservlet创建session,可以用ShowSessions访问。


session的生命周期:

创建:

当客户端第一次访问某个jsp或servlet时候,服务器会为当前回话创建一个sessionid,每次客户端向服务器发送请求时,都会将此sessionid携带过去,服务器会对此sessionid进行校验,判断是否属于同一次会话。

活动:

当某次会话当中通过超链接打开的新页面属于同一次会话。

只要当前会话页面没有全部关闭,重新打开新的浏览器窗口访问同一项目资源时属于同一次会话。

除非本次会话的所有页面都关闭后再重新访问某个jsp或servlet将会创建新的会话。

注意:原有的会话还存在,只是这个旧的sessionid仍然存在于服务器端,只不过在没有客户端会携带他然后交与服务器校验。

销毁:

调用session.invalidate()方法

session过期(超时)

服务器重新启动


设置超时:

tomcat默认session超时时间是30分钟

或者1.session.setMaxInactiveInterval(时间);秒

2.web.xml配置:

    <session-config>        <session-timeout>10</session-timeout>    </session-config>


0 0
原创粉丝点击