JAVA web中的一点东西

参考文献:
http://m.blog.csdn.net/article/details?id=45151569
http://www.cnblogs.com/goody9807/archive/2007/06/13/782519.html
http://www.runoob.com/jsp/jsp-tutorial.html

一点框架中的知识
目录:
1.Servlet
2.JSP
3.常用Java web框架
3.1Hibernate
3.2 Spring
3.3Struts2
4.其他

1.Servlet

Servlet是什么

Servlet定义:Servlet是基于Java技术的Web组件,由容器管理并产生动态的内容。Servlet引擎作为WEB服务器的扩展提供支持Servlet的功能。Servlet与客户端通过Servlet容器实现的请求/响应模型进行交互。
1)Servlet是按照Servlet规范编写的Java类。
2)Servlet应用请求/响应模型,扩展了服务器的功能。
Servlet是WEB应用程序中的一个组件。

Servlet技术特点

Servlet技术带给程序员最大的优势是它可以处理客户端传来的HTTP请求,并返回一个响应
Servlet是一个Java类,Java语言能够实现的功能,Servlet基本上都可以实现(图形界面除外)。总的来说,Servlet技术具有以下特点
1.高效。在服务器上仅有一个Java虚拟机在运行,它的优势在于当多个来自客户端的请求进行访问时,Servlet为每个请求分配一个线程而不是进程。
2.方便。Servlet提供了大量的实用工具例程,例如处理很难完成的HTML表单数据、读取和设置HTTP头、处理Cookie和跟踪会话等。
3.跨平台。Servlet是用Java类编写的,它可以在不同的操作系统平台和不同的应用服务器平台下运行。
4.灵活性和可扩展性。采用Servlet开发的Web应用程序,由于Java类的继承性、构造函数等特点,使得其应用灵活,可随意扩展。
6.共享数据。Servlet之间通过共享数据可以很容易地实现数据库连接池。它能方便地实现管理用户请求,简化Session和获取前一页面信息的操作。而在CGI之间通信则很差。由于每个CGI程序的调用都开始一个新的进程,调用间通信通常要通过文件进行,因而相当缓慢。同一台服务器上的不同CGI程序之间的通信也相当麻烦。
7.安全。有些CGI版本有明显的安全弱点。即使是使用最新的标准和PERL等语言,系统也没有基本安全框架。而Java定义有完整的安全机制,包括SSL\CA认证、安全政策等规范。

Servlet相关包的介绍

--javax.servlet.* :存放与HTTP 协议无关的一般性Servlet 类;
--javax.servlet.http.* :除了继承javax.servlet.* 之外,并且还增加与HTTP协议有关的功能。
  (注意:大家有必要学习一下HTTP协议,因为WEB开发都会涉及到)
  所有的Servlet 都必须实现javax.servlet.Servlet 接口(Interface)。
  若Servlet程序和HTTP 协议无关,那么必须继承javax.servlet.GenericServlet类;
  若Servlet程序和HTTP 协议有关,那么必须继承javax.servlet.http.HttpServlet 类。
--HttpServlet :提供了一个抽象类用来创建Http Servlet。
  public void doGet()方法:用来处理客户端发出的 GET 请求
  public void doPost()方法:用来处理 POST请求
  还有几个方法大家自己去查阅API帮助文件
--javax.servlet包的接口:
  ServletConfig接口:在初始化的过程中由Servlet容器使用
  ServletContext接口:定义Servlet用于获取来自其容器的信息的方法
  ServletRequest接口:向服务器请求信息
  ServletResponse接口:响应客户端请求
  Filter接口:
--javax.servlet包的类:
  ServletInputStream类:用于从客户端读取二进制数据
  ServletOutputStream类:用于将二进制数据发送到客户端
--javax.servlet.http包的接口:
  HttpServletRequest接口:提供Http请求信息
  HttpServletResponse接口:提供Http响应

Servlet生命周期

Servlet生命周期定义了一个Servlet如何被加载、初始化,以及它怎样接收请求、响应请求,提供服务。在讨论Servlet生命周期之前,先让我们来看一下这几个方法:
1. init()方法

  在Servlet的生命周期中,仅执行一次init()方法,它是在服务器装入Servlet时执行的,可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init();
  1. service()方法

    它是Servlet的核心,每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。

  2. destroy()方法

    仅执行一次,在服务器端停止且卸载Servlet时执行该方法,有点类似于C++的delete方法。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。

    下面来谈谈Servlet的生命周期,Servlet的生命周期是由Servlet容器来控制的,它始于装入Web服务器的内存时,并在终止或重新装入Servlet时结束。这项操作一般是动态执行的。然而,Server通常会提供一个管理的选项,用于在Server启动时强制装载和初始化特定的Servlet。

    在代码中,Servlet生命周期由接口javax.servlet.Servlet定义。所有的Java Servlet 必须直接或间接地实现javax.servlet.Servlet接口,这样才能在Servlet Engine上运行。javax.servlet.Servlet接口定义了一些方法,在Servlet 的生命周期中,这些方法会在特定时间按照一定的顺序被调用。
    这里写图片描述

加载和实例化Servlet

我们来看一下Tomcat是如何加载的:

 1. 如果已配置自动装入选项,则在启动时自动载入。

 2. 在服务器启动时,客户机首次向Servlet发出请求。

 3. 重新装入Servlet时。

  当启动Servlet容器时,容器首先查找一个配置文件web.xml,这个文件中记录了可以提供服务的Servlet。每个Servlet被指定一个Servlet名,也就是这个Servlet实际对应的Java的完整class文件名。Servlet容器会为每个自动装入选项的Servlet创建一个实例。所以,每个Servlet类必须有一个公共的无参数的构造器。

初始化

当Servlet被实例化后,Servlet容器将调用每个Servlet的init方法来实例化每个实例,执行完init方法之后,Servlet处于“已初始化”状态。所以说,一旦Servlet被实例化,那么必将调用init方法。通过Servlet在启动后不立即初始化,而是收到请求后进行。在web.xml文件中用 …… 对Servlet进行预先初始化。

初始化失败后,执行init()方法抛出ServletException异常,Servlet对象将会被垃圾回收器回收,当客户端第一次访问服务器时加载Servlet实现类,创建对象并执行初始化方法。

请求处理

Servlet 被初始化以后,就处于能响应请求的就绪状态。每个对Servlet 的请求由一个Servlet Request 对象代表。Servlet 给客户端的响应由一个Servlet Response对象代表。对于到达客户机的请求,服务器创建特定于请求的一个“请求”对象和一个“响应”对象。调用service方法,这个方法可以调用其他方法来处理请求。

Service方法会在服务器被访问时调用,Servlet对象的生命周期中service方法可能被多次调用,由于web-server启动后,服务器中公开的部分资源将处于网络中,当网络中的不同主机(客户端)并发访问服务器中的同一资源,服务器将开设多个线程处理不同的请求,多线程同时处理同一对象时,有可能出现数据并发访问的错误。

另外注意,多线程难免同时处理同一变量时(如:对同一文件进行写操作),且有读写操作时,必须考虑是否加上同步,同步添加时,不要添加范围过大,有可能使程序变为纯粹的单线程,大大削弱了系统性能;只需要做到多个线程安全的访问相同的对象就可以了。

卸载Servlet

当服务器不再需要Servlet实例或重新装入时,会调用destroy方法,使用这个方法,Servlet可以释放掉所有在init方法申请的资源。一个Servlet实例一旦终止,就不允许再次被调用,只能等待被卸载。

Servlet一旦终止,Servlet实例即可被垃圾回收,处于“卸载”状态,如果Servlet容器被关闭,Servlet也会被卸载,一个Servlet实例只能初始化一次,但可以创建多个相同的Servlet实例。如相同的Servlet可以在根据不同的配置参数连接不同的数据库时创建多个实例。

ServletConfig对象与ServletContext区别

ServletContext对象:servlet容器在启动时会加载web应用,并为每个web应用创建唯一的servlet context对象,可以把ServletContext看成是一个Web应用的服务器端组件的共享内存,在ServletContext中可以存放共享数据。ServletContext对象是真正的一个全局对象,凡是web容器中的Servlet都可以访问。

servletConfig对象:用于封装servlet的配置信息。从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对servlet自身有效,一个servlet的ServletConfig对象不能被另一个servlet访问。

这里写图片描述

简单实例

package cn.dragon.servlet;

//下面是导入相应的包

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

/**

* 这是第一个Servlet的例子

* @author cn.dragon

*/

public class ServletDemoFirst extends HttpServlet {   

  //用于处理客户端发送的GET请求   

  public void doGet(HttpServletRequest request, HttpServletResponse response)   

    throws ServletException, IOException {   

     response.setContentType("text/html;charset=GB2312"); //这条语句指明了向客户端发送的内容格式和采用的字符编码.   

     PrintWriter out = response.getWriter();    

     out.println(" 您好!"); //利用PrintWriter对象的方法将数据发送给客户端   

     out.close();   

  }   

  //用于处理客户端发送的POST请求   

  public void doPost(HttpServletRequest request, HttpServletResponse response)   

    throws ServletException, IOException {   

    doGet(request, response); //这条语句的作用是,当客户端发送POST请求时,调用doGet()方法进行处理   

  }

}

2.JSP

JSP是什么

JSP与PHP、ASP、ASP.NET等语言类似,运行在服务端的语言。
JSP(全称Java Server Pages)是由Sun Microsystems公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成HTML、XML或其他格式文档的Web网页的技术标准。
JSP技术是以Java语言作为脚本语言的,JSP网页为整个服务器端的Java库单元提供了一个接口来服务于HTTP的应用程序。
JSP文件后缀名为(*.jsp)。
JSP开发的WEB应用可以跨平台使用,既可以运行在Linux上也能运行在Window上。

why JSP

JSP程序与CGI程序有着相似的功能,但和CGI程序相比,JSP程序有如下优势:
性能更加优越,因为JSP可以直接在HTML网页中动态嵌入元素而不需要单独引用CGI文件。
服务器调用的是已经编译好的JSP文件,而不像CGI/Perl那样必须先载入解释器和目标脚本。
JSP基于Java Servlets API,因此,JSP拥有各种强大的企业级Java API,包括JDBC,JNDI,EJB,JAXP等等。
JSP页面可以与处理业务逻辑的servlets一起使用,这种模式被Java servlet 模板引擎所支持。
最后,JSP是Java EE不可或缺的一部分,是一个完整的企业级应用平台。这意味着JSP可以用最简单的方式来实现最复杂的应用。

JSP小例子

<html>
    <head>
           <title>第一个JSP程序</title>
    </head>
    <body>
           <%
                  out.println("Hello World!");
           %>
    </body>
</html>

JSP处理

以下步骤表明了Web服务器是如何使用JSP来创建网页的:
就像其他普通的网页一样,您的浏览器发送一个HTTP请求给服务器。
Web服务器识别出这是一个对JSP网页的请求,并且将该请求传递给JSP引擎。通过使用URL或者.jsp文件来完成。
JSP引擎从磁盘中载入JSP文件,然后将它们转化为servlet。这种转化只是简单地将所有模板文本改用println()语句,并且将所有的JSP元素转化成Java代码。
JSP引擎将servlet编译成可执行类,并且将原始请求传递给servlet引擎。
Web服务器的某组件将会调用servlet引擎,然后载入并执行servlet类。在执行过程中,servlet产生HTML格式的输出并将其内嵌于HTTP response中上交给Web服务器。
Web服务器以静态HTML网页的形式将HTTP response返回到您的浏览器中。
最终,Web浏览器处理HTTP response中动态产生的HTML网页,就好像在处理静态网页一样。
以上提及到的步骤可以用下图来表示:
这里写图片描述
一般情况下,JSP引擎会检查JSP文件对应的servlet是否已经存在,并且检查JSP文件的修改日期是否早于servlet。如果JSP文件的修改日期早于对应的servlet,那么容器就可以确定JSP文件没有被修改过并且servlet有效。这使得整个流程与其他脚本语言(比如PHP)相比要高效快捷一些。
总的来说,JSP网页就是用另一种方式来编写servlet而不用成为Java编程高手。除了解释阶段外,JSP网页几乎可以被当成一个普通的servlet来对待。

JSP 生命周期 

理解JSP底层功能的关键就是去理解它们所遵守的生命周期。
JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。
以下是JSP生命周期中所走过的几个阶段:
编译阶段:
servlet容器编译servlet源文件,生成servlet类
初始化阶段:
加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法
执行阶段:
调用与JSP对应的servlet实例的服务方法
销毁阶段:
调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例
很明显,JSP生命周期的四个主要阶段和servlet生命周期非常相似,下面给出图示:
这里写图片描述

jsp内置对象 

定义:可以不加声明就在JSP页面脚本(Java程序片和Java表达式)中使用的成员变量  JSP共有以下9种基本内置组件(可与ASP的6种内部组件相对应):  

1.request对象 

客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。  
序号 方 法 说 明  

   1 object getAttribute(String name) 返回指定属性的属性值  
        2 Enumeration getAttributeNames() 返回所有可用属性名的枚举  
        3 String getCharacterEncoding() 返回字符编码方式  
        4 int getContentLength() 返回请求体的长度(以字节数)  
        5 String getContentType() 得到请求体的MIME类型  
        6 ServletInputStream getInputStream() 得到请求体中一行的二进制流
        7 String getParameter(String name) 返回name指定参数的参数值
        8 Enumeration getParameterNames() 返回可用参数名的枚举  
        9 String[] getParameterValues(String name) 返回包含参数name的所有值的数组  
        10 String getProtocol() 返回请求用的协议类型及版本号  
        11 String getScheme() 返回请求用的计划名,如:http.https及ftp等  
        12 String getServerName() 返回接受请求的服务器主机名  
        13 int getServerPort() 返回服务器接受此请求所用的端口号  
        14 BufferedReader getReader() 返回解码过了的请求体  
        15 String getRemoteAddr() 返回发送此请求的客户端IP地址  
        16 String getRemoteHost() 返回发送此请求的客户端主机名  
        17 void setAttribute(String key,Object obj) 设置属性的属性值             18 String getRealPath(String path) 返回一虚拟路径的真实路径 

2.response对象 

    response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。  
    序号 方 法 说 明  
    1 String getCharacterEncoding() 返回响应用的是何种字符编码  
    2 ServletOutputStream getOutputStream() 返回响应的一个二进制输出流  
    3 PrintWriter getWriter() 返回可以向客户端输出字符的一个对象  
    4 void setContentLength(int len) 设置响应头长度  
    5 void setContentType(String type) 设置响应的MIME类型  
    6 sendRedirect(java.lang.String location) 重新定向客户端的请求 

3.session对象 

session对象指的是客户端与服务器的一次会话,从客户端连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.  
序号 方 法 说 明  
1 long getCreationTime() 返回SESSION创建时间  
2 public String getId() 返回SESSION创建时JSP引擎为它设的惟一ID号   3 long getLastAccessedTime() 返回此SESSION里客户端最近一次请求时间  
4 int getMaxInactiveInterval() 返回两次请求间隔多长时间此SESSION被取消(ms)  
5 String[] getValueNames() 返回一个包含此SESSION中所有可用属性的数组  
6 void invalidate() 取消SESSION,使SESSION不可用  
7 boolean isNew() 返回服务器创建的一个SESSION,客户端是否已经加入   8 void removeValue(String name) 删除SESSION中指定的属性  
9 void setMaxInactiveInterval() 设置两次请求间隔多长时间此SESSION被取消(ms)  

4.out对象 

    out对象是JspWriter类的实例,是向客户端输出内容常用的对象  
    序号 方 法 说 明  
    1 void clear() 清除缓冲区的内容  
    2 void clearBuffer() 清除缓冲区的当前内容  
    3 void flush() 清空流  
    4 int getBufferSize() 返回缓冲区以字节数的大小,如不设缓冲区则为0      5 int getRemaining() 返回缓冲区还剩余多少可用  
    6 boolean isAutoFlush() 返回缓冲区满时,是自动清空还是抛出异常
    7 void close() 关闭输出流  

5.page对象 

page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例  
序号 方 法 说 明  
1 class getClass 返回此Object的类  
2 int hashCode() 返回此Object的hash码  
3 boolean equals(Object obj) 判断此Object是否与指定的Object对象相等  
4 void copy(Object obj) 把此Object拷贝到指定的Object对象中  
5 Object clone() 克隆此Object对象  
6 String toString() 把此Object对象转换成String类的对象  
7 void notify() 唤醒一个等待的线程  
8 void notifyAll() 唤醒所有等待的线程  
9 void wait(int timeout) 使一个线程处于等待直到timeout结束或被唤醒  
10 void wait() 使一个线程处于等待直到被唤醒  
11 void enterMonitor() 对Object加锁  
12 void exitMonitor() 对Object开锁 

6.application对象  

application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。  
序号 方 法 说 明  
1 Object getAttribute(String name) 返回给定名的属性值  
2 Enumeration getAttributeNames() 返回所有可用属性名的枚举  
3 void setAttribute(String name,Object obj) 设定属性的属性值  
4 void removeAttribute(String name) 删除一属性及其属性值  
5 String getServerInfo() 返回JSP(SERVLET)引擎名及版本号  
6 String getRealPath(String path) 返回一虚拟路径的真实路径  
7 ServletContext getContext(String uripath) 返回指定WebApplication的application对象  
8 int getMajorVersion() 返回服务器支持的Servlet API的最大版本号 
9 int getMinorVersion() 返回服务器支持的Servlet API的最大版本号
10 String getMimeType(String file) 返回指定文件的MIME类型  
11 URL getResource(String path) 返回指定资源(文件及目录)的URL路径
12 InputStream getResourceAsStream(String path) 返回指定资源的输入流  
13 RequestDispatcher getRequestDispatcher(String uripath) 返回指定资源的RequestDispatcher对象
14 Servlet getServlet(String name) 返回指定名的Servlet  
15 Enumeration getServlets() 返回所有Servlet的枚举  
16 Enumeration getServletNames() 返回所有Servlet名的枚举  
17 void log(String msg) 把指定消息写入Servlet的日志文件  
18 void log(Exception exception,String msg) 把指定异常的栈轨迹及错误消息写入Servlet的日志文件  
19 void log(String msg,Throwable throwable) 把栈轨迹及给出的Throwable异常的说明信息 写入Servlet的日志文件  

7.exception对象 

exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象  
序号 方 法 说 明  
1 String getMessage() 返回描述异常的消息  
2 String toString() 返回关于异常的简短描述消息  
3 void printStackTrace() 显示异常及其栈轨迹  
4 Throwable FillInStackTrace() 重写异常的执行栈轨迹  

8.pageContext对象 

pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本类名也叫pageContext。  
序号 方 法 说 明  
1 JspWriter getOut() 返回当前客户端响应被使用的JspWriter流(out) 
2 HttpSession getSession() 返回当前页中的HttpSession对象(session)
3 Object getPage() 返回当前页的Object对象(page)  
4 ServletRequest getRequest() 返回当前页的ServletRequest对象(request)  
5 ServletResponse getResponse() 返回当前页的ServletResponse对象(response)  
6 Exception getException() 返回当前页的Exception对象(exception) 
7 ServletConfig getServletConfig() 返回当前页的ServletConfig对象(config)  
8 ServletContext getServletContext() 返回当前页的ServletContext对象(application)  
9 void setAttribute(String name,Object attribute) 设置属性及属性值  
10 void setAttribute(String name,Object obj,int scope) 在指定范围内设置属性及属性值  
11 public Object getAttribute(String name) 取属性的值  
12 Object getAttribute(String name,int scope) 在指定范围内取属性的值  
13 public Object findAttribute(String name) 寻找一属性,返回起属性值或NULL  
14 void removeAttribute(String name) 删除某属性  
15 void removeAttribute(String name,int scope) 在指定范围删除某属性  
16 int getAttributeScope(String name) 返回某属性的作用范围  
17 Enumeration getAttributeNamesInScope(int scope) 返回指定范围内可用的属性名枚举  
18 void release() 释放pageContext所占用的资源  
19 void forward(String relativeUrlPath) 使当前页面重导到另一页面
20 void include(String relativeUrlPath) 在当前位置包含另一文件

9.config对象 

    config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)  
    序号 方 法 说 明  
    1 ServletContext getServletContext() 返回含有服务器相关信息的ServletContext对象  
    2 String getInitParameter(String name) 返回初始化参数的值  
    3 Enumeration getInitParameterNames() 返回Servlet初始化所需所有参数的枚举

3.常用Java web框架

3.1 Hibernate

相关概念

1.ORM 对象-关系 映射
将程序中的对象 和数据库中的关系对应起来,使得对对象的操作 能和对数据库关系的操作关联起来,使得程序员能以面向对象的方式处理数据库操作

2.Hiberanate中对象的状态
持久态:持久实例是具有数据库标识的实例,即和数据库中的记录相对应。
特点:
a.位于Session缓存中,持久化状态的实例总是被一个Session实例关联
b.和数据库记录相对应
c.Session清理缓存时,会根据持久化状态的属性变化来更新数据库记录。

转化:
Session的save方法将临时状态变成持久化状态。
Session的load,get,find方法返回的对象就处于持久化状态。
Session的update,saveOrupdate,lock方法使游离状态对象变成持久化状态。
临时状态:使用New 操作符新生成的实例,没有和数据库表进行任何关联
特点:和Hiberante session等其他对象有任何关系
转化:
Session的delete方法能将一个持久化状态对象或游离态对象转变成临时状态。

**游离态:**Session关闭后,持久化状态对象变成游离状态。离线表示这个对象不能和数据库保持同步,不在受hiberante管理。
特点:
不在Session缓存中。
转化:

3.关系映射
分为如下四种:
多对一关系映射
一对一关系映射
一对多关系映射
多对多关系映射

4.Hiberante中重要的对象
SessionFactory:重量级对象,不要轻易创建。用它来创建Session对象,本身要用到ConnectionFactory。可以提供二级缓存。

Session:为应用程序和持久存储层之间交互操作的单线程对象,轻量级对象。可用它来获取transaction.拥有一级缓存,在执行Flush之前,将持久化操作的数据都在缓存session中。

TransactionFactory:事务工厂

Transaction:和数据库事务的概念是相同的。

ConnectionProvider:JDBC连接工厂,同时具有连接池的作用。

使用例子:

         Configuration cfg=new Configuration().configure();//加载hiberante.cfg.xml配置文件
                SessionFactory sf=cfg.buildSessionFactory();
                Session session=sf.openSession();

                Transaction tx=session.beginTransaction();

                Stu  stu=new Stu("stu1","stu1");

                session.save(stu);
                tx.commit();

hiberante.hbn.xml配置样例

<?xml version='1.0' encoding='gb2312'?> 


<!DOCTYPE hibernate-configuration PUBLIC 
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 
    <!--声明Hibernate配置文件的开始-->          

<hibernate-configuration>    
 <session-factory>    

          <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver </property> 


          <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect </property> 

          <property name="hibernate.connection.url">jdbc:mysql://localhost/school</property> 


          <property name="hibernate.connection.username">test </property> 

          <property name="hibernate.connection.password">test</property>        

          <property name="hibernate.connection.pool.size">20 </property>    


       <property name="hibernate.show_sql">true </property> 
       <property name="jdbc.fetch_size">50 </property> 
        <property name="jdbc.batch_size">23 </property> 
        <property name="jdbc.use_scrollable_resultset">false </property> 
       <property name="Connection.useUnicode">true </property> 

    <property name="connection.characterEncoding">utf-8 </property>      

/表和对象的配置,在子文件中       
          <mapping resource="User.hbn.xml"/> 
          <mapping resource="MyClass.hbn.xml"/> 

  </session-factory> 
  </hibernate-configuration>    

关系配置文件样例:

MyClass类成员:
private Integer id;
private String name;
private Set<Stu> myStu;


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-mapping  package="Pojo">

                <class name="MyClass"  table="class">

                                <id name="id">
                                   <generator class="native"/>

                                </id>

                                <property name="name" column="name"  length="10"/>
                            <set name="myStu" cascade="all">
                                 <key column="class_id" />
                                 <one-to-many class="Stu" />
                            </set>
                </class>

</hibernate-mapping>




Stu类成员:
public class Stu {
        private Integer id;
        private String name;
        private String password;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC 
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

 <hibernate-mapping  package="Pojo">

                <class name="Stu"  table="student">

                                <id name="id">
                                   <generator class="native"/>
                                </id>

                                <property name="name" column="name"  length="10"/>
                                <property name="password" column="password"  length="10"/>


                </class>

</hibernate-mapping>

分页操作

Hibernate通过对不同的数据库提供统一的接口设计,实现了通用化透明化的数据分页机制

使用Hibernate进行分页查询
逻辑分页(效率低不推荐)和物理分页(不用数据库不同mysql limit语句 oracle为rownum语句)

查询出第2页的所有用户数据示例,每页最大记录为10
int pageNo = 2;
int pageSize = 10;
String hql = "from User";
Query query = session.createQuery(hql);
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
query.list();


使用
Criteria criteria=session.createCriteria(User.class);
criteria.add(Expression.eq(“age”,20));
//从检索结果中获取从第100条开始到第120条结束的20条记录
criteria.setFirstResult(100);
criteria.setFetchSize(20);

Hibernate分页的实现原理

Hibernate List可以实现分页查询:
从第2万条开始取出100条记录
这里写图片描述
Hibernate2.0.3的Loader源代码第480行以下:
这里写图片描述

如果相应的数据库定义了限定查询记录的sql语句,那么直接使用特定数据库的sql语句。
然后来看net.sf.hibernate.dialect.MySQLDialect:

这里写图片描述

再来看net.sf.hibernate.dialect.Oracle9Dialect:

这里写图片描述
Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。

除此之外,Interbase,PostgreSQL,HSQL也支持分页的sql语句,在相应的Dialect里面,大家自行参考。

如果数据库不支持分页的SQL语句,如果在配置文件里面hibernate.jdbc.use_scrollable_resultset true
默认是true,如果你不指定为false,那么Hibernate会使用JDBC2.0的scrollable result来实现分页,看Loader第430行以下:
这里写图片描述

如果支持scrollable result,使用ResultSet的absolute方法直接移到查询起点,如果不支持的话,使用循环语句,rs.next一点点的移过去。

值得一提的是,Oracle的JDBC驱动的Scrollable ResultSet的实现方法实际上也是用循环语句rs.next一点点的移过去。

Hibernate中一级缓存和二级缓存使用

一、一级缓存二级缓存的概念解释
(1)一级缓存就是Session级别的缓存,一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中,如果短时间内这个session(一定要同一个session)又做了同一个操作,那么hibernate直接从一级缓存中拿,而不会再去连数据库,取数据;

(2)二级缓存就是SessionFactory级别的缓存,顾名思义,就是查询的时候会把查询结果缓存到二级缓存中,如果同一个sessionFactory创建的某个session执行了相同的操作,hibernate就会从二级缓存中拿结果,而不会再去连接数据库;

(3)Hibernate中提供了两级Cache,第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由hibernate管理的,一般情况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或群集范围的缓存。这一级别的缓存可以进行配置和更改,并且可以动态加载和卸载。 Hibernate还为查询结果提供了一个查询缓存,它依赖于第二级缓存;

二、一级缓存和二级缓存的比较

(1)第一级缓存、第二级缓存 缓存的范围事务范围
每个事务都有单独的第一级缓存进程范围或集群范围,缓存被同一个进程或集群范围内的所有事务共享并发访问策略。由于每个事务都拥有单独的第一级缓存,不会出现并发问题。无需提供并发访问策略由于多个事务会同时访问第二级缓存中相同数据,因此必须提供适当的并发访问策略,来保证特定的事务隔离级别数据过期策略没有提供数据过期策略。

(2)处于一级缓存中的对象永远不会过期,除非应用程序显式清空缓存或者
清除特定的对象必须提供数据过期策略,如基于内存的缓存中的对象的最大数目,允许对象处于缓存中的最长时间,以及允许对象处于缓存中的最长空闲时间物理存储介质内存内存和硬盘。

(3)对象的散装数据首先存放在基于内存的缓存中,当内存中对象的数目达到数据过期策略中指定上限时,就会把其余的对象写入基于硬盘的缓存中。

(4)缓存的软件实现在Hibernate的Session的实现中包含了缓存的实现由第三方提供,Hibernate仅提供了缓存适配器(CacheProvider)。用于把特定的缓存插件集成到Hibernate中。

(5)启用缓存的方式
只要应用程序通过Session接口来执行保存、更新、删除、加载和查询数据库数据的操作,Hibernate就会启用第一级缓存,把数据库中的数据以对象的形式拷贝到缓存中,对于批量更新和批量删除操作,如果不希望启用第一级缓存,可以绕过Hibernate API,直接通过JDBC API来执行指操作。

(6)用户可以在单个类或类的单个集合的粒度上配置第二级缓存。如果类的实例被经常读但很少被修改,就可以考虑使用第二级缓存。

(7)只有为某个类或集合配置了第二级缓存,Hibernate在运行时才会把它的实例加入到第二级缓存中。

用户管理缓存的方式第一级缓存的物理介质为内存,由于内存容量有限,必须通过恰当的检索策略和检索方式来限制加载对象的数目。

Session的 evit()方法可以显式清空缓存中特定对象,但这种方法不值得推荐。第二级缓存的物理介质可以是内存和硬盘,因此第二级缓存可以存放大量的数据,数据过期策略的maxElementsInMemory属性值可以控制内存中的对象数目。

(8)管理第二级缓存主要包括两个方面:选择需要使用第二级缓存的持久类,设置合适的并发访问策略:选择缓存适配器,设置合适的数据过期策略。

三、 一级缓存的管理

(1)当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的 list()、iterate()或filter()方法时,如果在Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,

Hibernate会根据缓存中对象的状态变化来同步更新数据库。 Session为应用程序提供了两个管理缓存的方法:
evict(Object obj):从缓存中清除参数指定的持久化对象。
clear():清空缓存中所有持久化对象。

(2)save、update、saveOrupdate、load、list、iterate、lock会向一级缓存存放数据;

(3)什么操作会从一级缓存取数据:get、load、list

get / load 会首先从一级缓存中取,如没有.再有不同的操作[get 会立即向数据库发请求,而load 会返回一个代理对象,直到用户真的去使用数据,才会向数据库发请求;
注意:

① 一级缓存不需要配置,就可以使用,它本身没有保护机制,所以我们程序员要考虑这个问题,我们可以同 evict 或者 clear来清除session缓存中对象. evict 是清除一个对象,clear是清除所有的sesion缓存对象

② session级缓存中对象的生命周期, 当session关闭后,就自动销毁.

③ 我们自己用HashMap来模拟一个Session缓存,加深对缓存的深入.

四、Hibernate二级缓存的管理

  1. Hibernate二级缓存策略的一般过程如下:
    1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。

2) 把获得的所有数据对象根据ID放入到第二级缓存中。

3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。

4) 删除、更新、增加数据的时候,同时更新缓存。

Hibernate二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query Cache。

5) 二级缓存的对象可能放在内存,也可能放在磁盘.

  1. 什么样的数据适合存放到第二级缓存中?

1) 很少被修改的数据
2) 不是很重要的数据,允许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。

  1. 不适合存放到第二级缓存的数据?

1) 经常被修改的数据
2) 财务数据,绝对不允许出现并发
3) 与其他应用共享的数据。

3.2 Spring

Spring:也可以在java se项目中使用

重要概念

1.AOP
实现方式:基于java反射机制和JAVA动态代理

2.IoC
实现方式:基于java反射机制。在配置bean时,可以使用setter方式注入(先调用用无参的构造方法生成对象,然后使用反射机制为配置了的熟悉调用setter方法赋值)、构造器方式(使用与参数对应的构造函数构造对象并初始化)注入。

构造器方式:  
<bean id="myclass" class="Pojo.MyClass">
       <constructor-arg index="0" >  <value>345</value>  </constructor-arg> 
       <constructor-arg index="1">   <value>java</value>  </constructor-arg>     
</bean>  


setter方式:
    <bean id="myclass" class="Pojo.MyClass">
         <property name="id" > <value>345</value> </property>
         <property name="name" value="class" />
         <property name="stu" ref="stu"/>
    </bean>

3.Spring bean循环依赖

见例:
     public class MyClass {

                private Integer id;
                private String name;
                private Stu myStu;
               .....
        }

        public class Stu {
                private Integer id;
                private String name;
                private String password;
                private MyClass  myClass;
        }

        当配置上述两个java bean对象时,就是构成了bean的循环依赖

解决办法:
a.重新设计,使得bean之前不具有循环依赖关系
b.如果必须有这种循环依赖的话,那就使用setter方式注入,这种方式可解决大部分循环依赖bean的注入。(使用构造器方式注入的话,spring会抛出错误:循环依赖错误)

4.如果在web中使用Spring,为了让web启动的时候就初始化spring容器,则需要配置web.xml文件
加上标签:

<listener>
<listener-class>
org.spring.framework.web.context.ContextLoaderListener
</listener-class>
</listener>

5.Aop中的相关概念

JoinPoint连接点:程序执行过程中某个特定的点,总是表示一个方法的执行(加入切点的地方)
切入点:用来匹配、定位连接点的。Spring使用AspectJ来定位(将增强和连接点关联)
weaving织入:将切面应用到目标对象中,来创建新的代理对象的过程(Spring在运行时织入)
Advice增强:是织入到目标连接点上的程序代码
introduction引介:特殊的增强,为类添加属性和方法的。

6.简单例子
需要在 applicationContext.xml文件中配置id为myclass,stu的bean.


 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

       MyClass myclass = (MyClass)ctx.getBean("myclass");   
       myclass.printMyclass();

        Stu s = (Stu)ctx.getBean("stu");
        s.printStu();

bean的生命周期

在spring中,singleton属性默认是true,只有设定为false,则每次指定别名取得的Bean时都会产生一个新的实例

一个Bean从创建到销毁,如果是用BeanFactory来生成,管理Bean的话,会经历几个执行阶段(如图1.1):

这里写图片描述
1:Bean的建立:
容器寻找Bean的定义信息并将其实例化。

2:属性注入:
使用依赖注入,Spring按照Bean定义信息配置Bean所有属性

3:BeanNameAware的setBeanName():
如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。

4:BeanFactoryAware的setBeanFactory():
如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

5:BeanPostProcessors的ProcessBeforeInitialization()
如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。

6:initializingBean的afterPropertiesSet():
如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法

7:Bean定义文件中定义init-method:
可以在Bean定义文件中使用”init-method”属性设定方法名称例如:
如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法

8:BeanPostProcessors的ProcessaAfterInitialization()
如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法

此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉(如图1.2):

这里写图片描述
1:DisposableBean的destroy()
在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法

2:Bean定义文件中定义destroy-method
在容器关闭时,可以在Bean定义文件中使用”destroy-method”属性设定方法名称,例如:

如果有以上设定的话,则进行至这个阶段时,就会执行destroy()方法,如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。

bean的scope

如何使用spring的作用域:

这里的scope就是用来配置spring bean的作用域,它标识bean的作用域。

在spring2.0之前bean只有2种作用域即:singleton(单例)、non-singleton(也称 prototype), Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean。
因此,默认情况下Spring2.0现在有五种类型的Bean。当然,Spring2.0对 Bean的类型的设计进行了重构,并设计出灵活的Bean类型支持,理论上可以有无数多种类型的Bean,用户可以根据自己的需要,增加新的Bean类 型,满足实际应用需求。
1、singleton作用域(scope 默认值)
当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把 一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都 将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中 只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时 候,spring的IOC容器中只会存在一个该bean。
配置实例:

<bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 
或者
<bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/>

2、prototype
prototype作用域部署的bean,每一次请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。 清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。(让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用 bean的后置处理器,该处理器持有要被清除的bean的引用。)
配置实例:

<bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/>
或者
<beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/>

3、request
request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,配置实例:
request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:
如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可:


 <web-app>
    ...
   <listener>
 <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
   </listener>
    ...
 </web-app>

,如果是Servlet2.4以前的web容器,那么你要使用一个javax.servlet.Filter的实现:

<web-app>
  ..
  <filter> 
     <filter-name>requestContextFilter</filter-name> 
     <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
  </filter> 
  <filter-mapping> 
     <filter-name>requestContextFilter</filter-name> 
     <url-pattern>/*</url-pattern>
  </filter-mapping>
    ...
 </web-app>

接着既可以配置bean的作用域了:

4、session
session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效,配置实例:
配置实例:
和request配置实例的前提一样,配置好web启动文件就可以如下配置:

<bean id="role" class="spring.chapter2.maryGame.Role" scope="session"/>

5、global session
global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用。
配置实例:
和request配置实例的前提一样,配置好web启动文件就可以如下配置:

<bean id="role" class="spring.chapter2.maryGame.Role" scope="global session"/>

6、自定义bean装配作用域
在spring2.0中作用域是可以任意扩展的,你可以自定义作用域,甚至你也可以重新定义已有的作用域(但是你不能覆盖singleton和 prototype),spring的作用域由接口org.springframework.beans.factory.config.Scope来定 义,自定义自己的作用域只要实现该接口即可,下面给个实例:
我们建立一个线程的scope,该scope在表示一个线程中有效,代码如下:

publicclass MyScope implements Scope { 
       privatefinal ThreadLocal threadScope = new ThreadLocal() {
           protected Object initialValue() {
              returnnew HashMap(); 
            } 
      }; 
      public Object get(String name, ObjectFactory objectFactory) { 
          Map scope = (Map) threadScope.get(); 
          Object object = scope.get(name); 
         if(object==null) { 
            object = objectFactory.getObject(); 
            scope.put(name, object); 
          } 
         return object; 
       } 
      public Object remove(String name) { 
          Map scope = (Map) threadScope.get(); 
         return scope.remove(name); 
       }
       publicvoid registerDestructionCallback(String name, Runnable callback) { 
       }
     public String getConversationId() {
        // TODO Auto-generated method stub
         returnnull;
      } 
 }

applicationContext.xml配置样例

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 


    <bean id="stu" class="Pojo.Stu">
         <property name="id" > <value>345</value> </property>
         <property name="name" value="stu" />

         <property name="myClass" ref="myclass"/>
    </bean>


    <bean id="myclass" class="Pojo.MyClass">
         <property name="id" > <value>345</value> </property>
         <property name="name" value="class" />
         <property name="stu" ref="stu"/>
    </bean>




  <!--
      <bean id="stu" class="Pojo.Stu">
       <constructor-arg index="0" >  <value>345</value>  </constructor-arg> 
       <constructor-arg index="1">   <value>stuname</value>  </constructor-arg> 
       <constructor-arg index="2">   <value>password</value>  </constructor-arg> 
        <constructor-arg index="3"  ref="myclass">  </constructor-arg> 
      </bean>


    <bean id="myclass" class="Pojo.MyClass">
         <constructor-arg index="0" >  <value>345</value>  </constructor-arg> 
       <constructor-arg index="1">   <value>java</value>  </constructor-arg> 

    </bean>  

      -->





    <bean id="audience" class="Audience"/>

    <bean id="sax" class="Saxophone"/>
    <bean id="kenny" class="Instrumentalist">
         <property name="song" value="Jingle Bells" />
         <property name="age" value="25" />
         <property name="instrument" ref="sax"/>
    </bean>


    <aop:config proxy-target-class="true">
        <aop:aspect ref="audience">
            <aop:pointcut id="performance" expression="execution(* Performer.perform(..))"/>

            <aop:before pointcut-ref="performance" method="takeSeats"/>
            <aop:before pointcut-ref="performance" method="turnOffCellPhones"/>
            <aop:after-returning pointcut-ref="performance" method="applaud"/>
            <aop:after-throwing pointcut-ref="performance" method="demandRefund"/>
        </aop:aspect>
    </aop:config>

</beans>

XML配置文件说明

Spring的xml一般起名叫做bean.xml或者xxxapplication.xml这种,然后放在src下通过ClassPathXmlApplicationContext进行加载。文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:aop="http://www.springframework.org/schema/aop"
         xmlns:tx="http://www.springframework.org/schema/tx"
         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 

    <bean id="audience"class="com.spring.test.aop.Audience"/>

    <aop:config>
    </aop:config>
</beans>




下面的<beans>是Spring的配置标签,beans里面几个重要的属性:
  xmlns:
  是默认的xml文档解析格式,即spring的beans。地址是http://www.springframework.org/schema/beans。
  通过设置这个属性,所有在beans里面声明的属性,可以直接通过<>来使用,比如<bean>等等。
  xmlns:xsi:
  是xml需要遵守的规范,通过URL可以看到,是w3的统一规范,后面通过xsi:schemaLocation来定位所有的解析文件。

  xmlns:aop:
  这个是重点,是我们这里需要使用到的一些语义规范,与面向切面AOP相关。

  xmlns:tx:
  Spring中与事务相关的配置内容。

  

  一个XML文件,只能声明一个默认的语义解析的规范。
  例如上面的xml中就只有beans一个是默认的,其他的都需要通过特定的标签来使用,比如aop,它自己有很多的属性,如果要使用,前面就必须加上aop:xxx才可以。比如上面的aop:config。

  类似的,如果默认的xmlns配置的是aop相关的语义解析规范,那么在xml中就可以直接写config这种标签了。

AOP的 执行匹配表达式

注意星号后面要有个空格

切入点表达式的使用规则:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

有“?”号的部分表示可省略的
modifers-pattern表示修饰符如public、protected等
ret-type-pattern表示方法返回类型
declaring-type-pattern代表特定的类
name-pattern代表方法名称
param-pattern表示参数
throws-pattern表示抛出的异常。
在切入点表达式中,可以使用*来代表任意字符,用..来表示任意个参数。

<aop:config proxy-target-class="false">
         <aop:aspect ref="corletPointCutTest">
             <aop:pointcut id="allRenderProcess"
                 expression="execution(* com.hsbc.esf.requestprocessing.portlet.impl.PortletFrontController.doRenderService(..)) || execution(* com.hsbc.esf.requestprocessing.portlet.impl.PortletFrontController.processRenderRequest(..))||execution(* com.hsbc.esf.requestprocessing.portlet.impl.PortletFrontController.doActionService(..))" />
          <aop:before  method="checkPorletPoint" pointcut-ref="allRenderProcess"/>
         </aop:aspect>
     </aop:config>   

3.2 Struts2

开发流程

注意:依赖包到导入到web-inf目录下的lib中
1.导入Struts2 依赖Jar包
2.在web.xml中配置,过滤需要用struts2处理的请求

  <filter>
        <filter-name>struts-prepare</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

       <filter-mapping>
        <filter-name>struts-prepare</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

3.编写Action处理请求(相应的Action可以是普通类,但是继承ActionSupport可以省去很多功夫)

  public class UserAction extends ActionSupport {
在Structs中获取相应的response,request等对象的方法:
           HttpServletRequest request = ServletActionContext.getRequest();

            HttpServletResponse response = ServletActionContext.getResponse();

            ServletContext servletContext = ServletActionContext.getServletContext();

            request.getSession();

4.编写struts.xml配置文件,配置请求对应的方法和 不同返回值对应的处理,如果需要重定向、或是转到另一个action,就配置forward,redirect等标签就可

 <package name="test.structs.common" extends="struts-default">
        <action name="login" class="test.structs.common.UserAction" method="login">
            <result name="success">/WEB-INF/jsp/user/main.jsp</result>
            <result name="input">index.jsp</result>
        </action>
    </package> 

高级功能

Struts2中的拦截器

其他

关于请求中的属性和参数

在JAVA WEB开发中经常遇到获取请求参数的值和在request对象中set或者get属性,初学者往往容易混淆,那么二者之间关系到底如何呢?下面是个人的总结:

区别:
•来源不同:
参数(parameter)是从客户端(浏览器)中由用户提供的,若是GET方法是从URL中
提供的,若是POST方法是从请求体(request body)中提供的;
属性(attribute)是服务器端的组件(JSP或者Servlet)利用requst.setAttribute()设置的 •操作不同:
参数(parameter)的值只能读取不能修改,读取可以使用request.getParameter()读取;
属性(attribute)的值既可以读取亦可以修改,读取可以使用request.setAttribute(),设置可使用request.getAttribute() •数据类型不同:
参数(parameter)不管前台传来的值语义是什么,在服务器获取时都以String类型看待,并且客户端的参数值只能是简单类型的值,不能是复杂类型,比如一个对象。
属性(attribute)的值可以是任意一个Object类型。

共同点
二者的值都被封装在request对象中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值