Java-Web JSP、Cookie和Session域对象

一、JSP入门

    1.什么是JSP

        JSP(Java Server Pages)是JavaWeb服务器端的动态资源。它与html页面的作用是相同的,显示数据和获取数据。

    2.JSP的组成

    JSP = html + Java脚本(代码片段) + JSP动态标签


    3.JSP语法

        3.1 JSP脚本

                JSP脚本就是java代码片段,分为三种:

        (1)<%...%>:Java语句;

                        java代码片段(常用),用于定义0~N条Java语句!方法内能写什么,它就可以放什么!

        (2)<%=…%>:Java表达式;

                        java表达式,用于输出一条表达式(或变量)的结果。response.getWriter().print( ... );这里能放什么,它就可以放什么!

        (3)<%!...%>:Java定义类成员;

                        声明,用来创建类的成员变量和成员方法(基本不用)

        3.2 多个<%...%>可以通用

                在一个JSP中多个<%...%>是相通的。例如:

  <body>
    <h1>out.jsp</h1>
	<%
		String s = "hello";
	%>
	<%
		out.print(s);
	%>
  </body>

                循环打印表格:

  <body>
    <h1>表格</h1>
	
	<table border="1" width="50%">
		<tr>
			<th>序号</th>
			<th>用户名</th>
			<th>密码</th>
		</tr>
	<%
		for(int i = 0; i < 10; i++) {	
	%>
		<tr>
			<td><%=i+1 %></td>
			<td>user<%=i %></td>
			<td><%=100 + 1 %></td>
		</tr>
	<%
		}
	%>
	</table>
  </body>
    4.JSP原理

        JSP是一种特殊的Servlet,当JSP页面首次被访问时,容器(Tomcat)会先把JSP编译成Servlet,然后再去执行Servlet。所以JSP其实就是一个Servlet!


    5.JSP注释

        格式:<%-- ... --%>

        JSP是需要先编译成.java,再编译成.class的。其中<%-- ... --%>中的内容在JSP编译成.java时会被忽略的,即JSP注释。

        也可以在JSP页面中使用html注释:<!-- … -->,但这个注释在JSP编译成的.java中是存在的,它不会被忽略,而且会被发送到客户端浏览器。但是在浏览器显示服务器发送过来的html时,因为<!-- … -->是html的注释,所以浏览器是不会显示它的。


    6.JSP和Servlet的分工

      * JSP:

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

            作为请求结束页面,例如显示数据。

      * Servlet:

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

    小案例演示:

        客户端请求该jsp页面,输出数字求和

    <form method="post" action="/4.29/AServlet">
    	请输入数字:<input type="text" name="num1"/><br/>
    	请输入数字:<input type="text" name="num2"/><br/>
    	<input type="submit" value="求和" />
    </form>
        该jsp将请求页面发送到AServlet中,AServlet进行数据的处理,然后转发到showSum.jsp中
public class AServlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取请求的参数
		String num1 = request.getParameter("num1");
		String num2 = request.getParameter("num2");
		//把字符串转成Integer类型
		Integer num11 = Integer.valueOf(num1);
		Integer num22 = Integer.valueOf(num2);
		int sum = num11 + num22;
		//把相加的结果保存到request域对象中
		request.setAttribute("sum", sum);
		//转发到showSum.jsp中
		request.getRequestDispatcher("/sum/showSum.jsp").forward(request,
				response);
	}

}
    showSum页面获取到request传递过来的sum值,并输出在客户端中
    <%Integer sum=(Integer)request.getAttribute("sum"); %>
    <h3>和为<%=sum %></h3>

二、Cookie

    1.Cookie概述

        Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。

        Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对。客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie)。当客户端向服务器发出请求时会把所有这个服务器Cookie包含在请求中发送给服务器,这样服务器就可以识别客户端了!


    2.Cookie规范

            Cookie大小上限为4KB;

            一个服务器最多在客户端浏览器上保存20个Cookie

            一个浏览器最多保存300个Cookie;

        注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。

    3.Cookie与HTTP头

        Cookie是通过HTTP请求和响应头在客户端和服务器端传递的:

        Cookie:请求头,客户端发送给服务器端;

            格式:Cookie: a=A; b=B; c=C。即多个Cookie用分号离开;

                Set-Cookie:响应头,服务器端发送给客户端;

                一个Cookie对象一个Set-Cookie:

                    Set-Cookie: a=A

                    Set-Cookie: b=B
    4.Cookie生命

        可以通过setMaxAge(int)来设置Cookie的有效时间。

            cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。

            cookie.setMaxAge(60*60):表示cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时;

            cookie.setMaxAge(0):cookie生命等于0是一个特殊的值,它表示cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过Cookie的setMaxAge(0)来删除这个Cookie。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie。 

    5.Cookie的path

        现在有WEB应用A,向客户端发送了10个Cookie,这就说明客户端无论访问应用A的哪个Servlet都会把这10个Cookie包含在请求中!但是也许只有AServlet需要读取请求中的Cookie,而其他Servlet根本就不会获取请求中的Cookie。这说明客户端浏览器有时发送这些Cookie是多余的!

        可以通过设置Cookie的path来指定浏览器,在访问什么样的路径时,包含什么样的Cookie。

        (1)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/

        (2)设置Cookie路径

        设置Cookie的路径需要使用setPath()方法,例如:

                    cookie.setPath(“/cookietest/servlet”);

如果没有设置Cookie的路径,那么Cookie路径的默认值当前访问资源所在路径,例如:

    访问http://localhost:8080/cookietest/AServlet时添加的Cookie默认路径为/cookietest;

    访问http://localhost:8080/cookietest/servlet/BServlet时添加的Cookie默认路径为/cookietest/servlet;

    访问http://localhost:8080/cookietest/jsp/BServlet时添加的Cookie默认路径为/cookietest/jsp;

    6.Cookie中保存中文

        Cookie的name和value都不能使用中文,如果希望在Cookie中使用中文,那么需要先对中文进行URL编码,然后把编码后的字符串放到Cookie中。

    向客户端响应中添加Cookie

public class BServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) {
		String name;
		try {
			name = URLEncoder.encode("姓名", "UTF-8");
			String value = URLEncoder.encode("张三", "UTF-8");
			Cookie c = new Cookie(name, value);
			c.setMaxAge(3600);
			response.addCookie(c);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

    从客户端请求中获取Cookie

public class CServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		Cookie[] cs = request.getCookies();
		if (cs != null) {
			for (Cookie cookie : cs) {
				String name = URLDecoder.decode(cookie.getName(), "UTF-8");
				String value = URLDecoder.decode(cookie.getValue(), "UTF-8");
				String s = name + ":" + value + "<br/>";
				response.getWriter().print(s);
			}
		}
	}
}

三、HttpSession

    1.HttpSession概述

      * HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!

     * HttpSession是Servlet三大域对象之一(request、session、application(ServletContext))。

      * HttpSession底层依赖Cookie,或是URL重写!

    2.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);

    3.登陆案例

需要的页面:

    login.jsp:登录页面,提供登录表单;

    succ1.jsp:主页,显示当前用户名称,如果没有登录,退回到login页面;

    LoginServlet:在login.jsp页面提交表单时,请求本Servlet。在本Servlet中获取用户名、密码进行校验,如果用户名、密码错误,显示“用户名或密码错误”,如果正确保存用户名session中,然后重定向到succ1.jsp;

login.jsp

<!--获取登陆过后给用户名设置的Cookie值,下次方便登陆-->
	<%
		String uname="";
		Cookie[] cookie=request.getCookies();
		if(cookie!=null){
			for(Cookie coo:cookie){
				if("username".equals(coo.getName())){
					uname=coo.getValue();
				}
			}
		}
	%>
<!--获取loginServlet发送过来的数据并显示在浏览器上 -->
	<h3>登陆界面</h3><br />     
	<% String message="";
		String judge=(String)request.getAttribute("judge");
		if(judge!=null){
			message=judge;
		}
	%>
	<font color="red"><b><%=message%></b></font>
	<form action="/4.29/loginServlet" method="post">
				<%-- 把cookie中的用户名显示到用户名文本框中 --%>
		用户名:<input type="text" name="username" value="<%=uname%>" /><br /> 
		密    码:<input type="password" name="password" /><br /> 
		<input type="submit" value="登陆" />
	</form>

loginServlet

public class loginServlet extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		// 获取表单提交的参数
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 对帐号进行校验,成功的话
		if (!username.equals("hello")) {
			// 将帐号作为Cookie保存在浏览器中
			Cookie cookie = new Cookie("username", username);
			cookie.setMaxAge(60 * 60);
			response.addCookie(cookie);
			// 将获取的参数存在session域中,方便succ1获取
			HttpSession session = request.getSession();
			session.setAttribute("username", username);
			session.setAttribute("password", password);
			// 重定向到登陆成功页面
			response.sendRedirect("/4.29/Login/succ1.jsp");
			// 失败的话
		} else {
			// 保存错误信息到request域中
			request.setAttribute("judge", "用户名或密码错误。请重新输入。");
			// 转发到login.jsp
			request.getRequestDispatcher("/Login/login.jsp").forward(request,
					response);

		}
	}
}

succ1.jsp

	<%
		String username = (String) session.getAttribute("username");//获取用户名
		/*
		 	如果用户名为null,向request域中保存错误信息,转发到login.jsp
		 */
		if (username == null) {
			request.setAttribute("judge", "您还没有登陆");
			request.getRequestDispatcher("/Login/login.jsp").forward(
					request, response);
			return;
		}
	%>
	<h2>欢迎回来,<%=username%></h2>
    4.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对象。

    5.Session与浏览器

        session保存在服务器,而sessionId通过Cookie发送给客户端,但这个Cookie的生命不-1,即只在浏览器内存中存在,也就是说如果用户关闭了浏览器,那么这个Cookie就丢失了。

        当用户再次打开浏览器访问服务器时,就不会有sessionId发送给服务器,那么服务器会认为你没有session,所以服务器会创建一个session,并在响应中把sessionId中到Cookie中发送给客户端。     

        你可能会说,那原来的session对象会怎样?当一个session长时间没人使用的话,服务器会把session删除了!这个时长在Tomcat中配置是30分钟,可以在${CATALANA}/conf/web.xml找到这个配置,当然你也可以在自己的web.xml中覆盖这个配置!从客户端请求中获取Cookie。

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

        如果你打开网站的一个页面开始长时间不动,超出了10分钟后,再去点击链接或提交表单时你会发现,你的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,那么session为什么依赖Cookie呢?因为服务器需要在每次请求中获取sessionId,然后找到客户端的session对象。那么如果客户端浏览器关闭了Cookie呢?那么session是不是就会不存在了呢?

        其实还有一种方法让服务器收到的每个请求中都带有sessioinId,那就是URL重写!在每个页面中的每个链接和表单中都添加名为jSessionId的参数,值为当前sessionid。当用户点击链接或提交表单时也服务器可以通过获取jSessionId这个参数来得到客户端的sessionId,找到sessoin对象。

<body>
<h1>URL重写</h1>
<a href='/day06_5/index.jsp;jsessionid=<%=session.getId() %>'
<form action='/day06_5/index.jsp;jsessionid=<%=session.getId() %>' method="post">
    <input type="submit" value="提交"/>
</form>
</body>

        也可以使用response.encodeURL()对每个请求的URL处理,这个方法会自动追加jsessionid参数,与上面我们手动添加是一样的效果。

<a href='<%=response.encodeURL("/day06_5/index.jsp") %>' >主页</a>
<form action='<%=response.encodeURL("/day06_5/index.jsp") %>' method="post">
	<input type="submit" value="提交"/>
</form>

        使用response.encodeURL()更加“智能”,它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法在URL后面追加jsessionid,否则不会追加。        


猜你喜欢

转载自blog.csdn.net/fy_java1995/article/details/80145041