zoukankan      html  css  js  c++  java
  • 三、Jsp(一)

    一、JSP入门

    1.1、JSP概述

    (1)、什么是JSP

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

    (2)、JSP的组成

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

    1.2、JSP语法

    (1)、JSP脚本

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

    • <% ... %>:代码段,Java语句

    • <%= ... %>:表达式,只是表达式!表达式的值会被输出到客户端

    • <%! ... %>:定义,定义成员!例如例如成员变量,方法等

    <%
            // Java语句
            String s1 = "hello jsp";
            // 不会输出到客户端,而是在服务器端的控制台打印
            System.out.println(s1);
    %>
      <!-- 输出到客户端浏览器上 -->
        输出变量:<%=s1 %><br/>
        输出int类型常量:<%=100 %><br/>
        输出String类型常量:<%="你好" %><br/>

    (2)、内置对象out

    out对象在JSP页面中无需创建就可以使用,它的作用是用来向客户端输出。

    <%
            //向客户端输出
            out.print("你好!");
    %>

    其中<%=…%>与out.print()功能是相同的!它们都是向客户端输出,例如:

    <%=s1%>等同于<% out.print(s1); %>

    (3)、多个<%...%>可以通用

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

    1.3、JSP的原理

    (1)、JSP是特殊的Servlet

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

    (2)、JSP真身存放目录

    JSP生成的Servlet存放在${CATALANA}/work目录下,我经常开玩笑的说,它是JSP的“真身”。我们打开看看其中的内容,了解一下JSP的“真身”。

    你会发现,在JSP中的静态信息(例如<html>等)在“真身”中都是使用out.write()完成打印!这些静态信息都是作为字符串输出给了客户端。

    二、会话跟踪技术

    2.1、什么是会话跟踪技术

    我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应。例如你给10086打个电话,你就是客户端,而10086服务人员就是服务器了。从双方接通电话那一刻起,会话就开始了,到某一方挂断电话表示会话结束。在通话过程中,你会向10086发出多个请求,那么这多个请求都在一个会话中。

    在JavaWeb中,客户向某一服务器发出第一个请求开始,会话就开始了,直到客户关闭了浏览器会话结束。

    在一个会话的多个请求中共享数据,这就是会话跟踪技术。例如在一个会话中的请求如下:

    • 请求银行主页;

    • 请求登录(请求参数是用户名和密码);

    • 请求转账(请求参数与转账相关的数据);

    • 请求信誉卡还款(请求参数与还款相关的数据)。

    在这上会话中当前用户信息必须在这个会话中共享的,因为登录的是张三,那么在转账和还款时一定是相对张三的转账和还款!这就说明我们必须在一个会话过程中有共享数据的能力。

    2.2、会话路径技术使用Cookie或session完成

    我们知道HTTP协议是无状态协议,也就是说每个请求都是独立的!无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪

    在JavaWeb中,使用session来完成会话跟踪,session底层依赖Cookie技术。

    三、Cookie

    3.1、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

    //Servlet中向客户端发送Cookie
     Cookie cookie1 = new Cookie("test1", "abcdefg");
     Cookie cookie2 = new Cookie("test2", "ABCDEFG");
     response.addCookie(cookie1);
     response.addCookie(cookie2);
    
    //Servlet中获取客户端发送过来的Cookie
     Cookie[] cs = request.getCookies();
     if(cs != null) {
        for(Cookie c : cs) {
          System.out.println(c.getName() + "=" + c.getValue());
        }
     }

    3.2、Cookie的生命

      Cookie不只是有name和value,Cookie还是生命。所谓生命就是Cookie在客户端的有效时间,可以通过setMaxAge(int)来设置Cookie的有效时间。

    当服务器创建Cookie对象后,可以调用setMaxAge()方法设置Cookie的最大生命。

    • maxAge > 0:表示Cookie在客户端硬盘上保存的最大时间,单位为秒;

    • maxAge < 0:表示Cookie不会被浏览器保存到硬盘上,而只在浏览器内存中存活,一旦客户端关闭浏览器在,那么Cookie就消失;

    • maxAge == 0:表示删除Cookie,例如客户端硬盘已经存在名为abc的Cookie,如果服务器再向客户端发送名为abc,并且maxAge为0的Cookie,那么表示删除客户端上的名为abc的Cookie。

    3.3、Cookie的path

    (1)、什么是Cookie的路径

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

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

    (2)、Cookie路径与请求路径的关系

    下面我们来看看Cookie路径的作用:

    下面是客户端浏览器保存的3个Cookie的路径:

    a: /cookietest;

    b: /cookietest/servlet;

    c: /cookietest/jsp;

    下面是浏览器请求的URL:

    A: http://localhost:8080/cookietest/AServlet

    B: http://localhost:8080/cookietest/servlet/BServlet

    C: http://localhost:8080/cookietest/servlet/CServlet

    • 请求A时,会在请求中包含a;

    • 请求B时,会在请求中包含a、b;

    • 请求C时,会在请求中包含a、c;

    也就是说,请求路径如果包含了Cookie路径,那么会在请求中包含这个Cookie,否则不会请求中不会包含这个Cookie。

    • A请求的URL包含了“/cookietest”,所以会在请求中包含路径为“/cookietest”的Cookie;

    • B请求的URL包含了“/cookietest”,以及“/cookietest/servlet”,所以请求中包含路径为“/cookietest”和“/cookietest/servlet”两个Cookie;

    • B请求的URL包含了“/cookietest”,以及“/cookietest/jsp”,所以请求中包含路径为“/cookietest”和“/cookietest/jsp”两个Cookie;

    (3)、设置Cookie的路径

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

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

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

    3.4、Cookie的domain

    Cookie的domain属性可以让网站中二级域共享Cookie,次要!

    百度你是了解的对吧!

    http://www.baidu.com

    http://zhidao.baidu.com

    http://news.baidu.com

    http://tieba.baidu.com

    现在我希望在这些主机之间共享Cookie(例如在www.baidu.com中响应的cookie,可以在news.baidu.com请求中包含)。很明显,现在不是路径的问题了,而是主机的问题,即域名的问题。处理这一问题其实很简单,只需要下面两步:

    • 设置Cookie的path为“/”:c.setPath(“/”);

    • 设置Cookie的domain为“.baidu.com”:c.setDomain(“.baidu.com”)。

    当domain为“.baidu.com”时,无论前缀是什么,都会共享Cookie的。但是现在我们需要设置两个虚拟主机:www.baidu.com和news.baidu.com。

    • 第一步:设置windows的DNS路径解析

      找到C:WINDOWSsystem32driversetchosts文件,添加如下内容

    127.0.0.1    localhost  
    127.0.0.1    www.baidu.com  
    127.0.0.1    news.baidu.com  
    • 第二步:设置Tomcat虚拟主机

    找到server.xml文件,添加<Host>元素,内容如下:

    <Host  name="www.baidu.com"  appBase="F:webappswww"  unpackWARs="true"  autoDeploy="true"      xmlValidation="false"  xmlNamespaceAware="false"/>    
    <Host  name="news.baidu.com"   appBase="F:webapps
    ews"  unpackWARs="true"  autoDeploy="true"    xmlValidation="false"  xmlNamespaceAware="false"/>  
    • 第三步:创建A项目,创建AServlet,设置Cookie。
    Cookie c = new Cookie("id", "baidu");      
    c.setPath("/");      
    c.setDomain(".baidu.com");      
    c.setMaxAge(60*60);      
    response.addCookie(c);      
    response.getWriter().print("OK");  

    把A项目的WebRoot目录复制到F:webappswww目录下,并把WebRoot目录的名字修改为ROOT。

    • 第四步:创建B项目,创建BServlet,获取Cookie,并打印出来。

    Cookie[] cs = request.getCookies();     
    if(cs != null) {
      for(Cookie c : cs) {         
        String s = c.getName() + ": " + c.getValue() + "<br/>";                                      response.getWriter().print(s);        
          }     
     }  

    把B项目的WebRoot目录复制到F:webapps ews目录下,并把WebRoot目录的名字修改为ROOT。

    • 第五步:访问www.baidu.comAServlet,然后再访问news.baidu.comBServlet。

    3.5、Cookie中保存中文

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

    • 向客户端响应中添加Cookie

    String name = URLEncoder.encode("姓名", "UTF-8");
    String value = URLEncoder.encode("张三", "UTF-8");
    Cookie c = new Cookie(name, value);
    c.setMaxAge(3600);
    response.addCookie(c);
    • 从客户端请求中获取Cookie
    response.setContentType("text/html;charset=utf-8");
    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");
                    String s = name + ": " + value + "<br/>";
                    response.getWriter().print(s);
                }
            }

    四、HttpSession

    4.1、HttpSession概述

    什么是HttpSesssion?

    javax.servlet.http.HttpSession接口表示一个会话,我们可以把一个会话内需要共享的数据保存到HttSession对象中!

    (1)、获取HttpSession

    //如果当前会话已经有了session对象那么直接返回,如果当前会话还不存在会话,那么创建session并返回
    HttpSession session = request.getSession();
    //当参数为true时,与requeset.getSession()相同。如果参数为false,那么如果当前会话中存在session则返回,不存在返回null;
    HttpSession session = request.getSession(false);

    (2)、Servlet中可以使用的域对象

    • HttpServletRequest:一个请求创建一个request对象,所以在同一个请求中可以共享request,例如一个请求从AServlet转发到BServlet,那么AServlet和BServlet可以共享request域中的数据;

    • ServletContext:一个应用只创建一个ServletContext对象,所以在ServletContext中的数据可以在整个应用中共享,只要不启动服务器,那么ServletContext中的数据就可以共享;

    • HttpSession:一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享session中的数据;

    4.2、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>

    4.3、session与浏览器

    • session对象是保存在服务器端的,而sessionId是通过Cookie保存在客户端的。因为Cookie不能在多个浏览器中共享,所以session也不能在多个浏览器中共享。也就是说,使用IE登录后,再使用FireFox访问服务器还是没有登录的状态。

    • 而且同时打开多个相同浏览器的窗口,是在使用同一session。如果你使用的是老浏览器,例如IE6,那么就会每个窗口一个session。

    4.4、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

  • 相关阅读:
    千万数量级分页存储过程(效果演示)
    hibernate注解实体类(Dept.java)
    hibernate注解实体类(Dept.java)
    hibernate注解的测试
    hibernate注解的测试
    hibernate注解的测试
    Hibernate中使用Criteria查询及注解——( EmpCondition)
    Hibernate中使用Criteria查询及注解——( EmpCondition)
    Hibernate中使用Criteria查询及注解——( EmpCondition)
    Hibernate中使用Criteria查询及注解——(DeptTest.java)
  • 原文地址:https://www.cnblogs.com/jdy1022/p/13815945.html
Copyright © 2011-2022 走看看