JavaEE系列之(一)JSP基础知识详解

原文摘自网络

一、JSP基础语法

    1、JSP简介
       JSP(Java Server Pages),其根本是一个简化的Servlet设计,它实现了在Java中使用HTML标签。JSP是一种动态网页技术标准,也是JavaEE的标准。JSP和Servlet一样,是在服务器端执行的。JSP是在Servlet技术发展之后为了让开发者写html标签更方便而发展起来的技术,JSP实际上就是Servlet。
       但是,人们通常把Servlet作为Web应用中的控制组件来使用,只负责响应请求产生数据,并把数据通过转发技术带给jsp,而把jsp技术作为数据显示模板来使用。这样使程序结构更清晰,可读性和可维护性更高。
     2、常用动态网站开发技术
         JSP:Java平台,安全性高,适合开发大型的,企业级的,分布式的Web应用程序。如Hadoop,电子银行,12306等
         ASP.net:.Net平台,简单易学。但是安全性以及跨平台型差。
         PHP:简单,高效,成本低开发周期端,特别适合中小型企业的Web应用开发。(LAMP:Linux+Apache+MySQL+PHP)
      3、JSP页面元素构成
         3.1、JSP指令:
             JSP指令(directive)是为JSP引擎二设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。在JSP2.0规范中共定义了三个指令,基本语法格式为,<%@ 指令 属性名="值" %>,如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写。
              page指令:page指令用于定义JSP页面的各种属性,无论指令出现在页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令通常放在整个JSP页面的起始位置,一个页面可以有多个page指令。
 
<%@ page language="java" contentType="text/html,ISO-8859-1" import="java.util.*,java.sql.*,java.io.*" 
session="true|flase" buffer="none|8kb|sizekb" autoFlush="true|false" info="一段字符串内容"
errorPage="relative_url" isErrorpage="true|false"%> 1、language 指定JSP页面使用的脚本语言,默认值为java 2、contentType 用来指定JSP页面的文件类型和所采用的编码方式, 默认值为“text/html,ISO-8859-1” 3、import 通过该属性来引用脚本语言中使用到的类文件,导入多个类或包用逗号分隔。
JSP引擎自动导入java.lang.*;java.servlet.*;javax.servlet.jsp.*;javax.servlet.http.* 4、pageEncoding 指定JSP页面的编码方式, 默认值为“ISO-8859-1” 5、session,用来说明是否创建session对象,默认为true 6、buffer,用来指定out对象是否创建buffer缓冲区,并指定缓冲区大小。默认为8kb,none表示不创建缓冲区。 7、autoFlush,缓冲区是否自动刷新,默认为true,如果为false,缓冲区满后不手动刷新会包异常。 8、info,定义一个字符串常量,使用getServletInfo方法可以打印。 9、errorPage,指定异常处理页。也可以在web.xml中使用<error-page>元素为整个WEB应用程序设置处理页面,
其中的<exception-type>子元素指定异常类的完全限定名,<location>元素指定以"/"开头的错误处理页面的路径。
如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中这是的错误处理将不对该页面起作用。
 

 

               include指令:用于引入其他JSP页面,如果使用include指令引入了其他JSP页面,那么JSP引擎将把这两个JSP翻译成一个Servlet,所以include指令引入通常也成为静态引入。
               <%@ include file=“被包含组件的绝对URL或相对URL"%>
               被引入的文件必须遵循JSP语法。被引入的文件可以是任意扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见名知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。由于使用include指明将会涉及到2个JSP页面,并会把JSO翻译成一个Servlet,所以这两个JSP页面的指令不能冲突(pageEncoding和导包除外)
               taglib指令:使用标签库定义显得自定义标签,在JSP页面中启用定制行为。
          3.2、表达式:
                在JSP页面中执行的表达式 <%=表达式%>,注意表达式不以分号结束。例如,当前时间:<%= new java.util.Date() %>
          3.3、脚本片段:
                在JSP页面中插入多行java代码 <% Java代码 %>,JSP引擎在翻译JSP页面时,会将JSP脚本片段中的Java代码原封不动的放到Servlet的_jspServlet方法中,所以,<% %>中的Java代码必须严格遵循java语法。
          3.4、声明:
                在JSP页面中定义变量或者方法  <%! Java代码 %>,声明中的Java代码被翻译到_jspService方法的外面,属于类,所以可以声明成员变量并初始化,也可以声明方法或定义方法,同时还可以声明静态代码块。
                JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象
 
<%!
static 
{ 
    System.out.println("loading Servlet!"); 
}
private int globalVar = 0;
public void jspInit()
{
    System.out.println("initializing jsp!");
}
%>
<%!
public void jspDestroy()
{
    System.out.println("destroying jsp!");
}
%>
 

          3.5、注释(3种方式):

                 HTML注释:<!--html注释,且客户端可见-->
                 JSP注释:<%--JSP注释,客户端不可见--%>
                 JSP脚本注释:即java注释 //单行 , /*多行 */
          3.6、静态内容:
 
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>

<html>
  <head>
    <title>index.jsp page</title>
  </head>
  <body>
    <h1>大家好</h1>
    <hr>
    <!-- 我是HTML注释,在客户端可见 -->
    <%-- 我是JSP注释,在客户端不可见 --%>
    <%! 
       String s = "张三";  //声明了一个字符串变量
       int add(int x,int y) //声明了一个返回整型的函数,实现两个整数的求和。
       {
          return x+y;
       }
    %>
    <% 
       //单行注释
       /*多行注释*/
       out.println("大家好");
    %>
    <br>
    你好,<%=s %><br>
    x+y=<%=add(10,5) %><br>    
  </body>
</html>
 

    4、JSP运行原理及生命周期:

          
           用户第一次请求Tomcat会将jsp文件编程成一个Servlet的java文件,并将java文件编译成class文件,加载到内存,生成文件在Tomcat的work目录的对应项目文件夹。如果jsp页面发生了修改,JSP引擎会对其进行重新编译并加载到内存,以方便用户请求。注意,用户第一次请求一个jsp页面时,首先被执行的方法是构造方法。
           _jspService()方法被调用来处理客户端的请求。对每一个请求,JSP引擎创建一个线程来处理该请求。如果有多个客户端同时请求该JSP文件,则JSP引擎会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可以大大降低对系统资源的需求,提高系统的并发量及响应时间。但也要主要多线程的编程带来的额同步问题,由于该Servlet始终驻于内存,所以响应是非常快的。
            JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象共_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面是获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用。
 
二、JSP 9个内置对象
       1、内置对象简介
           JSP内置对象是Web容器创建的一组对象,不使用new关键字就可以使用的内置对象。
           
       2、四种作用域范围
         application_SCOPE:作用于整个Web应用,多个用户之间共享。
         session_SCOPE:作用于整个Web应用,单个用户之间共享。
         request_SCOPE:作用于请求,转发间请求共享。
         page_SCOPE:作用于当前页面,当前页面可见。
       3、out对象
         缓冲区:Buffer,即内存中的一块区域用来保存临时数据
         out对象:是JspWriter类的实例,是向客户端发送文本常用的对象,是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。当缓冲区满足如下条件是才会写入Servlet引擎提供的缓冲区:设置page指令的buffer属性关闭了out对象的缓存功能;out对象的缓冲区已满。整个JSP页面结束。      
<%
   out.println("aaa");
   response.getWriter().write("bbb");
%>
"bbb会比aaa先输出"

 

 
         常用方法:1、void println(); 向客户端打印字符串
                   2、void clear(); 清除缓冲区的内容,如果在flush之后调用会抛出异常。
                   3、void clearBuffer(); 清除缓冲区的内容,如果在flush之后调用不会抛出异常
                   4、void flush(); 将缓冲区内容输出到客户端
                   5、int getBufferSize(); 返回缓冲区以字节数的大小,如不设缓冲区则为0
                   6、int getRemaining(); 返回缓冲区还剩余多少可用
                   7、boolean isAutoFlush(); 返回缓冲区满是,是自动清空还是抛出异常
                   8、void close(); 关闭输出流
 

      4、request/response对象

          请求响应机制请参考本博客的Servlet部分。
            4.1、表单的两种提交方式:get与post
                get:以明文的方式通过URL提交数据,数据在URL中可以看到。提交的数据最多不超过2KB。安全性较低,但效率比post方式搞。适合提交数据量不大,安全性高的数据。比如:搜索、查询等功能
                post:将用户提交的信息封装在HTML header内。适合提交数据量大,安全性高的用户信息。比如:注册、修改、上传等功能。
            4.2、request对象
                客户端的请求信息被封装在request对象中,通过它才能了解到客户端的需求,然后做出响应。它是HttpServletRequest类的实例。request对象具有请求域,即完成客户端的请求之前,该对象一直有效。             
  1. //request常用方法:
  2. String getParameter();返回指定参数的参数值
  3. String[] getParameterValues();返回指定参数的所有值
  4. void setAttribute();存储此请求中的属性
  5. object getAttribute();返回指定属性的属性值
  6. String getContentType();得到请求体的MIME类型
  7. String getProtocol();返回请求用的协议及版本号
  8. String getServerName();返回接受请求的服务器主机名
  9. int getServerPort();返回服务器接受此请求的端口号
  10. String getCharacterEncoding();返回字符编码方式
  11. void setContentEncoding();设置请求的字符编码方式
  12. int getContentLength();返回请求体的长度(以字节数)
  13. String getRemoteAddr();返回发送此请求的客户端IP地址
  14. String getRealPath(String path);返回一个虚拟路径的真实路径或相对路径的绝对路径
  15. StringgetContextPath();返回上下文路径,即项目的根目录
                中文乱码问题:request.setCharacterEncoding("UTF-8");
                URL中中文乱码问题:Tomcat的/conf/server.xml 的添加<Connector URIEncoding="UTF-8">属性。
            4.3、response对象
                response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。response对象具有页面作用域,及访问一个页面时,该页面内的response对象只能对这次访问有效,其他的response对象对当前页面无效。           
  1. //response对象的常用方法
  2. String getCharacterEncoding();返回响应用的是何种字符编码
  3. void setContentType();设置响应的MIME类型,一般为"text/html, charset=UTF-8"
  4. PrintWriter getWriter();返回可以向客户端输出字符的一个对象("注意比较:PrintWriter与内置out对象的区别,PrintWriter对象的其输出总是提前于内置out对象,或者在out中手动flush")
  5. sendRedirect(loaction);重新定向客户端的请求
                 请求重定向:是客户端行为,response。sendRedirect(),从本质上将等同于两次请求,前一次的请求对象不会保存,地址栏的URL地址会改变。
                 请求转发:是服务器行为,request.getRequestDispatcher().forward();是一次请求,转发后请求对象会保存,地址栏的URL地址不会改变。
       5、session对象
          session表示客户端与服务器的一次会话,Web中的session指的是用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间。
          在服务器的内存中,为不同的用户保存着不同的session。
          session对象是一个JSP内置的对象。
          session对象在第一个JSP页面被装载是自动创建,完成会话期管理。
          从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话。
          当一个客户访问一个服务器时,肯能会在服务器的几个页面之间切换,服务器应当通过某种办法知道这是一个客户,就需要session对象。
          session对象是HttpSession类的实例。
  1. //session的常用方法
  2. long getCreationTime();返回session创建时间
  3. String getId();返回session创建时JSP引擎为它设的唯一ID
  4. Object setAttribute();使用指定名称将对象绑定到此会话
  5. Object getAttribute();返回与此会话中的指定名称绑定在一起的对象,没有返回null
  6. String[] getValueNames();返回一个包含此session中所有可用属性的数组
  7. int getMaxInactiveInterval();返回两次强求间隔多长时间此session被取消(单位秒)
  8. void setMaxInactiveInterval();设置session存活时间。
           session的生命周期:
               创建:当客户端第一次访问某个jsp或者Servlet时候,服务器会为当前会话创建一个SessionId,每次客户端向服务端发送请求时,都会将此SessionId携带过去,服务端会对此SessionId进行校验。
               活动: 某次会话当中通过超链接打开的新页面属于同一次会话。只要当前会话页面没有全部关闭,重新打开新的浏览器窗口访问同一项目资源时属于同一次会话。除非本次会话的所有页面都关闭后,在重新访问某个jsp或者Servlet将会创建新的会话(但此时原有会话还存在,这个就的SessionId仍然存在于服务端,只不过再也没有客户端会携带它然后教育服务端校验,直到该会话超时。)。
               销毁:有三种销毁方式
                    1、调用了session.invalidate()方法
                    2、Session过期(超时)可以在web.xml中配置Session超时时间<session-config><session-timeout>1单位是分钟
                    3、服务器重新启动
       6、application对象
             application对象实现了用户间数据的共享,可存放全局变量。
             application开始于服务器的启动,终止于服务器的关闭。
             在用户的前后连接或不同用户之间的连接中,可以对application对象的同一属性进行操作。
             在任何地方对application对象属性的操作,都将影响到其他用户对此的访问。
             服务器的启动和关闭决定了application对象的生命。
             application对象是ServletContext类的实例。     
  1. //application的常用方法
  2. void setAttribute();使用指定名称将对象绑定到此会话
  3. Object getAttribute();返回与此会话中的指定名称绑定在一起的对象,如果没有,返回null
  4. Enumeration getAttributeNames();返回所有可用属性名的枚举
  5. String getServerInfo();返回JSP(Servlet)引擎名及版本号
        7、page对象
             page对象就是指向当前jsp页面本身,有点像类中的this指针,它是java.lang.Object类的实例。常用方法就是Object类的成员方法。
        8、pageContext对象  
              pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其他8个隐式对象的引用,其自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如include,forward其他资源、检索其他域对象中的属性等。
              pageContext对象提供了对jsp页面内所有的对象及名字空间的访问。该对象可以访问到本页所在的Session,也可以取本页所在的application中的属性值。该对象相当也页面中所有功能的集大成者。该对象的本类名也叫pageContext。             
  1. //pageContext的常用方法
  2. JspWriter getOut();返回当前客户端响应被使用的out对象
  3. HttpSession getSession();返回当前页中的Session对象
  4. Object getPage();返回当前页的page对象
  5. ServletRequest getRequest();返回当前页的Request对象
  6. ServletResponse getResponse();返回当前页的Response对象
  7. void setAttribute();设置属性及属性值
  8. Object getAttribute();在指定范围内取属性的值
  9. int getAttributeScope();返回某属性的作用范围
  10. void forward();跳转到另一个页面,地址栏不变
  11. void include();包含另一个页面,
  12. PageContext.APPLICATION_SCOPE 代表各个域的常量
  13. PageContext.SESSION_SCOPE
  14. PageContext.REQUEST_SCOPE
  15. PageContext.PAGE_SCOPE
  16. findAttribute(); 查找各个域中的属性
         9、Config对象
              Config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)              
  1. //Config的常用方法
  2. ServletContext getServletContext();返回含有服务器信息的ServletContext对象
  3. String getInitParameter();返回初始化参数的值
  4. Enumeration getInitparameterNames();返回Servlet初始化所需所有参数的枚举
         10、Exception对象
                Exception对象是一个异常对象,当一个页面在运行过程中发生了异常,就产生这个对象。如果一个jsp页面要应用此对象,就必须报isErrorPage设为true,否则无法编译。它实际上是java.lang.Throwable的对象。页面要想在有异常时得到处理,就要指定异常处理页面<% page errorPage="exception.jsp"%>         
  1. //exception的常用方法
  2. String getMessage();返回描述异常的消息
  3. String toString();返回关于异常的简短描述消息
  4. void printStackTrace();显示异常及其栈轨迹
  5. ThrowableFillInStackTrace();重写异常的执行栈轨迹
 
三、JSP动作标签
          1、 JSP动作元素(action elements):动作元素为请求处理阶段提供信息。动作元素遵循XML元素的语法,有一个包含元素名的开始标签,可以有属性、可选的内容、与开始标签匹配的结束标签。
            JSP标签也称之为JSP Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护。
          2、 JSP动作元素包含五大类:
              1、与存储JavaBean有关的:<jsp:useBean>, <jsp:setProperty>, <jsp:getProperty>
              2、JSP1.2规范就有的6个基本动作元素:<jsp:include>, <jsp:forward>, <jsp:param>, <jsp:plugn>, <jsp:params>, <jsp:fallback>
              3、JSP2.0新增加,主要与JSP Document有关的6个动作元素:<jsp:root>, <jsp:declaration>, <jsp:scriptlet>, <jsp:exception>, <jsp:text>, <jsp:output>
              4、JSP2.0新增加,主要永磊动态生成XML元素标签的值,包括3个动作:<jsp:attribute>, <jsp:body>, <jsp:element>
              5、JSP2.0新增加,只要用在Tag File中:<jsp:invoke>, <jsp:dobody>
          3、JSP常用标签
              <jsp:include>:该标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容中,这种在JSP页面执行时的引入方式称之为动态引入。<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />。flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
             <jsp:include>与include指令比较:<jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。但include指令要比<jsp:include>标签效率高些。可以从下面的表格中更直观的看到两者的区别   
             
              <jsp:forward>:该标签用于把请求转发给另外一个资源。<jsp:forward page="relativeURL | <%=expression%>" />。等同于request.getRequestDispatcher("/url").forward(request,response)。即执行服务器内部跳转操作。
              <jsp:param>:当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
  1. <jsp:include page="relativeURL | <%=expression%>">
    <jsp:param name="parameterName" value="parameterValue|<%= expression %>"/>
    </jsp:include>
    可以使用多个<jsp:param>标签来传递多个参数。

             4、映射JSP

            映射JSP就是将一个JSP映射成其他任意形式的URL,在web.xml文件张配置
  1.  
    <servlet>
        <servlet-name>SimpleJspServlet</servlet-name>
        <jsp-file>/jsp/simple.jsp</jsp-file>
        <load-on-startup>1</load-on-startup >
    </servlet>
        ……
    <servlet-mapping>
        <servlet-name>SimpleJspServlet</servlet-name>
        <url-pattern>/xxx/yyy.html</url-pattern>
    </servlet-mapping>
     

     

  2. 四、JavaBeans

        1、Javabean简介
              Javabeans就是符合某种特定规范的Java类。使用Javabeans的好处是解决代码重复编写,减少代码冗余,功能区分明确,提高了代码的可维护性。
        2、Javabean设计原则
               必须是共有类;
               必须包含一个无参的共有构造方法;
               所有属性必须私有;
               使用getter和setter访问器对属性访问封装。              
 
public class Book {  //一个符合要求的Javabean类
    private String bookName;
    private String author;
    private double price;
    public Book() {
    }
    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
 

       3、JSP中如何使用Javabean

              第一种方式:像使用普通java类一样,创建javabean实例。
              第二种方式:在JSP页面中通常使用jsp动作标签使用javabean。
        4、<jsp:useBeans>
              作用:在jsp页面中实例化或者在指定范围内使用javabean
              <jsp:useBean id="标识符" class="java类名" scope="作用范围"/> scope默认为page。
        5、<jsp:setProperty>
               作用:给已经实例化的Javabean对象的属性赋值,一共有四种形式:
               <jsp:setProterty name="Javabean实例名" property="*"/>(跟表单关联)
               <jsp:setProterty name="Javabean实例名" property="Javabean属性名"/>(跟表单关联)
               <jsp:setProterty name="Javabean实例名" property="Javabean属性名" value="BeanValue"/>(手工设置)
               <jsp:setProterty name="Javabean实例名" property="propertyName" param="request对象中的参数名"/>(跟request参数关联)通过url地址传递的参数
        6、<jsp:getProperty>
               作用:获取指定Javabean对象的属性值。
               <jsp:getProperty name="Javabean实例名" property="属性名"/>
        7、Javabean的四个作用域范围
                使用useBeans的scope属性可以用来指定javabean的作用范围。
                page:仅在当前页面有效
                request:可以通过request.getAttribute方法取得JavaBean对象
                session:可以通过session.getAttribute方法取得JavaBean对象
                application:可以通过application.getAttribute方法取得JavaBean对象
        8、Model1简介
            Model1出现前,整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接作出响应。
            弊端:在界面层充斥着大量的业务逻辑的代码和数据访问层的代码,Web程序的可扩展性和可维护性非常差。
            Javabean的出现可以使jsp页面中使用Javabean封装的数据或者调用Javabean的业务逻辑代码,这样大大提升了程序的可维护性。
            
         9、Model2简介
            
 
五、JSP状态管理
          1、http协议的无状态性
              无状态是指,当浏览器发送请求该服务器的时候,服务器响应客户端请求。但是当同一个浏览器再次发送请求给服务器的时候,服务器并不知道它就是刚才那个浏览器。简单的说就是服务器不会记得你,所以就是无状态协议。
          2、保存用户状态的两大机制
              Cookie技术、Session技术
          3、Cookie简介
              Cookie:是Web服务器保存在客户端的一系列文本信息。
              典型应用:判定注册用户是否已经登录网站。
                        购物车的处理。
              Cookie的作用:
                          对特定对象的追踪
                          保存用户网页浏览记录与习惯
                          简化登录
               安全风险:容易泄露用户隐私信息。
          4、Cookie的创建与使用
                Cookie与Session的详细讲解请参考本博客文章《Servlet---JavaWeb技术的核心基础,JavaWeb框架的基石(二)》中的Cookie与Session部分。
          5、Session与Cookie的对比
                共同点:都是用来保存用户状态的;都会过期
                Session:在服务器端保存用户信息,保存的是Object类型,随会话的结束而将其存储的数据销毁,保存重要的信息。
                Cookie:在客户端保存用户信息,保存的是String类型,可以长期保存在客户端,保存不重要的用户信息。

本文原版链接为:https://www.cnblogs.com/rocomp/p/4822419.html

成果归作者享有,作者如有发现侵权请私信告知,本人收到通知必删。此处引用只为学习记录。

同类文章阅读

[1]    java web 整合开发王者归来学习总结

--------------------------------------------------

[1] 文章

第一章java web开发概述
胖客户端CS,瘦客户端BS(Browser)
网址请求---服务器处理响应-----返回结果-----浏览器显示
CGI可以动态生成页面,但是每个进程都要启动一个CGI程序的系统进程,并在系统进程中启动一个jvm,开销大,执行效率低;java servlet只需要启动一次服务器进程,加载一次JVM,之后再加载另外的类,这样降低了开销,加载类可以处理多个相同请求,servlet能直接与web服务器交互。但是servlet嵌入了HTML标签和表达式,修改文件,就需要重新编译源文件。JSP(java server page)servlet结合了动静态的HTML技术,jsp先被jsp引擎转换成java源代码,在编译成可执行的二进制字节码,接收到客户请求后,执行上面的二进制字节码的jsp文件。
第二章 搭建javaweb开发环境
    JDK包括JRE。Myeclipse 包括eclipse,还增加了一些封装好的插件,更好用。
环境搭建步骤:安装jdk,设置环境变量JAVA_HOME为安装目录,添加到Path环境变量 jdk的bin路径----安装eclipse+myeclipse插件,或者直接安装myeclipse程序,下载tomcat服务器,解压设置环境变量CATALINE_HOME为安装路径,添加bin目录路径到Path环境变量。---新建工程,在myeclipse上新建web工程-----部署到tomcat,手动复制到tomcat的webapp文件夹下,或者在myeclipse上window|preferences添加tomcat,将工程add到tomcat-----运行tomcat服务器,输入网址访问网页。
    也可以导出为war文件复制到webapp文件夹,tomcat自动完成解包部署工作。
    在myeclipse中window|perference中设置tomcat为debug模式,在myeclipse中启动tomcat,可以调试程序。
第三章 深入servlet技术
    GET方式常用于查询信息,查询内容显示在地址栏中,信息不安全,且提交内容不能超过256个字节。Post方式常用于提交数据,需要提供数据类型和长度,无长度限制,不显示在地址栏,安全。
    Web.xml配置:servle-name(创建的servlet类的名称HelloServlet,文件中唯一),servle-class(带包名称的类路径:com.bclfirst.HelloServlet),在servlet-mapping中配置url-pattern(/servlet/HelloServlet)设置servlet的访问方式,http://ip:port/webapp下文件夹名称/url-pattern (http://127.0.0.1/FirstWeb//servlet/HelloServlet.jsp)即为url访问路径。HelloServlet.jsp的后缀可以用通配符*表示任意的后缀。
    请求和响应:HttpServletRequest中包含了发出请求的客户端的ip端口、系统、tomcat服务器、servlet路径、类名等信息。HttpServletresponse响应用户请求,PrintWrite out=response.getWtiter(); out.println()打印输出html显示输出结果。
    生成图片验证码的关键步骤:Random对象生成随机数和随机颜色RGB值,BufferImage创建一个彩色图片,Graphic2D对象绘制图片颜色和验证码字符串。JPEGImageEncoder对象转换格式,ServletOutputStream对象的flush()函数打印输出。
    获取web文件参数:getInitParameter(Stirng param)获取web.xml中通过<init-param><init-param>配置的指定名称的参数,getInitParameters()获取所有的<init-param名称;getServletCofig().getServletContext()来获取一个ServletContext对象sc,用getInitParameters()和getInitParameter(Stirng param)函数获取所有的参数名称和单个参数值。
资源注射(@Resourse):private @Resourse(name =”addas”) String message;自动获取web.xml文件中的变量,配置方式是<env-entry><env-entry-name><env-entry-type><env-entry-value>.
搜索引擎:采用雅虎的yahoo_search-2.0.1.jar加入到lib文件夹下,import com.search.SearchClient ,调用SearchClient.imageSearch(ImageSearchRequest )检索。
    上传文件:FORM默认的数据类型enctype是application/x-www-form-urlencoded 表示ASCII码,上传文件时应该设置为multipart/form-data二进制文件格式。使用Apache Commons Upload类库。

上传进度读取:

Servlet生命周期:在服务器启动(load-on-startup为1)或第一次请求(load-on-startup为0)初始化一个servlet对象,执行init()函数;在服务器关闭时销毁对象,执行destory() 函数。中间每个请求启动一个线程执行service方法。
    注解@PostConstruct在servlet构造函数和init之间运行,注解函数@PreDestory在destory()函数之后执行。Web.xml中设置metadata-complete=“true”表示启动服务器时要去检测工程class文件和jar是否使用了注解。
    转向(Forward)RequestDispatcher rd = request.getRequestDispatcher(String to)可以跳转到文件、jsp、其他servlet,rd.forward(request,response)转向指定的;
    重定向(Redirect):response。sendRedirect(String loacation)集合了setStatus()(设置重定向状态为302临时重定向,301永久重定向。)和setHeader()(设置重定向的地址)。客户端请求两次,第一次返回状态和地址,第二次访问访问真实地址。
自动刷新:Response.setHeader(“Refresh”,”1000;URL=http://localhost:8080/servlet”);
    Servlet线程不安全问题:因为servlet只有一个实例,多线程时调用相同的doGet方法,如果多个线程同时写一个公共的私有变量,获取变量值时会出现不同步的问题。只读没问题。
第四章深入JSP技术
4.1JSP概述
JSP(java server page)也是一种servlet,是HTML代码和java代码的混合,无需使用out.println函数。直接复制到tomcat文件夹下,通过路径名称访问,无需web.xml文件。第一次请求jsp文件时,先被转换为java源代码,然后被编译为class类文件,运行class文件响应请求。以后不再重新编译。除了init和destroy外还有自己的_jspInit()和_jspDestory()方法。
4.2JSP语法
Jsp分为模板数据,指HTML输出样式;元素指java部分,包括脚本scriptlet、指令derective、标签tag;
Jap脚本:脚本用<% %>括起来,中间是java代码。使用out.println输出。
<%@ page language=”java”  contentType=”text/html,charset=utf-8”%>
<html>
<body>
<% 
int num=10;
out.println(“数字”+num+“阶乘为:”+resault);
%>
</body>
</html>

 

 
 
jsp输出:或者用<% =%>输出,例如:数字<% = num%>的阶乘为:<% = resault %>
jsp注释:用//或者/**/或者<% --      --%>
jsp声明方法和全局变量:在<%! %>内声明一个或多个方法和变量。
Jsp if for while return break语句:这些语句可以和HTML语句混合,但必须被<% %>包括在内,才能穿插其中。Return 之后的代码不会执行,包括</html>。
Jsp访问:将jspx项目部署到tomcat下,浏览器输入http:localhost:8080/jsp/greeting.jsp?param=3, param表示参数,可以通过request.getParameter(“param”)获取。
4.3jsp指令
4.3.1Page指令
 <%@ page language=”java”  contentType=”text/html, charset=utf-8”%>,一个或者多个属性。
Page常见属性:
language 采用的语言;
extends 指明继承于那个类,继承普通类时需要实现sevlet的init和destory方法;
import 引入jsp中用到的类、包,唯一可以声明多次的属性;
session 是否内置session对象,默认true;
autoFlush是否运行缓存,超出缓冲区大小或者执行out.flush()后输出到客户端显示,默认为true;
buffer指定缓存大小;
isThreadSafe 是否线程安全,true表示可以多个线程同时运行jsp,默认为false;
isErrorPage  是否为错误处理界面,如果true,jsp内置一个Exception对象exception,默认false;
errorPage 指明出现错误后转向的错误显示页面。
contentType 有效的文档类型,HTML格式为text/html,纯文本text/plain,jpg图像为image/jpeg,GIF图像为image/gif,word文档为application/msword;
info 传入jsp的任意字符串,用Servlet.getServletInfo()得到;
4.3.2include指令
格式为<%@ include  file=”relative jspurl”%> ,可以引入其他的jsp文件,路径为相对路径,便于jsp页面的区块化,例如将导航块放入head.jsp,将版权放在foot.jsp中。在jsp首尾include这两个文件;
JSP包含文件行为与Jsp包含指令不同,<jsp:incude page= “relative url ”/></jsp:incude>,指令是先包含在编译,行为是先运行,再包含;
4.3.3taglib指令
标签技术支持视图代码重用,<%@ taglib  uri=”http://java.sun.com/jsp/core “  prefix=”c”%>,uri指定类库地址,prefix指定标签的前缀;
4.4JSP行为
4.4.1jsp:incude行为
<jsp:incude flush=”true”  page= “/head.jsp ”/></jsp:incude>, page指定本程序内的文件,flush为true表示读入文件前先清空缓存;
4.4.2jspjava bean 行为
(1)在useBean.Html文件用表单<form action="useBean.jsp" method="post">,用户输入person的信息后,提交表单,传给useBean.jsp
(1)在jsp文件中用jsp:useBean声明普通类对象
<%-- 声明 Person 类对象 person --%>
<jsp:useBean id="person" class="com.helloweenvsfei.jspweb.bean.Person" scope="page"></jsp:useBean>  id对象名称,calss类名称, scope对象范围(page在当前jsp内,request本次请求中有效,session当前用户有效,application当前web程序内有效)。
(2)在jsp文件中用jsp:setProperty设置值,提交后request中含有提交的值,根据输入的名称对应值,保存到person对象中。
<%-- 设置 person 的所有属性,所有的属性值从 request 中自动取得 --%>
<jsp:setProperty name="person" property="*" />4)通过<jsp:getProperty name="person" property="name" />获取属性值
4.4.3scope可以用于网页访问次数计数
session当前用户访问次数,application总的访问次数)。
4.4.4<jsp:plugin/>嵌入Applet
4.4.5<jsp:forward/>跳转行为
<%
    out.clear();
    if("1".equals(request.getParameter("param"))){
%>
<jsp:forward page="/somepage.jsp">
    <jsp:param name="param1" value="value1"/>
    <jsp:param name="param2" value="value2"/>
</jsp:forward>
<%
    }
%>
4.4.6 <jsp:directive/>行为
Jsp行为和指令之间可以相互改写,实现相同的功能。

4.5jsp中隐藏对象
Jsp中内置的隐藏对象有out,request,reponse,config,session, application,page, pageContext, exception.
4.6jsp配置
Jsp文件可以直接访问,也可以通过web.xml配置文件来映射访问路径。标签采用<jsp-file>,其他一致。也可以添加初始化参数<init-param>,采用隐藏对象config的getInitParamter(String name)获取。
4.7EL(Expression language)表达式
用${}括起来的脚本在HTML中,不可再<%%>中,可以方便的读取对象的属性。例如${person.age}。EL可以方便的读取隐藏对象的属性。EL支持运算符,逻辑运算符,比较运算符。
第五章会话跟踪
因为HTTP协议是无状态的协议,请求响应结束后,连接关闭,再次请求响应时建立新的连接,服务器无法从连接上判断是哪个用户,即无法进行会话跟踪。会话跟踪用于记录客户的登陆信息,Cookie是在客户端记录信息,session是在服务器端记录信息。
5.1Cookie机制
客户端向服务器发出第一次请求,服务器向客户端颁发一个cookie,用于确认用户的身份,再次请求时浏览器将请求的网址连同颁发的cookie一起发给服务器,服务器可以修改cookie的内容在返回给浏览器。
Cookie通过request.getCookie()获取,通过response.addCookie()设置。Cookie是一个key-value的键-值对。
可以包含多个cookie。Cookie可以保存用户的访问次数。Cookie不能跨越域名去访问,浏览器判断一个网站是否可以操纵另一个网站的Cookie的判断依据是Cookie的属性域名,百度和谷歌不能相互访问。
    Cookie在保存中文时,需要用java.net.URLEncoder和java.net.URLDecoder进行获取的解码和写入时的编码。
    Cookie还可以保存图片数据,先用InputStream读取文件数据到内存,然后用BASE64Encoder进行编码,添加到Cookie中,客户端得到、Cookie后用response.getOutputStream().write(binary)输出到界面显示;但是每次请求都会携带Cookie,所以内容不宜过多,否则影响速度。
    Cookie除了name(名称)和value(值)外,还有maxAge(失效时间,负数表示关闭浏览器时删除,0表示立即删除,可以添加maxAge=0同名的Cookie来删除该名称的Cookie,整数表示超过秒数后删除),secure(是否按安全协议传输,默认false),path(设置cookie的允许访问的程序路径),domain(可以访问cookie的域名,必须以.开头,例如.goole.com),还有comment(描述)和version(版本)属性。
document.cookie返回cookie,每个载入浏览器的 HTML 文档都会成为 Document 对象。Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
 

5.2 Session机制
    Session是在服务器端保存用户信息,访问时通过查询客户明细表来确认身份。也是一个键值对加属性,jsp含隐藏的session对象,或者用request和response对象的方法获取。Seeion可以直接保存person对象与data对象。比cookie方便。
    访问jsp、servlet时才会创建Session,只访问HTML等静态资源不会创建session。
    Session的有效期通过设置MaxInactiveInterval活跃超时时间。
    Session需要依赖于cookie来辨识客户,服务器向客户端发送一个名称为JSESSIONID的cookie,依据此Session来识别是否是同一用户。
    地址重写,Response.encodeURL()方法自动判断浏览器是否支持cookie,支持则原样输出,不支持则将jsessionid重写到url地址中。
如果是页面重定向,用 response.sendRedirect(response.encodeRedirectURL (admini strator.jsp))重定向,支持cookie时,返回原url,如果不支持,加上jsessionid后返回。
第一次请求不会携带cookie,通过地址重写携带jsessionid,第二次请求时,如果携带了值为jsessionid的cookie,则url地址不会带有jsessionid了;可以在conntext.xml中设置是否禁用自动维护jsessionid的cookie。
5.3Session与cookie的比较
Session可以保存任何类型的数据,cookie只能保存ASCII字符串,不能直接存储java对象。
Session比cookie安全性更好;
Cookie可以实现登陆消息长期有效,session依赖于cookie,不能实现长期登陆有效的效果。
服务器访问数量多的采用cookie比较合适。否则服务器的负担太重。


第七章监听器listener
    监听器listener用于监听session、context、request的创建和删除,属性的变化。先在配置文件中配置<listener><listener-class>com.helloweenvsfei.listener.listenertest </listener></listener-class>,映射listener指向的文件,当session等创建销毁使会自动调用listenertest类里的方法,listenertest实现方法继承于httpsessionlistener的接口,接口固定。
    监听session、context、request属性变化,接口名称为XxxAttributeListener,当监听到对象添加、更新、移除会调用函数XxxAdded,Xxxreplaced,XxxRemove方法。
除了上述六个listener外,还有两个listener,无需在web.xml中配置,新建类时,实现listener的接口;分别为HttpSessionBindingListener和HttpSessionActivationListener,当对象放入Session中时,执行valueBound方法,删除时执行valueUNBound方法;服务器关闭时,Session内容保存到硬盘中,执行sessionWillPassivate方法,服务器重启时,重新加载Session,执行sessionDidActive方法。
第八章jstl标签库
8.1JSTL概述
JSTL(java standard tag library)为标准标签库。Java采用分层结构MVC(model-view-control)model用于处理业务逻辑,view用来显示,control用于连接这两个;标签就是用于显示数据的;JSTL采用xml格式,与HTML代码类似,可读性强;
标签包括前缀、标签名称、标签属性以及标签体;
8.2JSTL的core标签库
文件头包含<%@ taglib uri=”http://java.sun.com/jsp/jstl/core”  prefix=”c”>
c:out与EL表达式一起使用输出<c:out value=”&{para.action}”></c:out>
实现if的功能
<c:if test=”${param.action==’add’}”></c:if> test可以是boolean类型的true,也可以是字符串的true(ingore case);
实现if else的功能
<c:choose>
<c:when test=”true”>
When 标签的输出
</c:when>
<c:otherwise>
Otherwise  标签的输出
</c:otherwise>
 </c:choose>
<c:forEach>实现循环
<c:forEach var=”num”  begin=”2”  end =”100”  step=”2”>
<div>${num}</div>
</c:forEach>
Var定义变量名称,begin初始值,end结束值,step步长;向对于for(int num=2;num<=100;num+=2);
<c:forEach items=”${personlist}”  var=”person”></c:forEach>遍历list或者map
<c:forEach>有一个varStatus属性。

 

第16章 struts2.0 概述
16.1structs实例
添加类库
Struts2需要下载类库,即jar包,放在lib文件中。如果没有plaxus、Sitergraph、Spring,需要将对应的插件删掉,否则会出错;
创建文件
    创建loginaction.java,继承于com.opensymphony.xwork2.ActionSupport类,在类中创建set和get方法获取类的成员变量值;最重要的是execute()方法,为action的主方法,提交数据会调用该方法,返回值代表显示页面的名称,在struts2配置文件中配置action的结果的名称与显示页面的名称对应,调用对应jsp文件显示名称对应的界面。
配置文件
    Struts配置文件如下所示,每个action都有一个配置结点,result name即为上述中action返回界面的名称,后面的jsp文件即为显示的界面,package name用于继承特性,子package里的action能够使用父package里的资源;struts-default包含拦截器;global-results是全局的结构,任何action都可以调用;
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <!-- 声明 Struts2 的属性  例如将 Struts2 后缀改为 .helloween -->
    <!-- 
        <constant name="struts.action.extension" value="helloween"></constant>
    -->
<!—package name-->
    <package name="main" extends="struts-default">
        <global-results>
            <result name="login">/login.jsp</result>
        </global-results>
        <action name="login"
            class="com.helloweenvsfei.struts2.action.LoginAction">
            <result name="success">/welcome.jsp</result>
        </action>
        <action name="logout"
            class="com.helloweenvsfei.struts2.action.LoginAction"
            method="logout">
            <result name="success">/welcome.jsp</result>
        </action>
    </package>
</struts>
用struts2标签的jsp页面文件
    使用标签先加入<%@ taglib uri="/struts-tags" prefix="struts"%>标签库,然后用struts:head和struts:form等标签,theme="ajax"是主题,ajax主题会加载struts2的dojo库;/struts-tags位于struts2-core-2.0.6.jar包中,不需要复制到WEB_INF下面,直接使用即可,使用主题,页面会根据主题自动布局,无需html布局标签;
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/struts-tags" prefix="struts"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
    <struts:head theme="ajax" />
  </head>
  
  <body>
  
          <struts:fielderror />
  
          <struts:form action="loginPerson">
              <struts:label value="登录系统"></struts:label>
              <struts:textfield name="account" label="帐号"></struts:textfield>
              <struts:password name="password" label="密码"></struts:password>
              <struts:submit value="登录"></struts:submit>
          </struts:form>
  
      helloween, 1234
  
  </body>
</html>
配置web.xml文件
Struts1使用ActionServlet作为分发器,struts2使用filter作为分发器,需在web.xml的最后面配置struts的filter;修改action后缀可在web.xml或者struts.properties内配置struts.action.extension为其他值;
<!-- Struts2的Filter的URI配置 -->
    <filter-mapping>
        <filter-name>struts</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

<filter>
        <filter-name>struts</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.FilterDispatcher
        </filter-class>
        <!-- 
            <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.helloweenvsfei.struts2.action</param-value>
            </init-param>
            <init-param>
            <param-name>struts.action.extension</param-name>
            <param-value>helloween</param-value>
            </init-param>
        -->
    </filter>
Struts2工作流程
    新建loginaction.java------在struts.xml配置该action名称为loginperson------登陆界面提交表单给名称为“loginperson”的action-----struts截获请求-----查找struts.xml中名称为loginperson的action,创建名称为loginperson的action实例-----将提交的数据通过set方法设置到实例中----调用action的主方法execute()------根据结果跳转到配置的对应的welcome.jsp显示界面。
Struts线程安全
    每次请求都会创建一个action实例,实例间彼此独立,处理完后销毁,所以线程安全;
16.2struts配置文件
Web.xml配置struts2的分发器filter,struts.properties配置struts2的默认属性,可不添加该文件,struts.xml配置struts2的action;
Package有继承的特性,子package可以引用父package内的所有资源;package内可以配置命名空间,访问时需要加上命名空间;
16.3action详解
Actionsupport类中实现了一些基本方法,例如数据校验可直接被继承的action的使用;action接口只定义了execute方法,和几个常用的结果名称(success,error等),action类可以通过继承action接口来实现,Actionsupport类也继承与action接口;也可以不继承任何类和接口,只要实现execute方法即可;
自定义的action可执行方法
Action的可执行方法可以是其他方法,但必须是无参数返回值为string的方法;
用login!loginout.action的url访问;
或者需要在struts.xml中配置class后面加上method=“logout”, login为配置文件中的action的名称,loginout为方法名称;
还可以通过通配符*来配置,避免配置login和logout两种action输出;
<action name =”*Person”   class=””  method=”{1}”>
<result  name=”success”>/welcome.jsp</result >
<result  name=”{1}”>/{1}.jsp</result >
</action>
16.4用注解@代替struts.xml的配置
    直接在定义action的文件中通过注解的方式来实现action的配置,如下
@namespace (value=”/test”)             //命名空间
@Results({                          //结果集
@result(name=”success”, value =”/success.jsp”),
@result(name=”redirect”, value =”/redirect.jsp”,type=ServletRedirectResult.class)
})
注解方式配置的action的访问方式
    ,因为没有访问路径的配置,需要去掉类名中的action,并且首字母小写,例如Annotated Action的访问方式为annotated.action.annotated!login.action;
    零配置需要在web.xml中配置action包的位置,指定了actionPackage后,只会加载注解action,struts.xml配置文件中配置将失效;注解配置和strutsxml文件配置只能二选一;
<init-param>
<param-name>actionPackages</param-name>
<param-value>com.helloweenvsfei.struts2.action</param-value>
</init-param>
16.5 action中的pojo(简单普通java对象,plain ordinary java object)
    Action中的定义的pojo类需要定义get和set方法,struts2会自动完成pojo属性的赋值;使用struts:url标签来标示,action的方法,调用时会自动添加.action的后缀,无需主动添加;如下所示;
<a href="<struts:url action="initAddBook" />">添加书籍</a>
<a href="<struts:url action="listBook" />">书籍列表</a>
<a href="<struts:url action="clearBook" />">清空书籍列表</a>
禁用自动添加,可以如下
 
 
<a href="<struts:url action="initAddBook"  includeParams=”none”/>">
 
 
或者直接在struts.properties中禁用所有的自动追加特性
 
 
Struts.url.includeParams=none
 
 
第16章 struts2.x高级应用
17.1日期时间转换器
继承与DefaultTypeConverter类,实现convertValue接口,三种日期格式和两种时间格式放入数组内,然后根据输入数据的类型,循环调用每种格式转换,正确的返回值;
    在配置文件xwork-conversion.properties中配置数据类型对应的转换器(或者在struts的action中配置convertor=“com.helloweenvsfei.struts2.convertor.DatatimeConvertor”,这样只能被该action使用)------输入界面输入提交信息给action-----struts截获请求查找配置文件中action将提交的数据(是string类型,通过配置的转换器转化为对应的时间日期类型)注入到action的属性中,-----根据提交时的方法名称convert调用方法convert()-------返回success------action根据返回结果跳转到对应的jsp显示界面。
17.2ServletActionContext类
    需包含import org.apache.struts2.SeveletActionContext;该类中包含request、Response、ServletContext等对象;
    或者实现*Aware(ServletContextAware、ServletRequestAware、ServletResponseAware、SessionAware)接口来,并实现set*方法(session的方法是setSession(Map sessionValues),map表示内部存储的各种数据,),将数据注入action的属性中;
17.3validator校验数据
    支持校验必须继承Validateable接口,actionsupport类就继承该接口;在package内添加校验配置文件,名称按照格式Action类名-validation.xml或者Action类名-Action别名-validation.xml;例如下:
!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
    <!-- 检查书名,必须非空 -->
    <field name="book.name">
        <field-validator type="requiredstring">
            <param name="trim">true</param>
            <message>请输入书籍名称</message>
        </field-validator>
    </field>
    <!-- 检查作者,必须非空 -->
    <field name="book.author">
        <field-validator type="requiredstring">
            <message>请输入书籍作者</message>
        </field-validator>
    </field>
    <!-- 检查出版日期。 -->
    <field name="book.publishedDate">
        <field-validator type="date">
            <param name="min">1900-01-01</param>
            <param name="max">2200-01-01</param>
            <message><![CDATA[ 日期格式必须位于 1900-01-01 与 2200-01-01 之间 ]]></message>
        </field-validator>
    </field>
</validators>
客户端validator校验配置,<struts:form>标签添加validate=“true”属性;
    或者通过注解来添加校验;

 

第18章 struts 标签
18.1struts2标签
统一包含在struts-tags-tld文件中,位于Struts-core-2.0.11.1.jar的META-INF中;
18.2ognl语言
(object-graph navigation language)是操作对象属性的语言,可以用#获取上下文的资源;
#parameters表示request提交的所有参数,#request表示request的所有属性;
流程
先action继承ServletContextAware、ServletRequestAware、SessionAware接口,定义对象属性,和set方法,execute()方法设置对象的一些属性值;在ognlSUCCESS.jsp中直接通过<struts:property  value=”#request.account”>显示值;
18.3控制标签
 
 
<struts:if  test=”name= ‘ kuto’ ”> hello kuto </struts:if> 
<struts:elseif test=”name= ‘ fvssd’ ”> hello fvssd </ struts:elseif >
<struts:else> hello other </ struts:elseif >
 
 
第19章 struts2拦截器和文件上传
19.1 使用拦截器
面向切面的开发思想,把相对独立的代码抽象出来,如数据转换和数据校验,action在struts.xml中配置的时候,package中需要继承struts-default才能使用struts的拦截器,如下
<package name="main" extends="struts-default">
Struts有很多现成的拦截器
Timer计时拦截器计算action执行的时间
<action name="timer"
            class="com.helloweenvsfei.struts2.action.TimerAction">
            <interceptor-ref name="timer"></interceptor-ref>
            <result>/timerSuccess.jsp</result>
        </action>
Token防重复提交拦截器
 
 
<action name="token"
            class="com.helloweenvsfei.struts2.action.TokenAction">
            <interceptor-ref name="token"></interceptor-ref>
            <interceptor-ref name="basicStack" />//必须的,自动赋值拦截器集合
            <result>/tokenSuccess.jsp</result>
            <result name="input">/tokenInput.jsp</result>
            <result name="invalid.token">/tokenInvalid.jsp</result>//失败跳转界面,必须
        </action>
 
 
表单中要加一个<struts:token />标记,才会触发token拦截器;这个标记在Session中生成表单的唯一标示,提交一次后失效;
execAndWait执行等待拦截器显示等待页面
 
 
<action name="wait"
            class="com.helloweenvsfei.struts2.action.WaitAction">
            <interceptor-ref name="completeStack" />//完成后触发
            <interceptor-ref name="execAndWait" />等待触发
            <result>/waitSuccess.jsp</result>
            <result name="wait">/waiting.jsp</result>
        </action>
 
 
自定义权限验证拦截器
自定义拦截器要继承interceptor接口或者abstractInterceptor抽象类,是一个java文件,需要实现intercept(ActionInvocation  invocation)return invocation.invoke();表示继续调用action,否则权限不通过返回登陆界面return action.LOGIIN;定义好intercept类后需要在struts.xml中配置该拦截器,如下
 
 
<interceptors>
            <interceptor name="authentication"
                class="com.helloweenvsfei.struts2.interceptor.AuthenticationInterceptor">
            </interceptor>
</interceptors>
 
 
然后在需要使用该拦截器的action中配置该拦截器,与struts2的默认拦截器配置相同;
<action name="authentication"
            class="com.helloweenvsfei.struts2.action.AuthenticationAction">
            <interceptor-ref name="authentication"></interceptor-ref>
            <result>/authenticationSuccess.jsp</result>
        </action>
19.2上传文件
Struts2文件封装在java.io.File中,需要定义一个对象用于接收表单上传的文件,struts2会将文件复制到一个临时文件夹中,以时间戳为名,后缀为|.tmp,避免重复,File属性保存的就是这个临时文件的路径加名字;要获取该文件的原始名称和原始属性,需要定义string类型的属性,命名格式为XXFileName和XXContentType,struts2会将原文件名和类型输入到这两个属性上;需要用循环写入的方式复制文件数据;
package com.helloweenvsfei.struts2.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class UploadAction extends ActionSupport {

    private static final long serialVersionUID = -60950803930068947L;

    private File picture;//定义file属性保存临时文件名

    private String pictureContentType; //保存数据类型File对象名字+ContentType

    private String pictureFileName;//保存文件的真实名字File对象名字+FileName
    public String execute() {
        return "input";
    }

    public String upload() throws Exception {

        System.out.println("Context: "
                + ServletActionContext.getServletContext()
                        .getRealPath("upload"));

        System.out.println("File: " + picture);

        System.out.println("FileName: " + pictureFileName);

        File saved = new File(ServletActionContext.getServletContext()
                .getRealPath("upload"), pictureFileName);//创建保存的文件

        InputStream ins = null;
        OutputStream ous = null;

        try {
            saved.getParentFile().mkdirs();

            ins = new FileInputStream(picture);
            ous = new FileOutputStream(saved);

            byte[] b = new byte[1024];
            int len = 0;

            while ((len = ins.read(b)) != -1) {//循环读取临时文件数据保存到服务器的文件中
                ous.write(b, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ous != null)
                ous.close();
            if (ins != null)
                ins.close();
        }

        return "list";
    }

    public File getPicture() {
        return picture;
    }

    public void setPicture(File file) {
        this.picture = file;
    }

    public String getPictureContentType() {
        return pictureContentType;
    }

    public void setPictureContentType(String fileContentType) {
        this.pictureContentType = fileContentType;
    }

    public String getPictureFileName() {
        return pictureFileName;
    }


    public void setPictureFileName(String fileFileName) {
        this.pictureFileName = fileFileName;
    }

}
上传文件的设置
    默认使用javax.servlet.context.tempdir作为工作目录,可以通过设置struts.multipart.saveDir属性修改目录,struts.multipart.maxSize来修改最大上传文件大小,默认2097152byte;自带的拦截器可以设置
<interceptor-ref name="fileUpload">
                <param name="allowedTypes">
                    image/bmp,image/x-png,image/gif,image/jpeg
                </param>
                <param name="maximumSize">20480</param>
            </interceptor-ref>
第20章 hibernate入门
20.1hibernate简介
Hibernate是一种对象-关系数据库-映射(ORM,object-relative database-mapping),将pojo拆分成各种属性自动组织sql语句,保存到数据库;或者将数据中数据抽取出来,拼装成pojo对象返回;
20.2使用hibernate步骤
新建webproject------右键addhibernateCapabilities------添加hibernate包------配置实体类----在hibernate.cfg.xml中配置数据库连接信息,还有注解实体类信息或者无注解的实体类+类配置文件信息;-----创建CatTest.java文件,severlet的main函数中创建Session相当于数据库连接------创建Transaction相当于任务-------然后用Session的函数去实现对象与数据库记录之间的映射; 
可以将Hibernate的的数据库操作封装成一个类,将Session和transaction的创建和销毁封装起来;创建BaseDAO.java文件内部参数采用object,可以接收任意的实体类,hibernate实现实体类和数据库之间的数据交互;在severlet的doPost函数中根据不同的参数来调用不同的函数,函数中调用BaseDAO中封装的数据库操作函数;
 
 
package com.helloweenvsfei.hibernate.bean;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.QueryHint;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

//@NamedQuery(name = "all cat", query = " select c from Cat c ")
//@NamedNativeQuery(name = "all cat", query = "select * from tb_cat")
@NamedQueries(value = {
        @NamedQuery(name = "all cat", query = " select c from Cat c "),
        @NamedQuery(name = "cat by name", query = " select c from Cat c where c.name = :name ", hints = { @QueryHint(name = "org.hibernate.callable", value = "true") }),
        @NamedQuery(name = "cat by mother", query = " select c from Cat c ") })
//@NamedNativeQueries(value = {
//        @NamedNativeQuery(name = "all cat", query = "select * from tb_cat"),
//        @NamedNativeQuery(name = "all cat", query = "select * from tb_cat"),
//        @NamedNativeQuery(name = "all cat", query = "select * from tb_cat") })
@Entity
// 注解Entity表示该类能被Hibernate持久化
@Table(name = "tb_cat")
// 指定该Entity对应的数据表名
public class Cat {

    @Id
    @Column(name = "id")
    // 指定该列为主键
    @GeneratedValue(strategy = GenerationType.AUTO)
    // 主键类型, auto为数据库自增长类型
    private Integer id;

    @Column(name = "name")
    // 指定属性对应的数据库表的列为“name”
    private String name;

    @Column(name = "description")
    // 同上。@Column与name均可省略
    private String description;

    @ManyToOne
    // 指定POJO之间的关系,本例为多对一关系
    @JoinColumn(name = "mother_id")
    // 该属性对应的列
    private Cat mother;

    @Temporal(TemporalType.TIMESTAMP)
    // 日期类型(DATE, TIME还是TIMESTEMP)
    @Column(name = "createDate")
    private Date createDate;

    @OneToMany(mappedBy = "cat")
    // @JoinColumns(value = { @JoinColumn(name = "cat_id", referencedColumnName
    // = "id") })
    private List<Event> events = new ArrayList<Event>();
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Cat getMother() {
        return mother;
    }
    public void setMother(Cat mother) {
        this.mother = mother;
    }
    public Date getCreateDate() {
        return createDate;
    }
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public List<Event> getEvents() {
        return events;
    }
    public void setEvents(List<Event> events) {
        this.events = events;
    }
}
 
 
Hibernate操作数据库
 
 
// 开启一个 Hibernate 对话
        Session session = HibernateSessionFactory.getSessionFactory()
                .openSession();
        // 开启一个事务
        Transaction trans = session.beginTransaction();

        // 将三只猫的资料保存到数据库
        session.persist(mother);
        session.persist(kitty);
        session.persist(mimmy);

        // 查询数据中的所有的猫
        @SuppressWarnings("all")
        List<Cat> catList = session.createQuery(" from Cat ").list();

        StringBuffer result = new StringBuffer();
        result.append("数据库里的所有的猫:\r\n\r\n");

        // 遍历 输出猫与猫妈妈
        for (Cat cc : catList) {
            result.append("猫: " + cc.getName() + ",          ");
            result.append("猫妈妈: "
                    + (cc.getMother() == null ? "没有记录" : cc.getMother()
                            .getName()));
            result.append("\r\n");
        }
    trans.commit();//结束事物
    session.close();//关闭Session
 
 
第21章 从宏观上把握hibernate
SessionFactory是一个线程安全的Session工厂类,为不同的线程提供Session,维护这Session的相关德尔资源,包括数据库连接池等、缓存信息;
Transaction代表一次事物,事物提交后,修改的数据操作才会生效。
在hibernate.properties中配置数据库的类型和连接信息,在hibernate.cfg.xml中配置注解实体类或者实体类的配置文件;
第22章hibernate实体映射
主键配置(用@id申明主键,用@cloumn申明该列的名称,@GeneratedValue指定生成策略,可以是自增长、源于其他表格、sequence等);主键生成规则(GenerationType.AUTO、GenerationType.TABLE、GenerationType.SEQUENCE、 GenerationType.INDENTITY)、
普通属性配置,使用@Cloumn配置,属性nullable(是否允许为null)、unique(是否唯一)、insertable(是否允许插入)updateable(是否允许更新)、length(列长度)、cloumnDefinition(列类型)、scale(整数长度)、precision(小数点精度);
@Cloumn(name=“salry”,nullable=true,cloumnDefinition=“number”,insertable=true)
用@Basic为普通属性配置加载方式,默认及时加载,如果数据比较大,可设置为延时加载,optional配置该列是否可以为null;
@Basic(fetch=FetchType.LAZY,optional=true)// FetchType.EAGER
配置日期属性配置;如果日期类型是java.util.Date类型,必须用@temporal配置日期类型。如果是java.sql.Date、 java.sql. Time、java.sql.TimeStamp,则无需申明;
 
 
@Temporal(TemporalType.TIMESTAMP)
@Cloumn(name=”createDate”)
Private java.util.Date createDate;
 
 
  临时属性;@Transient标注,表示临时为了方便计算而创建的属性,不会写入数据库;对应的getset方法也要配置;而对于所有没有配置到配置文件中都是临时属性;
   版本属性;乐观锁和悲观锁@Version;悲观锁操作时锁住,完成后释放;乐观锁采用Version属性来判断是否被修改,是否要重新读取;允许多条线程同时访问数据;
 
 
@version
Private int version;//注解配置
<version name =”version”></version>//要配置在主键后,普通属性前
<version type“timestamp” column=”version”></version>//配置文件配置可以是int、long、Timestamp;
 
 
第24章 Hibernate查询语言HQL
    HQL是面向对象的语言,直接将对象用于数据库查询语句,大小写不敏感,同名时用package区分;
查询数量计数
 
 
Number num=(Number)Session.createQuery(“select count(c) from Cat c”).uniqueResult();
 
 
返回集合属性
 
 
List<stirng[]> namelist =session.createQuery(“select c.name,c.mother.name from Cat c”).list();
List<Cat> catlist=session.createQuery(select c.mother from Cat c).list();
 
 
返回不同的多个对象,对象数组
 
 
List<Object[]> olist=session.createQuery(“select c.name,c.mother ,c.createDate from Cat c”).list();
返回list类型
List<List> list2=session.createQuery(“Select new list(c.name,c.mother,c.createDate)from Cat c”).list();
返回map类型
 
 
List listmap=Session.createQuery(“select new map(c.name as name,c.mother as mother, c.createDate as createDate ) from Cat c)”).list();
返回java实体对象
List<Cat> catlist=session.createQuery(“select new Cat(cat.name,cat.createDate) from Cat c”).list();
条件语句
 
 
Session.createQuery(“select c from Cat c where c.mother=null and c.createDate <:createDate”).setParameter(“createDate”,new Date()).list();
 
 
统计函数
语句中Count()、sum()min()、max(),avg()、count();返回 uniqueResault()类型与主键类型相同;
分页查询数据,获取查到的数据
 
 
List<Cat> cslist =session.createQuery(“from Cat”).setFirstResult(0).setMaxResault(10).list();
 
 
跨表查询
 
 
Select e From event e where e.cat.name=’ketty’                //查询Event和cat表;
级联查询
List<Cat> blist=session.createQuery(“Select c from Cat c left join c.events e where e.description like :description”).setParameter(“description”,”%吃早饭%”).List();
SQL查询
 
 
Session.createSQLQuery(“select * from tb_cat”);
 
 
@配置命名查询
将常用的查询用一个字符串来代替,相当于宏定义,在实体类的定义的前面配置
 
 
@NameQuery(name=”all cat”,query=”select c from Cat c”)//配置HQL查询
@NameNativeQuery(name=“all cat”,query=“select * from tb_cat”)
在xml配置文件中配置命名查询,name配置查询的名称,<return/>配置返回数据类型;
<sql_query name=”cat all”><![CDATA[]]><return alias=””,class=com.helloweenvsfei. hibernate.bean.Cat/></sql_query>;
第26章 Spring概述
26.1Spring 框架
Spring是一种轻量级的框架或容器,一般的程序是从外到内的过程,即程序应用层(main函数实例化服务对象,调用服务的接口函数)、service层(实现服务接口函数,实例化DAO对象,并调用其方法)、DAO层(实现真正的业务逻辑);而Spring则是从内到外的一个过程;
Spring使用流程,定义IDao的接口和实现类DaoImpl,定义IService接口和ServiceImpl实现类,在ServiceImpl定义IDao变量和set、get方法;而不是调用DAOimpl对象;通过配置文件将serviceImpl与DaoImpl类关联起来,建立依赖关系,相当于service.setDao(DaoImpl);Spring在运行时,根据配置注入依赖的对象,Spring实例化对象并维护对象,在编码阶段没有实例化,而是在运行阶段注入对象,并实例化、组装对象、维护对象,与传统的写代码,实例化、组装对象,执行方法方向相反;
 
 
<bean id="serviceImpl"
        class="com.helloweenvsfei.spring.example.ServiceImpl">
        <property name="dao">    
<bean class="com.helloweenvsfei.spring.example.DaoImpl"></bean>
        </property>
    </bean>
 
 
或者按照下面的配置
 
 
<!-- dao 实例 -->
<bean id="daoimpl" class="com.helloweenvsfei.spring.example.DaoImpl">
</bean>
<bean id="serviceImpl"
        class="com.helloweenvsfei.spring.example.ServiceImpl">
        <property name="dao" ref=” daoimpl”></property>
</bean>
 
 
26.3面向切面的编程
面向切面编程(Aspect oriented programming)将程序分成独立的几段,可以按不同顺序执行,方便添加删除功能;Spring实现了特定的AOP即可的类称为拦截器;
package com.helloweenvsfei.spring.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MethodBeforeInterceptor implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object instance)方法、参数、实例;
            throws Throwable {
        System.out.println("即将要执行方法:" + method.getName());
        if (instance instanceof AopServiceImpl) {
            String name = ((AopServiceImpl) instance).getName();
            if (name == null)
                throw new NullPointerException("name属性不能为null");
        }
    }
}
第27章 Spring的core模块
Core的主要功能是实现反向控制、依赖注入、beans配置和加载;有Beans、BeanFactory(加载beans)、BeanDefinition(beans的定义)ApplicationContext(配置文件);
27.1BeanFactory工厂
BeanFactory根据配置实例化beans对象,并设置相互依赖性,将beans注入sevelet、struts的Action中、Hibernate资源中;web程序无需实例化BeanFactory,自动实例化;java桌面程序中需要根据配置文件加载实例化,用ClassPathResourse加载ClassPath下的文件,或者用FileInputStream加载任意路径的配置文件,或者用ClassPathXmlApplicationContext加载多个配置文件;
27.2 配置java bean
配置文件中用id配置名称,class配置类名,必须两个参数;如果为工厂类(无类名构造函数),需要用factory-bean配置类名,factory-method配置构造函数名称;如果构造函数有参数,需要用<constroctor-arg><ref bean =”yetBean”/></constroctor-arg>配置参数;
单态模式singleton,默认为单态模式,非单态模式需要设置bean属性singleton=“false”;
属性设置,通过<property  name=””, value=””></property>配置,Spring根据set方法设置;
 
 
<bean id="dataSource"//id和class必须
        class="org.apache.commons.dbcp.BasicDataSource"
<constroctor-arg><ref bean =”yetBean”/><constroctor-arg>//配置构造函数的两个参数,一个bean参数,一个数值参数, ref表示引用配置文件中其他的bean;yetBean为id
<constroctor-arg><value>1</value></constroctor-arg>
        destroy-method="close" (关闭方法,析构函数)singleton=”true”>//单态模式
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />//配置属性
        <property name="url"
            value="jdbc:mysql://localhost:3306/spring?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="admin" />
</bean>
 
 
配置list、set、map属性
 
 
<property name="interceptorNames">//list属性配置
            <list>
                <value>aopMethodBeforeInterceptor</value>
                <value>aopMethodAfterInterceptor</value>
                <value>aopThrowsInterceptor</value>
            </list>
</property>
<property name="interceptorNames">
            <set>//set属性配置
                <value>aopMethodBeforeInterceptor</value>
            </set>
</property>

<property name="someMap">
            <map>//map属性配置
            <entry key="yup an entry">//map键值对的键
            <value>just some string</value>//map键值对的值
            </entry>
            <entry key-ref="myDataSource">//bean map
            <ref bean="myDataSource" />
            </entry>
            </map>
</property>
 
 
depend-on设置依赖关系,加载之前先加载依赖的对象;
 
 
<bean id="personDao"
        class="com.helloweenvsfei.spring.dao.PersonDaoImpl"
        depends-on="dataSource" init-method="initDatabase">//依赖关系和初始化方法
        <property name="dataSource" ref="dataSource"></property>
</bean>
 
 
27.3属性自动装填autowire
<bean id="d" class="examples.D" autowire="byType"></bean>设置bean为自动装填后,会根据设置的规则去自动设置,不用<property  name=”” value=””>设置;
27.4依赖检查dependency
检查bean的属性是否被设置,还可以设置为no、simple、object、all;
<bean id="bean" class="examples.Bean" dependency-check="all"></bean>,
27.5Bean的高级特性
继承Spring的一些接口BeanNameAware和BeanFactoryAware,设置或获取bean的id、BeanFactory和初始化和销毁函数,但是会使程序与Spring耦合,依赖Spring的类库;
27.6BeanFactory高级特性
如果实现了BeanFactoryAware接口,可以获取BeanFactory对象,可以调用他的方法判断是否包含Bean,获取指定名称的bean,是否配置为singleton等;
第28章 Spring的AOP模块
28.1拦截器的使用
AOP是面向切面的编程方法,将一个业务流程分成几部分实现,再组装成一个完整的流程;
先定义IAopServiceAop.java接口,定义两个函数withaop和withoutaop;创建IAopServiceAopImpl.java实现类,实现两个方法;创建文件*interceptor.java实现MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice接口,实现三种拦截器;在配置文件ApplicationContext.xml中配置三种拦截器和拦截的方法,配置service对象,并采用list配置三种拦截器;在main函数中执行方法;
    Spring无法将service实现类和拦截器直接组装,需要把拦截器安装到代理类NameMatchMethodPointcutAdvisor,把自定义的Service安装到ProxyFactoryBean中,
 
 
<!-- 拦截器 在 withAop() 方法前运行 -->
    <bean id="aopMethodBeforeInterceptor"
        class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        <property name="advice">
            <bean
                class="com.helloweenvsfei.spring.aop.MethodBeforeInterceptor" />
        </property>
        <property name="mappedName" value="withAop"></property>
    </bean>

    <!-- 拦截器 在 withAop() 返回后运行 -->
    <bean id="aopMethodAfterInterceptor"
        class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        <property name="advice">
            <bean
                class="com.helloweenvsfei.spring.aop.MethodAfterInterceptor" />
        </property>
        <property name="mappedName" value="withAop"></property>
    </bean>

    <!-- 拦截器 在异常抛出后运行 -->
    <bean id="aopThrowsInterceptor"
        class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
        <property name="advice">
            <bean
                class="com.helloweenvsfei.spring.aop.ThrowsInterceptor" />
        </property>
        <property name="mappedName" value="withAop"></property>
    </bean>
<bean id="aopService"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 拦截器 -->
        <property name="interceptorNames">
            <list>//用list配置三种拦截器
                <value>aopMethodBeforeInterceptor</value>
                <value>aopMethodAfterInterceptor</value>
                <value>aopThrowsInterceptor</value>
            </list>
        </property>
        <!-- 被拦截的对象 -->
        <property name="target">
            <bean
                class="com.helloweenvsfei.spring.aop.AopServiceImpl">
                <!-- 
                    <property name="name"><null /></property>
                    <property name="name" value="Helloween"></property>
                -->
            </bean>
        </property>
    </bean>
 
 
在main函数中执行函数
 
 
package com.helloweenvsfei.spring.aop;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class AopRun {
    public static void main(String[] args) throws Exception {
        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(
                "applicationContext.xml"));
        IAopService hello = (IAopService) factory.getBean("aopService");
        hello.withAop();
        hello.withoutAop();
        factory.destroySingletons();
    }
}
 
 
28.2拦截器和Filter区别
两者都是基于AOP的编程思想;在程序应用范围、使用容器、使用资源、使用深度上有所区别;Filter只能用于web程序,拦截器还可以用于Application和swing;filter适用Servlet容器,拦截器适用于Spring容器;拦截器可以使用的资源更多;filter只能在servlet前后使用,Spring更深入,能在方法前后使用;


第29章 Spring的DAO模块
29.1数据库操作封装
    Spring对jdbc进行了封装,不需要进行数据库连接和事物提交等工作;直接用jdbcTemplate执行SQL语句;
    实现步骤 定义Person.java文件实现Person类,定义属性和set、get方法;创建IPersonDao.java文件,定义操作接口;创建PersonDaoImpl.java文件,实现IPersonDao接口并继承与JdbcDaoSupport类,实现接口函数是对象与数据库的映射关系,并定义初始化initDateBase()函数用于创建数据库表格,JdbcDaoSupport类封装了数据库连接和任务,通过jdbcTemplate执行sql语句,getJdbcTemplate()获取对象,调用方法queryForList(sql),update(sql,new object[]{});在ApplicationContext.xml配置文件中配置数据源,即数据库的类型、名称、url、登陆用户名和密码等信息;在配置文件的DAO中配置数据源和初始化函数;运行程序,创建DaoRun.java文件,在main函数中创建BeanFactory对象,加载
29.2实体对象与数据库映射
继承MappingSqlQurry抽象类,实现mapRow接口,接口内将查询结果赋值给对象,需要调用setDateSource()、setsql()函数设置数据源和sql语句,调用compile()执行编译,调用declareParameter()设置参数,调用execute()返回结果;
ApplicationContext.xml文件,获取IPersonDao对象,调用对象的函数实现对象到数据库的操作;
 
 
package com.helloweenvsfei.spring.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.object.MappingSqlQuery;
public class PersonMappingQuery extends MappingSqlQuery {
    @Override
    protected Object mapRow(ResultSet rs, int columnIndex) throws SQLException {
        Person person = new Person();
        person.setId(rs.getInt("id"));
        person.setName(rs.getString("name"));
        person.setSex(rs.getString("sex"));
        person.setAge(rs.getInt("age"));
        person.setBirthday(rs.getTimestamp("birthday"));
        return person;
    }
}
 
 
继承SqlUpdate类,执行SQL更新语句。继承SqlDunction返回单一结果;
29.3Spring的事物管理
Spring默认在DAO的方法上加事物,一个方法算一个事物;但是一个方法执行失败不会让上一个方法回滚;
先配置一个事物管理者jdbcTransactionManager,传入数据源信息,在ApplicationContext.xml按照bean配置;为事物管理者配置事物属性transactionAttributeSource;为IPersonDao类配置管理者和管理属性;run方法中某个调用函数失败,整个run方法会回滚;
 
 
<!-- JDBC 事务管理 -->
    <bean id="jdbcTransactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">//事物管理者
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 为所有的方法配置事务 -->
    <bean id="transactionAttributeSource"
    class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">
        <property name="properties">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>

    <!-- 
        <bean id="transactionRun"
        class="com.helloweenvsfei.spring.dao.TransactionRun">
        <property name="personDao" ref="personDao"></property>
        </bean>
    -->

    <!-- TransactionRun ,被管理的对象-->
    <bean id="transactionRun"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager"
            ref="jdbcTransactionManager" />
        <property name="target">
            <bean
                class="com.helloweenvsfei.spring.dao.TransactionRun">
                <property name="personDao" ref="personDao"></property>
            </bean>
        </property>
        <property name="transactionAttributeSource"
            ref="transactionAttributeSource" />
    </bean>
 
 
第30章 Spring的ORM模块
30.1Spring保存实体类
Spring封装了hibernate的Session和transation,内部管理这些资源;让用户只需关心对象与数据库之间的关系映射(Object-Relational Mapping);
使用步骤
创建Cat.java文件,定义Cat实体类,加注解;创建ICatDao.java文件定义ICatDao接口;创建CatDaoImpl.java文件实现ICatDao接口并继承HibernateDaoSupport类,该类提供HibernateTemplate对象对实体类进行操作;
 
 
package com.helloweenvsfei.spring.orm;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class CatDaoImpl extends HibernateDaoSupport implements ICatDao {
    public void createCat(Cat cat) {
        this.getHibernateTemplate().persist(cat);
    }
    public Cat findCatByName(String name) {
        List<Cat> catList = this.getHibernateTemplate().find(
                " select c from Cat c where c.name = ? ", name);
        if (catList.size() > 0)
            return catList.get(0);
        return null;
    }
    public int getCatsCount() {
        return (Integer) this.getSession(true).createQuery(
                " select count(c) from Cat c ").uniqueResult();
    }
    public List<Cat> listCats() {
        return this.getHibernateTemplate().find(" select c from Cat c ");
    }
}
 
 
30.2Spring中配置Hibernate
需要在ApplicationContext.xml中配置数据源、SessionFactory及CatDaoImpl、实体类;先配置数据源,然后配置SessionFactory,在SessionFactory中配置数据源,和加载的实体类路径和实体类名称,最后配置实体类操作类DAOImpl,设置SessionFactory属性;也可以加载配置文件配置的实体类;
 
 
<bean id="dataSource"配置数据源
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url"
            value="jdbc:mysql://localhost:3306/spring?characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="admin" />
    </bean>
<!-- Spring SessionFactory -->配置SessionFactory
    <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
        destroy-method="destroy">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedPackages"配置实体类的加载路径
            value="classpath:/com/helloweenvsfei/spring/orm">
        </property>
        <property name="annotatedClasses">配置实体类
            <list>
                <value>com.helloweenvsfei.spring.orm.Cat</value>
            </list>
        </property>
        <property name="hibernateProperties">配置Hibernate属性
            <props>
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.MySQLDialect
                </prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">false</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>

    <bean id="catDao"
        class="com.helloweenvsfei.spring.orm.CatDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>设置SessionFactory
    </bean>
 
 
30.3管理Hibernate事物
Spring默认在DAO层添加事物,每个方法一个事物。在DAO层添加service,在service层添加事物;
先定义一个HibernateTransactionManager管理器,在管理器中添加SessionFactory;然后添加事物管理规则,为所有的方法添加事物;借助Spring的代理类TransactionProxyFactoryBean,为DAOimpl配置事物管理器和管理规则
 
 
<bean id="hibernateTransactionManager"配置事物管理器
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />配置SessionFactory
    </bean>
    <bean id="hibernateTransactionAttributeSource"//配置事物管理规则
    class="org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource">//使用代理类
        <property name="properties">
            <props>
                <prop key="*">PROPAGATION_REQUIRED</prop>//所有方法加上事物
            </props>
        </property>
    </bean>

    <bean id="catService"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager"
            ref="hibernateTransactionManager">
        </property>
        <property name="target">
            <bean
                class="com.helloweenvsfei.spring.orm.CatServiceImpl"> CatServiceImpl不能直接加事物,需要借助TransactionProxyFactoryBean代理类
                <property name="catDao" ref="catDao"></property>//设置DAO依赖关系catDao是.CatServiceImpl的一个属性
            </bean>
        </property>
        <property name="transactionAttributeSource"
            ref="hibernateTransactionAttributeSource">
        </property>
    </bean>
 
 
第31章 Spring的web模块
31.1整合strut1.x:继承方式
CatAction直接继承ActionSupport类,GetWebApplicationContext().getBean(“iCatService”)先获取beanFactory,然后再获取各种资源;在CatAction中添加execute方法,作为action的主方法,根据action的动作执行方法;然后在struts配置文件中配置action对应的文件名称。
Spring和struts需要配置到web.xml文件中,Spring要配置ApplicationContext.xml的位置,以及加载配置文件的ContextLoadLisener

 

 

 

转载于:https://www.cnblogs.com/kitor/p/9727079.html

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值