maxActive="100" maxIdle="30" maxWait="10000"username="root" password="admin"url="jdbc:mysql://localhost:3306/databaseWeb?characterEncoding=utf-8"/>
Web程序的web.xml中配置数据源 引用:
< web-app ……>
< resource-ref >
< description > DB Connection description >
< res-ref-name > jdbc /databaseWeb res-ref-name >
< res-type > javax.sql.DataSource res-type >
< res-auth > Container res-auth >
resource-ref >
web-app >
使用方法方式一:
< sql:query var = "rs" dataSource = "jdbc/databaseWeb" >
select id, name, sex from tb_employee
sql:query >
< c:forEach var = "row" items = " ${rs.rows} " >
${ row['id'] }, ${ row['name'] }, ${ row['sex'] } < br />
c:forEach >
使用方法二:
<% ContextinitContext = new InitialContext();
Context envContext = (Context)initContext.lookup( "java:/comp/env" );
DataSource ds = (DataSource)envContext.lookup( "jdbc/databaseWeb" );
Connection conn = ds.getConnection(); ……
conn.close(); %>
第13章 XML概述
122. XML(Extensible Markup Language)两种写法:
123. XML定义:DTD/Schema(更规范,更流行)
数据解析:DOM(DocumentObject Model)/SAX(Simple API for XML)
样式风格XSLT(eXtensibleStylesheet LanguageTransformation):将XML按照指定样式转换为HTML
124. XML语法:声明:、XML文档有且只能有一个根元素、大小写敏感、文档中的空白不会被解析器删除、注释、转义字符(<à<、>à>等)、CDATA部件 包含的字符不用转义这里字符if(a>b){alert(a);}不用转义]]>
125. DOM解析XML (将XML内容加载到内存,生成对应的对象模型),xml 文件比较大时,该方法占用内存大,查找速度慢 。
FilexmlFile = new File("F:\\article.xml" );
DocumentBuilderFactorybuilderFactory = DocumentBuilderFactory
.newInstance ();// 通过单例模式创建 DocumentBuilderFactory 对象
DocumentBuilder builder = builderFactory .newDocumentBuilder();
Document document = builder .parse(xmlFile ); // 解析文件
Elementroot = document .getDocumentElement();// 获得根元素
root .getNodeName();//节点名称
NodeListnodes = root .getChildNodes();/子节点
nodes[0] .getAttributes().getNamedItem("category" ) .getNodeValue();//获取属性
nodes[0] .getTextContent());//获取节点文本
126. SAX解析XML(优先选用 ) :根据定义好的事件处理器 ,决定当前解析的部分,是否有必要记录并存储:
File xmlFile = new File("F:\\article.xml" );
SAXParserFactory factory =SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse(xmlFile, new MySaxHandler()); // 定义解析时的事件处理
MySaxHandler继承自org.xml.sax.helpers.DefaultHandler;
127. JAXB (Java Architecturefor XML Binding):XML与Java对象互转:
JavaBean中用@XmlRootElement(name = "articles")标注XML根元素
File xmlFile = new File("F:\\test.xml" );
JAXBContextcontext ; // 声明 JAXBContext 上下文对象
// 通过指定映射的类创建上下文
context = JAXBContext.newInstance (Article.class );
Marshallerm = context .createMarshaller(); // 创建 java 转化 xml 的对象 Marshaller
Articlearticle = new Article();
article .setAuthor("Janet" ); article .setTitle("XML" );
m .marshal(article ,xmlFile ); // 将 java 对象转化到 xml
XML转Java:
Unmarshalleru = context .createUnmarshaller();// 通过上下文创建 xml 转化 java 的对象 Unmarshaller
Articlearticle2 = (Article)u .unmarshal(xmlFile );
System.out .println(article2 .getAuthor());
System.out .println(article2 .getTitle());
第14章 Struts1.x概述
128. 传统Web应用中,Servlet,Jsp中既有数据库代码,又包括HTML、css等页面代码,还包括复杂的业务逻辑,代码耦合率高,层次混乱,维护开发成本高。
★★★ 而Struts提供MVC架构 ,把传统WEB开发分成Model、View、Control三层,Model层负责业务逻辑(数据存储与处理),View层专注于数据在浏览器的显示(Html、css、jsp),Control层连接Model层与View层,从Model层获取数据传到View层。
129. Struts 1.x是原来的Struts,Struts 2.x前身为WebWork框架。
130. Struts完成了诸如类型转化、自动赋值、错误检查、数据验证、标签库、文件上传 等一系列工作。
131. Struts配置:(1)Web.xml配置
< servlet >
< servlet-name > action servlet-name >
< servlet-class > org.apache.struts.action.ActionServlet
servlet-class >
< init-param >
< param-name > config param-name >
< param-value > /WEB-INF/struts-config.xml param-value >
init-param >
< init-param >
< param-name > config/namespace1 param-name > < param-value > /WEB-INF/struts-config-namespace1 .xml param-value > 例如 person.do 会调用 struts-config.xml 里配置的 Action ,而请求 namespace1/person.do 会调用 struts-config-namespace1.xml 里的 Action -->
init-param >
< init-param >
< param-name > debug param-name >
< param-value > 3 param-value >
init-param >
< init-param >
< param-name > detail param-name >
< param-value > 3 param-value >
init-param >
< load-on-startup > 0 load-on-startup >
servlet >
< servlet-mapping >
< servlet-name > action servlet-name >
< url-pattern > *.do url-pattern >
servlet-mapping >
(2)Struts配置文件/WEB-INF/struts-config.xml :
< struts-config >
< data-sources />
< form-beans >
< form-bean name = "helloForm" type = "com.czf.struts.form.HelloForm" />
form-beans >
< global-exceptions /> < global-forwards />
< action-mappings >
< action attribute = "helloForm" input = "/form/hello.jsp" name = "helloForm" path = "/hello" scope = "request" type = "com.czf.struts.action.HelloAction" >
< set-propertyproperty = "cancellable" value = "true" />
< forwardname = "success" path = "/form/helloSuccess.jsp" />
< forwardname = "fail" path = "/form/helloFail.jsp" redirect = "true" />
action>
action-mappings >
< message-resources parameter = "com.czf.struts. ApplicationResources " />
struts-config >
HelloAction 实现:
public class HelloAction extends Action {
public ActionForwardexecute(ActionMapping mapping , ActionForm form , HttpServletRequest request , HttpServletResponse response ) {
HelloForm helloForm = (HelloForm) form ;
if ( helloForm .getName() == null ||
helloForm .getName().trim().length() == 0) {
return mapping .getInputForward();
}
return mapping .findForward( "success" );
}
}
132. Struts工作流程
Ø 访问hello.jsp页面à
Ø 提交表单到/hello.doà
Ø Struts截获*.do请求à
Ø 查找struts-config.xml找到hello.do对应的HelloForm和HelloActionà
Ø 将表单封装为HelloForm,并反射调用HelloAction的execute()à
Ø Forward到/form/helloSuccess.jsp
133. Struts1.x的Action 是线程不 安全 的(Struts2.x中Action为线程安全 ,每个请求都会产生一个Action实例):Action生命周期与Servlet类似,Servlet由Tomcat容器产生并维护,而Action由Struts的ActionServlet产生并维护。每个Action都只有一个实例 ,在加载Struts时产生,在卸载Struts时销毁。
Ø Action与Servlet一样,都不是线程安全的
Ø 因此,应避免写 Action属性,最好把Action属性都置位final
第15章 Struts1.x高级应用
134. html标签库 :主要用于生成html。property指定生成输入框、按钮等的name属性,property只能 指定Form Bean中已经存在的属性。可以通过Action中指定Form Bean的属性值来操作Jsp页面的显示。
< html:form action = "/tag" enctype = "multipart/form-data" >
文件域: < html:file property = "file" > html:file> < br />
输入框: < html:text property = "text" > html:text>
提交按钮: < html:submitvalue = "提交按钮" /> < br/>
重置按钮: < html:cancelvalue = "重置按钮" /> < br/>
…… html:form>
135. bean 标签库 :主要用于操作POJO、Cookie、Header以及Struts对象等。P428
< bean:write name = "person" />< br/>
< bean:writename = "person" property = "createDate.time" />
< bean:cookieid = "sessionId" name = "JSESSIONID" />
< bean:writename = "sessionId" property = "value" /> ……
136. logic标签库 :
< logic:present cookie = "JSESSIONID" >
< bean:cookie id = "sessionId2" name = "JSESSIONID" />
< bean:write name = "sessionId2" property = "value" />
logic:present >
< logic:notPresent cookie = "JSESSIONID" >
Cookie“JSESSIOND” 不存在。
logic:notPresent >
< logic:equal value = "643BC94" cookie = "JSESSIONID" > logic:equal > ……
137. nested标签库:低版本Struts中用于定义深层次属性,高版本中html标签可实现该功能。
帐号 : < nested:text property = "person.account" > nested:text >
138. tiles标签库 :处理网页布局。
模板页中使用< tiles:getAsString name = "title" /> 定义字符串变量或者< tiles:insert attribute = "copyright" > tiles:insert > 定义文件/Jsp变量。
使用模板页时,< tiles:insert page = "/template.jsp" flush = "true" >
< tiles:put name = "title" value = " 读书频道 - 红楼梦 " > tiles:put > 【填入字符串】
< tiles:put name = "copyright" value = "/WEB-INF/classes/copyright.txt" > tiles:put > 【填入文件内容】
tiles:insert >
Tiles可与Struts结合使用P436.
139. 分发器DispatchAction :在实际应用中,一个Action中会有许多不同的操作,每个操作被封装成独立的方法,这些操作会以一个字段action或者method来区分:
// 根据 PersonForm 的 action 字段决定执行哪种操作
if ( "add" .equals( personForm .getAction())) {
return add( mapping , form , request , response );
} else if ( "list" .equals( personForm .getAction())) {
return list( mapping , form , request , response );
}
Ø 如果一个Action继承自org.apache.struts.actions.DispatchAction则自动具有分发功能
Ø 在execute方法调用return super .execute( mapping , form , request , response ); // 一定要执行这句代码 , 父类会利用反射调用相关方法
Ø 在 Struts 配置文件中配置该 Action 时,用 parameter 参数指定分发器使用的参数(一般使用 action 或者 method )
140. 在网站根目录下自动创建upload文件夹:
File classes = new File(getClass().getClassLoader() .getResource( "" )
.getFile() ); // 文件夹 /WEB-INF/classes
File uploadFolder = new File( classes .getParentFile().getParentFile(), "upload" ); // 文件夹 /upload
uploadFolder = new File(URLDecoder.decode ( uploadFolder .getAbsolutePath
(), "utf-8" ));// 解决中文路径空格变成 %20 的错误
uploadFolder .mkdirs();
141. Struts文件上传 :不需要解析request,直接保存FormFile中的文件数据
Ø ActionForm中用FormFile类型(private FormFile file ; )对应前端的
上传文件:< html:file property = "file" > html:file >
Ø execute方法中部分代码如下:
UploadForm uploadForm = (UploadForm) form ;
if ( uploadForm .getFile() != null && uploadForm .getFile().getFileSize() > 0) {
InputStream ins = uploadForm .getFile().getInputStream();
……读取ins,保存到File中
}
142. Struts数据校验(1) :ActionForm中的validate 方法进行后台 验证:
public ActionErrors validate(ActionMapping mapping , HttpServletRequest request ){
ActionErrors errors = new ActionErrors();
if ( name == null || name .trim().length() == 0)
errors .add( "name" , new ActionMessage( "hello.error.name" ));
return errors ;
} // 前端用< html:errors property = "name" /> 显示错误信息
143. Struts数据校验(2) :使用Validator自动校验数据,该校验为前后台 都校验。
Ø FormBean继承Struts的ValidatorForm ,且不能覆盖validate()方法à
Ø 在validation.xml中配置校验规则à
Ø 在ApplicationResources.properities中配置错误消息(国际化)à
Ø 在struts-config.xml中配置plug-in节点à
Ø 在Jsp页面使用标签使Struts在该处生成相应JavaScript校验代码à
Ø 在 标签中定义属性onsubmit = "returnvalidatemyFormName (this);" 使提交页面时使用js校验数据。P442
144. 动态属性FormBean :除了继承ActionForm实现Form Bean,Struts还提供了一种配置式的动态Form Bean:DynaActionForm 。这种Form Bean不需要实现具体的类,它的变量是配置在struts-config.xml中的:
< struts-config>
< form-beans>
< form-beanname = "dynaTestForm" type = "org.apache.struts.action.DynaActionForm" >
< form-property name = "birthday" type = "java.sql.Date" initial = "" />
< form-property name = "age" type = "java.lang.Integer" initial = "18" />
< form-property name = "name" type = "java.lang.String" initial = "" />
form-bean>
form-beans>
struts-config>
Action中获取属性 : DynaActionForm dynaTestForm = (DynaActionForm) form ;
String name = (String) dynaTestForm .get("name" );
145. 异常处理 :
Ø 继承org.apache.struts.action.ExceptionHandler类,覆盖execute方法:
if ( exception instanceof AccountException) {
return mapping .findForward( "login" );
}
return super .execute( exception , config , mapping , form , request , response );
Ø 配置struts-config.xml: key属性为对应资源文件中的键
<global-exceptions >
<exception key = "login.error" type = "javax.security.auth.login. AccountException " handler = "com.helloweenvsfei.struts.exceptionhandler.AccountExceptionHandler" />
global-exceptions >
<global-forwards >
<forward name = "login" path = "/login.jsp" >forward >
global-forwards >
146. struts-config.xml中使用通配符:P448
Ø *代表任何不包括‘/’的任意长度(包括0)任意字符
Ø **代表任何包括‘/’ 的任意长度(包括0)任意字符
Ø \为转义字符,\* 代表 *, \\ 代表 \
第16章 Struts2.x概述
147. Struts2.x起源于WebWork,与struts1.x完全不同:
Ø Struts2 代码和配置文件简洁 ,隐藏了细节
Ø Struts2的Action线程安全 (每个Action都会有多个实例,处理一次请求生成一个实例,各实例彼此独立,用完销毁),而Struts1非线程安全(每个Action只有一个实例,反复使用)
148. Struts2 示例 :
Ø 新建java Web项目,将Struts2类库复制到\WEB-INF\lib下
Ø 新建LoginAction ,继承自com.opensymphony.xwork2.ActionSupport
public class LoginAction extends ActionSupport {
private String account ; private String password ;//Getter、Setter略
@Override
public String execute() {
if ("hello" .equalsIgnoreCase(account ) && "1234" .equalsIgnoreCase(password )) { return SUCCESS ; }// SUCCESS 在父类中定义为“success ”
return LOGIN ;//在父类中定义为“login ”字符串常量
}}//返回值代表页面名称
Ø Struts配置文件struts.xml 位于src目录下:
< struts>
< package name = "main" extends = "struts-default" >
< global-results>
< result name = "login" > /login.jsp result>
global-results>
< action name = "loginPerson" class = "com.czf.strut2.action. LoginAction " >
< result name = "success" > /welcome.jsp result>
action>
package>
struts>
Ø 编写Jsp :
<%@ page language = "java" import = "java.util.*" pageEncoding = "UTF-8" %>
<%@ taglib uri = "/struts-tags" prefix = "struts" %>
DOCTYPE HTML PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN">
< html >
< head >
< title > My JSP 'success.jsp' starting page title >
< struts:head theme = "xhtml" />
head >
< body >
< struts:form action = "loginPersion" >
< 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 >
body >
html >
Ø 配置web.xml :Struts1使用ActionServlet作为分发器,而Struts2使用Filter作为分发器。如果有多个Filter,Struts的Filter必须放至最后。
< filter >
< filter-name > struts2 filter-name > < filter-class > org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter filter-class >
filter >
< filter-mapping >
< filter-name > struts2 filter-name >
< url-pattern > /* url-pattern >
filter-mapping >
149. Struts2工作流程 :
150. Struts2配置文件:(struts.properties 在src目录下)
struts.custom.i18n.resources = com.helloweenvsfei.struts2.resources. Resources
struts.multipart.saveDir = /temp
struts.multipart.maxSize= 10000000
……
151. Action中获取网站根目录:
// 获取 web 应用根目录下 /upload 文件夹
ServletContext context =ServletActionContext.getServletContext ();
File uploadFile = new File( context .getRealPath( "upload" ));
152. Struts2的Action实现:
Ø 继承 ActionSupport 类(优点:可以使用Struts2的数据验证、错误显示等功能)
Ø 实现Action接口
Ø 不继承不实现:(具有public String execute() {} 方法即可 )
153. Action的可执行方法 :execute是默认的可执行方法。其他方法只要返回String类型,没有参数,可以有throws声明,都可以成为可执行方法。执行方式如下:
Ø URL执行:actionName! methodName.action .
Ø 将method配置为Action执行:(struts.xml中配置如下)
< action name = "logout" class = "com.helloweenvsfei.struts2.action. LoginAction" method = "logout" >
< result name = "success" > /welcome.jsp result >
action >
< action name = "*Person" class = "com.helloweenvsfei.struts2.action. LoginAction" method = "{1}" >
< result name = "success" > /welcome.jsp result >
action >
Ø 在标签中可指定调用的方法:
" 执行 fieldError()" method="fieldError" />
154. Struts2的零配置(使用注解@Annotation ):
@Namespace(value = "/test" )
@Results( {
@Result(name = "success" , value = "/namespace1/success.jsp" ),
@Result(name = "redirect" , value = "/namespace1/redirect.jsp" , type = ServletRedirectResult. class ) })
public class AnnotatedAction extends ActionSupport { ……}
需要在web.xml中指定使用被@注解的Action的package:
< filter >
< filter-name > strutsfilter-name >
< filter-class > org.apache.struts2.dispatcher.FilterDispatcher filter-class >
actionPackages
com.helloweenvsfei.struts2.action
filter >
使用注解配置的Action只能用URL方式(actionName! methodName.action )访问
第17章 Struts2.x高级应用
155. 数据类型转换器 :P469
Ø 实现ognl.TypeConverter,一般直接继承DefaultType Converter类,并实现convertValue()方法。
public Object convertValue(Map context , Object value , Class toType ) {}
value 参数为request.getParameterValues(Stringname)返回的String[],
toType 为要转成的类型。
Ø 配置转换器(全局):在src/xwork-conversion.properties 文件中配置,key为需要转换的类型,value为转换器的类名:
java.sql.Date = com.struts2.convertor.DateTimeConvertor
java.sql.Time = com.struts2.convertor.DateTimeConvertor
java.util.Date= com.struts2.convertor.DateTimeConvertor
Ø 为Action配置转换器:在struts.xml定相应action节点定义converter属性即可
156. Struts2中获取request、response
Ø 利用ServletActionContext的静态方法(非注入方式/非IoC方式): ServletActionContext利用ThreadLocal 对象存储request等相关数据,保证各线程数据不混淆。
HttpServletRequest request = ServletActionContext.getRequest ();
HttpServletResponse response = ServletActionContext.getResponse ();
Ø 利用相关的Aware接口:(注入方式):P474. Struts在实例化一个Action对象时,如果发现它实现了相应的Aware接口,会吧相应的资源通过Aware的相应set方法注射进去。Application、request、response、session对应的Aware接口分别为:ServletRequestAware,ServletResponseAware, SessionAware, ServletContextAware
157. Xml中CDATA 部分由 " " 开始,由 "]]> " 结束:表示中间的为纯文本数据,无需进行xml解析
158. 使用Validator校验数据 :
★★★被校验的Action要继承ActionSupport类,并且要在action配置中指定名input的jsp,因为校验失败后会自动返回input页面。
Ø 使用xml配置数据校验Validator: 在Action类所在的package内添加一个XML文件,名为Action类名-validation.xml或者 Action类名-Action别名-validation.xml。如果Action中有多个方法,应使用后者,Action别名为struts.xml中为该方法配置的Action名。
< validators >
< field name = "book.name" >
< field-validator type = "requiredstring" >
< param name = "trim" > true param >
< message > 请输入书籍名称 message >
field-validator >
field >
validators >
Ø 使用@注解配置Validator:
@Validation ()注解Action类,表示该Action需要数据校验
@validations()配置在方法上,可指定多条规则
@SkipValidation()作用在方法上,跳过校验
例如:
@Validations (requiredStrings = {
@RequiredStringValidator (type = ValidatorType. SIMPLE , trim = true , fieldName = "book.name" , message = " 请输入书籍名称 . *" ) })
public String add() {}
★ 将Jsp中的标签添加validate=”true”属性即可实现客户端js校验。不像struts1那样弹出提示框,直接在文本域上方提示错误,无需另外修改jsp.
第18章 Struts2.x 标签
159. OGNL ,Struts2标签库主要使用OGNL( Object-GraphNavigation Language)语言 ,它是一种操作对象属性的开源表达式语言,该语言比EL更强大。OGNL特点:
Ø 能够访问对象方法,如list.size()
Ø 能够访问静态属性和方法(在类名和方法名上加@)。如@java.lang.Math@PI 、@java.lang.String@format(‘foo %s’,’bar’);
Ø 支持赋值和表达式串联,如#value=5
Ø OGNL3个符号:#、%、$; #符号最常用 ,用途如下:
Ø %符号 显示声明OGNL表达式:用于表示某字符串为一个OGNL表达式。某些标签中既能够接受字符串,又能够接受OGNL表达式,这时候标有%的被当做OGNL表达式执行,没有%的被当做普通字符串。
第一行将输出字符串#request.account,而第二行将输出request对象的account属性
Ø $符号 :在资源国际化文件或者struts.xml中使用OGNL表达式。
160. Struts2标签分为控制标签、数据标签、表单UI标签,非UI标签 四大类
161. 控制标签:
Ø if、elseif、else
< struts:if test = "#parameters.name[0]== 'Kurt'" >
Hello, Kurt.
struts:if >
< struts:elseif test = "#parameters.name[0]== 'Matt'" >
Hello, Matt.
struts:elseif >
< struts:else >
Hello, Other Buddies.
struts:else >
Ø append/merge 标签P485:append 用于将多个List合并成一个List,相当于Java中的list.addAll(list2)。mearge类似与append,不同的是apend先添加maleList所有元素,再添加femaleList 所有元素,而merge先添加maleList第一个元素,再添加femaleList第一个元素,再添加maleList 第二个元素……
< s:append id = "myAppendList" >
< s:param value = "%{maleList}" />
< s:param value = "%{femaleList}" />
s:append >
< s:iterator value = "%{#myAppendList}" >
< s:property /> < br />
s:iterator >
Ø generator 标签: 将字符串解析为List,相当于Java中的split
< s:generator val = "%{'李宁, 安踏, 双星, 阿达, 耐克'}" separator = "," >
< s:iterator >
< s:property /> < br />
s:iterator >
s:generator >
Ø iterator 标签:遍历集合:
< struts:iterator value = "magazineList.{?#this.price>18}">
< struts:property value = "name" /> < br />
struts:iterator >
Ø subset 标签:过滤集合元素:maleList是action中的集合属性,decider是Action中的Filter,必须实现SubsetIteratorFilter.Decider接口
< s:subset source = "maleList" decider = "decider" >
< s:iterator >
< s:property />
< br >
s:iterator >
s:subset >
Action中decider代码如下:
private SubsetIteratorFilter.Decider decider = new SubsetIteratorFilter.Decider() {
//返回true则将该对象置于子集合中
public boolean decide(Object obj ) throws Exception {
if ( obj instanceof String) {
if ( obj .equals( "Other" )) return false ; else return true ;
} return false ;
} };
162. 数据标签:
Ø action/include :包含action页面,相当于jsp中的include
< s:action name = "login" executeResult = "true" ignoreContextParams = "false" />
< span id = "indicator" style = "background:#FFF000; padding: 4px;" > 正在刷新 < s:property value = "#news" /> ... span >
< s:div theme = "ajax" href = "%{news}" showLoadingText = "false" updateFreq = "5000" indicator = "indicator" />
< s:form name = "newsActionForm" id = "newsActionForm" >
< s:textfield name = "key" label = " 关键词 " />
< s:submit value = " 查询新闻 " href = "%{news}" formId = "newsActionForm"
theme = "ajax" targets = "divNewsSearch" />
s:form >
< div id = "divNewsSearch" > div >
Ø tabbedPanel 标签页:
< s:tabbedPanel id = "test" closeButton = "tab" >
< s:div id = "one" label = " 第一个 TabItem" theme = "ajax" cssStyle = "padding:10px; " > 第一个 TabItem < br /> 第一个 TabItem < br /> s:div>
< s:url action = "divNews" id = "divNewsUrl" > s:url>
< s:div id = "three" label = " 新闻列表 " theme = "ajax" href = "%{#divNews Url}" > s:div>
s:tabbedPanel>
Ø tree / treenode 标签显示树,可显示文件结构,可动态加载数据。 P512
第19章 Struts2.x 拦截器与文件上传
165. Struts2提供面向切面编程(AOP,Aspect Oriented Programming),拦截器是一种成熟的AOP实现 。
166. ★★★拦截器(Interceptor)与过滤器(Filter)的区别:
1、拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器。
3、拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4、拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5、在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
167. timer 计时拦截器,能在控制台记录action方法运行时间。
< action name ="timer" class ="com.czf.struts2.action.TimerAction">
< interceptor-ref name ="timer"> interceptor-ref > <-- 引用Struts的拦截器-->
< result > /timerSuccess.jspresult >
action >
168. token 防重复提交拦截器,使用时要在 标签中添加< struts:token /> :
< action name = "token" class = "com.czf.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 >
169. executeAndWait 执行等待拦截器,在Action忙时,显示等待页面。现一般通过Ajax实现无刷新,显示进度条
170. 自定义拦截器(权限验证): 自定义拦截器一般继承自AbstractInterceptor类,或者直接实现Interceptor接口。
public class AuthenticationInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = -4433771430728214868L;
@Override @SuppressWarnings ("all" )
public String intercept(ActionInvocation invocation )throws Exception {
Map sessionValues = invocation .getInvocationContext() .getSession();
Stringaccount = (String) sessionValues .get("account" );
if (account == null ) { return Action.LOGIN ; }
return invocation.invoke();//验证通过,继续执行Action
}}
< package name ="main" extends ="struts-default" >
< interceptors >
< interceptor name ="authentication" class ="czf.interceptor.AuthenticationInterceptor" > interceptor >
interceptors >
< global-results >
< result name ="login" > /login.jspresult >
global-results >
< action name ="authentication" class ="czf.action.AuthenticationAction" >
< interceptor-ref name ="authentication" > interceptor-ref >
< result > /authenticationSuccess.jspresult >
action >
package >
171. Struts2上传文件 : Struts2直接将上传的文件封装为Java中的File对象(Struts1.x封装为FormFile),直接在Action中定义一个File变量,然后复制文件到保存目录即可。
Ø JSP:
< struts:form action = "upload" enctype="multipart/form-data" method="post" validate = "true" >
< struts:label value = " 上传文件 " > struts:label >
< struts:file name = "picture" label = " 文件一 " > struts:file >
< struts:submit value = " 开始上传 " method="upload" > struts:submit >
struts:form >
Ø Action:
public class UploadAction extends ActionSupport {
private File picture ;
private String pictureContentType ;//可选,Struts自动赋值MIME
private String pictureFileName ;//可选,Struts自动赋值文件名
public String execute() { return "input" ; }
public String upload() throws Exception {
File saved = new File(ServletActionContext.getServletContext ().getRealPath("upload" ), pictureFileName );
Files .copy (picture .toPath(), saved .toPath());//jdk1.7+
return "list" ;
}
}
Ø 上传文件相关设置
struts.properties文件加入下面两句:
struts.multipart.saveDir= /temp 《临时保存目录,在Tomcat所在盘根目录下》
struts.multipart.maxSize=10000000 《此配置需大于struts.xml中的设置》
struts.xml配置如下:
< action name = "upload" class = "com.struts2.action.UploadAction">
< interceptor-ref name = "fileUpload">
< param name = "allowedTypes"> image/bmp,image/png param > 《mime类型》
< param name = "maximumSize"> 90480 param > 《单位Byte》
interceptor-ref >
< interceptor-ref name = "defaultStack" />
< result name = "input"> /upload.jsp result >
< result name = "list"> /uploadList.jsp result >
action >
Ø 错误信息中文化
struts.properties文件加入下面语句:
struts.custom.i18n.resources = com.helloweenvsfei.struts2.resources.Resources
Resources.properties文件如下:
Ø 上传多个文件: P529.在Action中指定File[]或List类型的变量,并在JSP中使用多个同名的 标签即可。
第20章 Hibernate入门
172. Hibernate是一种ORM (ObjectRelational Mapping)框架,在Java对象(POJO)与关系数据库之间建立映射,以实现直接存取Java对象。类似ORM框架有JDO,TopLink,MyBatis(iBatis),OpenJPA。Hibernate是轻量级的框架 ,Java官方的ORM框架EJB、EJB2都是重量级框架,配置复杂,对容器依赖较大,商业上不成功。
173. JPA,ORM,Hibernate的关系 :
Ø JPA(Java Persistence API)框架是javaEE 5 的标准ORM接口。它是一种规范,一套接口,但不是实现。实现这一规范的ORM很多,其中Hibernate就是之一。JPA的目的在于规范各种ORM接口,JPA晚于Hibernate,受Hibernate影响了。
Ø ORM,对象关系映射,它是一种解决问题的思路,是一种思想。它通过配置文件或Java注解把Java对象映射到数据库上,自动生成SQL语句并执行 。
Ø Hibernate是ORM框架,它实现了JPA的规范。
174. Hibernate示例:
Ø 新建Web Project ,加入Hibernate特性,添加Annotation/MySql 等jar库
Ø 新建实体类 :Cat.java:注解都用javax.persistence.* 下的注解,如果某个字段不需要保存到数据库,可以用@javax.persisence.Transient配置
@Entity
@Table(name= "tb_cat" )
public class Cat {
@Id
@GeneratedValue(strategy= GenerationType. AUTO )
private Integer id ;
@Column(name= "name" )
private String name ;
@ManyToOne
@JoinColumn(name= "mother_id" )
private Cat mother ;
@Temporal(value = TemporalType. TIMESTAMP )// DATE 、 TIME 或 TIMESTEMP
private java.util.Date createDate ;
}//getter 和 setter 方法略
Ø 修改Hibernate配置文件,hibernate.cfg.xml
< hibernate-configuration>
< session-factory>
< property name = "hbm2ddl.auto" > create property>
< propertyname = "dialect" > org.hibernate.dialect.MySQLDialect property>
< property name = "connection.password" > admin property>
< property name = "connection.username" > root property>
< property name = "connection.url" > jdbc:mysql://localhost:3306/ hibernate?characterEncoding=UTF-8 & useSSL=true property>
< property name = "connection.driver_class" > com.mysql.jdbc.Driver property>
< property name = "show_sql" > true property> 《控制台显示SQL语句》
< property name = "current_session_context_class" > thread property> 《对于 Jboss 等内置 Hibernate 的容器配置为 jta ,其他容器 Tomcat 等设为 thread 》
< property name = "javax.persistence.validation.mode" > none property>
< mapping class = "com.czf.hibernate.bean.Cat" />
session-factory>
hibernate-configuration>
Ø 如果使用注解配置数据库映射,MyEclipse生成的HibernateSessionFactory类中的Configuration对象应改为AnnotationConfiguration 对象。如果使用XML配置数据库映射,则无需修改。
Ø 配置Log4J:Hibernate使用Log4J输出日志,src目录下log4j.properties:
log4j.rootLogger=ERROR, stdout
log4j.category.org.hibernate.tool.hbm2ddl=DEBUG, file
log4j.category.org.hibernate.SQL=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n
log4j.appender.file= org.apache.log4j.FileAppender
log4j.appender.file.File= log.txt
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=Hibernate: %m%n
Ø 执行Hibernate程序
Cat mother = new Cat();
mother .setName("Marry White" ); mother .setDescription("Ther Mama Cat." ); mother .setCreateDate(new Date());
Cat kitty = new Cat();
kitty .setName("Kitty" ); kitty .setDescription("Hello Kitty." );kitty .setMother(mother ); kitty .setCreateDate(new Date());
Session session = HibernateSessionFactory.getSession ();
Transaction trans = session .beginTransaction();
session .persist(mother ); session .persist(kitty );
List catList = session .createQuery("from Cat" ).list();
trans .commit(); session .close();
StringBuffer result = new StringBuffer();
result .append(" 数据库里的所有的猫: \r\n\r\n" );
for (Cat cc : catList ){
result .append(" 猫: " + cc .getName() + ", 猫妈妈: " + (cc .getMother() == null ? " 没有记录 " :cc .getMother().getName()) + "\r\n" );
}
JOptionPane.showMessageDialog (null , result .toString());
第21章 从宏观上把握Hibernate
175. Hibernate在程序中的位置:
Ø Hibernate直接操作Java对象,底层使用JDBC实现。
Ø 使用Hibernate后,开发者可以不用关注JDBC,而更关心业务逻辑。
Ø Hibernate是跨数据库平台的,通过配置不同sql方言(Dialect),生成不同的SQL语句。
176. Hibernate默认配置文件为hibernate.properties或者hibernate.cfg.xml位于classpath下面。如果properties文件中配置了参数,在cfg.xml中只声明实体类配置的位置就可以了。
< hibernate-configuration>
< session-factory>
< mapping resource = "com/czf/hibernate/bean/Cat.hbm.xml" />
session-factory>
hibernate-configuration>
177. Hibernate可以进行编程式配置(运行时配置)
Ø 调用Configuration对象的addResource(“com/czf/hibernate/bean/ Cat.hbm.xml”)方法可以动态加载实体类配置
Ø 调用addClass(com.czf.hibernate.bean.Cat.class)可以直接加载实体类(推荐 )
Ø 调用setProperty或者addProperties方法设置一个或多个Hibernate参数
第22章 Hibernate实体映射
178. Hibernate实体映射分为xml映射(Cat.hbm.xml等)和@注解映射(推荐: 对于所有ORM框架,注解映射通用) 。注解映射示例见20章,xml映射示例:
< hibernate-mapping package = "com.helloweenvsfei.hibernate.bean">
< class name = "Cat" table = "tb_cat">
< id name = "id" column = "id"> id >
< property name = "name" type = "string" column = "name"> property >
< property name = "description" type = "text"> property >
< property name = "createDate" type = "timestamp"> property >
< many-to-one name = "mother" column = "mother_id"> many-to-one >
class >
hibernate-mapping >
179. 主键映射:尽量选择可以为null的类型,如Integer、Long等,因为主键为null可以表示实体还没有保存到数据库的临时状态。
Ø 注解主键生成规则 :@GeneratedValue,JPA通用策略生成器 。JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
TABLE
使用一个特定的数据库表格来保存主键。 将当前主键的值单独保存到一个数据库的表中,主键的值每次都是从指定的表中查询来获得,这种生成主键的方式也是很常用的。这种方法生成主键的策略可以适用于任何的数据库,不必担心不同数据库不兼容造成的问题 。
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator="customer_gen ")
@TableGenerator(name = "customer_gen ",
table="tb_generator",
pkColumnName="gen_name", //该表中有这两列
valueColumnName="gen_value" ,
pkColumnValue="CUSTOMER_PK",
allocationSize=1 )
SEQUENCE
根据底层数据库的序列来生成主键,条件是数据库支持序列。(Oracle,DB2,PostgreSQL等)
IDENTITY
主键由数据库自动生成(主要是自动增长型) 。(DB2,MySQL,MS SQL Serer,Sybase)
AUTO
自动方式,根据底层数据库自动选择。
@Id// 指定该列为主键
@Column(name = "id" )
@GeneratedValue(strategy = GenerationType. AUTO ) // 主键类型 , auto 为数据库自增长类型
private Integer id ;
Ø XML主键生成规则 :
native
相当于GenerationType. AUTO 。 由hibernate根据使用的数据库自行判断采用identity、hilo、sequence其中一种作为主键生成方式,灵活性很强。
identity
同GenerationType. IDENTITY
sequence
同GenerationType. SEQUENCE
increment
由Hibernate从数据库中取出主键的最大值,每次增量为1,在内存中生成主键,不依赖于底层的数据库,可以跨数据库。
只能有一个Hibernate应用进程访问数据库,否则就可能产生主键冲突,所以不适合多进程并发更新数据库
hilo
hilo(hi/lo算法)是hibernate中最常用的一种生成方式,需要一张额外的表保存hi的值。
seqhilo
与hilo类似,通过hi/lo算法实现的主键生成机制,只是将hilo中的数据表换成了序列sequence,需要数据库中先创建sequence,适用于支持sequence的数据库,如Oracle。
uuid
(Universally Unique Identifier)uuid长度大,占用空间大,跨数据库,不用访问数据库就生成主键值,所以效率高且能保证唯一性,移植非常方便,推荐使用 。
guid
(Globally Unique Identifier)需要数据库支持查询uuid,生成时需要查询数据库,效率没有uuid高,推荐使用uuid 。
assigned
主键由外部程序负责生成,在 save() 之前必须指定一个。Hibernate不负责维护主键生成。
select
使用触发器生成主键,主要用于早期的数据库主键生成机制,能用到的地方非常少。
foreign
使用另外一个相关联的对象的主键作为该对象主键。主要用于一对一关系中。
180. 属性延迟加载@Basic (fetch = FetchType.LAZY ,optional = true)
181. 临时属性映射,使用注解时用@Transient。使用xml配置时,没配置到xml中的属性都被视为临时属性。
182. Hibernate乐观锁:
Ø 乐观锁的作用
乐观锁 的主要作用是为了解决事务并发带来的问题。相对于悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁 大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销。
Ø 乐观锁的工作原理
乐观锁,大多是基于数据版本(Version)记录机制实现。为数据增加一个版本标识,一般是通过为数据库表增加一个"version"字段来实现。读取出数据时,将此版本号一同读出,而更新对象时,对此版本号加1(使用hql或者原生sql更新时,version失效 )。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据,抛出异常。
Ø 使用@version或 指定实体类中的Version列即可
第23章 Hibernate实体关系映射
183. 单边一对多关系 :一个人对应多个电子邮件,Person.java中配置一对多关系
@OneToMany (fetch = FetchType.LAZY , targetEntity = Email.class , cascade = { CascadeType.PERSIST , CascadeType.REMOVE , CascadeType.MERGE , CascadeType.REFRESH })
@JoinColumns (value= { @JoinColumn (name = "person_id" , referencedColumnName = "id" ) })
@OrderBy (value="email desc" )
private List emails = new ArrayList();
184. 延时加载(默认) (fetch = FetchType.LAZY ),需在session关闭前调用persoin.getEmails(),迫使Hibernate加载数据,否则会产生异常。
即时加载 (fetch = FetchType.EAGER )
185. hibernate.hbm2ddl.auto的值
create
表示启动的时候先drop,再create
create-drop
也表示创建,只不过再系统关闭前执行一下drop
update
这个操作启动的时候会去检查schema是否一致,如果不一致会做scheme更新
validate
启动时验证现有schema与你配置的hibernate是否一致,如果不一致就抛出异常,并不做更新
186. @注解配置为JPA(Java Persistence API)配置,各ORM框架通用。XML配置为Hibernate独有,比注解配置更丰富,更灵活。
187. XML配置Person类,bag标签配置List属性,cascade可用“-”配置多个级联方式,例如“persist-save-delete”:
< hibernate-mapping package = "com.helloweenvsfei.hibernate.bean">
< class name = "Person2" table = "tb_person2">
< id name = "id" column = "id"> < generator class = "native"/> id >
< property name = "name" />
< bag name = "emails"cascade = "all" lazy = "false" where = "email like '%@%' " order-by = "email">
< key column = "email_id"> key >
< one-to-many class = "com.helloweenvsfei.hibernate.bean.Email"/>
bag >
class >
hibernate-mapping >
188. 单边一对一、多对一、多对多关系、双边的一对一、一对多、多对一、多对多关系配置见P578
第24章 Hibernate查询语言HQL
189. HQL类似于SQL,不同的是HQL是面向对象的,可直接查询实体类及属性。HQL大小写不敏感,但是涉及到java包名,类名,属性时大小写敏感。
190. 返回类型:
Ø 返回单个对象:
Query q= session.createQuery(“ selectcount(c) from Cat c “);
Number num=(Number)q.uniqueResult ();//如果返回值有多个报异常
int count=num.intValue();
Ø 返回List:
List list=session.createQuery(“select c from Cat c “).list ();
191. 同时返回多个对象:
Ø 返回Object[] 数组
List list=session.createQuery(“ select c.name,c.mother ,c.createDate from Cat c”).list();//因select 中既有String 又有Object
Ø 返回List或者Map类型
List list=session.createQuery(“select new List( c.name,c.mother ,c.createDate ) from Cat c”).list();
List list=session.createQuery(“select new Map( c.name as name ,c.motheras mother , c.createDate as createDate ) from Cat c”).list();
Ø 返回Java实体对象(查询部分属性时)
List catList= session.createQuery(“select new Cat( c.name, c.createDate ) from Cat c”).list();//调用构造函数,前提得有这个public的构造函数。
192. HQL参数格式为 :parameter ,使用Query的setParameter方法设置参数。应尽量使用setParameter传递参数 ,而不是将参数写到HQL语句中(Hibernate对于参数不同的相同查询有优化,即第二次后直接使用编译好的SQL语句)
193. HQL运算符和函数:其余运算符见P610.
Ø 使用 || 或者 concat(…,…) 连接字符串
Ø 集合查询:List list=session.createQuery(“ from Cat c where size (c.events)>5 “).list();
Ø 统计函数:count(),sum(),min(),max(),avg()等
194. HQL分页 :Query对象的setFirstResult ()设置起始记录(第一条记录索引从0开始);setMaxResults ()设置本页大小(本次取记录的个数)。
195. HQL级联查询
Ø 一般跨表查询用.(点号)即可,适用于非集合属性:
ListeventList=session.createQuery(“ select e from Event e where e.cat.name = ‘Ketty’ “).list();
Ø 级联查询(inner join,left join,right join等),适用于集合属性:
查询events集合属性中有“吃早饭”时间的cat:
List list=session.createQuery(“select c from Cat c left join c.events ewhere e.description like :description “).setParameter(“description”,”%吃早饭%”).list();
196. Hibernate使用SQL语句查询:使用SQLQuery对象
SQLQuery sqlQuery= session.createSQLQuery(“select * from tb_cat “);
sqlQuery.addEntity(Cat.class);//设置输出类型
List list= sqlQuery.list();
197. 命名常用查询 :
Ø 注解配置 :
在实体类上使用注解@NamedQuery配置HQL查询,使用@NamedNativeQuery配置命名的底层数据库SQL查询,使用@NamedQueries或@NamedNativeQueries设置多个命名查询:
//@NamedQuery(name= "all cat", query = " select c from Cat c ")
//@NamedNativeQuery(name= "all cat", query = "select * from tb_cat")
@NamedQueries (value = { @NamedQuery (name = "allcat" , query = " select c from Cat c " ), @NamedQuery (name = "cat bymother" , query = " select c from Cat c " ) })
使用时:Queryq=session.getNamedQuery(“cat by name ”).setParameter (“name”,“Kitty”);
Ø XML配置: 在实体类 节点内最后用 或者 配置
< query name = "findStudentByName">
from Student where name = :name ]]>
query >
< sql-query name = "findStudentByName">
< return alias = "s" class = "com.test.bean.Student"> return >
select {s.*} from student s where s.name = :name ]]>
sql-query >
第25章 Hibernate高级查询
198. Servlet + Hibernate 员工管理示例见P617.
第26章 Spring概述
199. 轻量级框架 :不依赖与容器就能运行的框架 。Spring、Struts、Hibernate都是轻量级的框架。EJB是重量级的,只能运行在支持EJB的容器如(Jboss,Glassfish)。
200. Spring实际是一个轻量级的容器 ,能够生产、管理、维护各种实例(DAO,Service)。
201. Spring的重要思想是IOC(控制反转)与AOP(面向切面编程)。
202. Spring主要思想是IoC (Inversion ofControl,控制反转 ,反向控制),或者称之为DI (Dependency Injection,依赖注入 )。IoC是对传统控制流程的一种颠覆。
Ø 传统程序中 ,相互的依赖关系(new 产生对象)是固定在程序中的。程序的执行流程可以从代码中阅读出来,都是正向运行的。
Ø 反向控制(IoC) ,代码中定义接口类型对象IDao,而不用new实例化(实例化一个DaoImpl对象)。该对象将被Spring注射 进来(通过反射 调用getter,setter方法)。而注射的动作发生在运行时,是在ServiceImpl代码写完之后,这个方向是反向的。Service层仍然要依赖Dao层,只不过这种依赖关系并不是写在程序中,而是配置在Spring文件中 ,由Spring在运行时设置。
203. Spring实例:
public interface IDao { public StringsayHello(String name );}
public class DaoImpl implements IDao {
public String sayHello(String name ) {
int hour = Calendar.getInstance ().get(Calendar. HOUR_OF_DAY );
if ( hour < 12){ return " 上午好 ," + name ; } else { return " 下午好 ," + name ; }
}
}
public interface IService { public void service(String name );}
public class ServiceImpl implements IService {
private IDao dao ;
public IDao getDao() { return dao ; }
public void setDao(IDao dao ) { this . dao = dao ; }
public void service(String name ) {
System. out .println( dao .sayHello( name ));
}
}// applicationContext.xml 配置文件如下:
xml version = "1.0" encoding = "UTF-8" ?>
<beans …… >
<bean id = "daoImpl" class = "czf.spring.dao.DaoImpl" > bean >
<bean id = "serviceImpl" class = "czf.spring.service.ServiceImpl" >
<property name = "dao" ref = "daoImpl" >property >
bean >
beans >
运行(Spring4.1):
public static void main(String[] args ) {
ApplicationContext context = new ClassPathXmlApplicationContext ("applicationContext.xml" );
IService helloService = context .getBean(ServiceImpl.class );
helloService .service(" 码云 " );
}
204. 面向切面编程 (AOP,Aspect Oriented Programing):在执行业务代码的前后执行另外的代码 ,使程序能灵活、扩展性更好,可以随意地添加、删除某些功能 (A|B à A|C|B。A、B、C看成切面,可将C组件插入到A组件与B组件中执行)。
Servlet中的Filter就是面向切面编程的例子,Tomcat会在程序运行的某个时机(即Servlet执行前后),执行与Servlet、JSP等毫无关系的Filter代码。
Spring提供非常灵活的AOP机制,Spring的另一种重要思想是AOP 。
205. 面向切面编程(拦截器Interceptor)实例:
定义方法执行前的拦截器:
public class MethodBeforeAdviceImpl implements MethodBeforeAdvice {
public void before(Method method , Object[] args , Object obj ) throws Throwable {
System. out .println( " 运行前检查 ... " );
System. out .println( "Method:" + method .getName());
System. out .println( "Args:" + Arrays.asList ( args ));
System. out .println( "Object:" + obj );
}
}//配置拦截器:
< bean id = "methodBeforeAdviceImpl" class = "com.helloweenvsfei.spring.example.MethodBeforeAdviceImpl" > bean >
< bean id = "theAdvisor" class = "org.springframework.aop. support.NameMatchMethodPointcutAdvisor" >
< property name = "advice" >
< ref local = "methodBeforeAdviceImpl" />
property >
< property name = "mappedName" value = "*" > property >
bean >
< bean id = "dao" class = "com.helloweenvsfei.spring.example.DaoImpl" >
bean >
< bean id = "serviceImpl" class = "com.helloweenvsfei.spring.example.ServiceImpl" > < property name = "dao" ref = "dao" > property > bean >
< bean id = "service" class = "org.springframework.aop.framework. ProxyFactoryBean" >
< property name = "interceptorNames" value = "theAdvisor" > property >
< property name = "target" > < ref local = "serviceImpl" /> property >
bean >
206. Spring 框架的组成如下图所示:
第27章 Spring的Core模块
207. Core模块是Spring最核心的模块,实现加载配置文件、管理、初始化Beans等功能。(实现IoC功能 ,Spring 所有功能都是借助IoC实现的)
第28章 Spring的AOP模块
208. AOP模块提供拦截器机制,允许自定义、配置方法拦截器、拦截的对象。
209. Spring提供三种拦截器:方法前拦截器、方法返回后拦截器、异常抛出拦截器。
210. 代理模式是Spring中常用的设计模式。Spring提供代理类:ProxyFactoryBean和TransactionProxyFactoryBean(为前者子类)
第29章 Spring的DAO模块
211. DAO模块提供JDBC支持,对JDBC进行封装,完全抛弃了JDBCAPI (无需与Connection、Statement、PreparedStatement、ResultSet等打交道),只需要继承JdbcDAOSupport类 使用封装好的JdbcTemplate 执行SQL语句。允许JDBC使用Spring的资源,并统一管理JDBC数据库连接和事务。
第30章 Spring的ORM模块
212. ORM模块提供对常用ORM框架的管理。Spring支持Hibernate、MyBatis/JDO等各种ORM框架,Spring并不提供自己的ORM实现,只是对现有的ORM框架进行封装,管理。
213. 使用Spring+Hibernate时,Hibernate及其SessionFactory等只是Spring一个特殊的Bean,由Spring负责实例化与销毁。DAO层只需要继承HibernateDao Support 类 ,而不需要与Hibernate API 打交道(不需要开启、关闭Session等)。Hibernate配置也可以转移到Spring配置文件中。
第31章 Spring的Web模块
214. Web模块提供对Struts、WebWork、JSF等各种Web框架的支持。Spring能够管理这些框架,并将Spring的各种资源如数据源、Beans等注射给框架。
215. Spring整合Struts1.x有继承方式(继承Spring提供的ActionSupport 类)和代理方式。继承方式较简单,但与Action代码与Spring代码发生了耦合,且Action并没有交给Spring管理,因此不能使用Spring的AOP,IOC等特性。代理方式 没有这些问题。推荐使用代理方式 ,Spring支持Struts2.
第32章 Spring的MVC模块
216. Web MVC模块是Spring提供的轻量级MVC实现,在Spring框架中可以使用Struts作为MVC框架,也可以使用Spring自带的MVC框架,SpringMVC 与Struts等框架相比更加简洁、灵活 。
第33章 Spring开发实例(SSH、SSJ)
217. IP地址库插件,查询实际地址:QQWry.data
第34章 EJB3概述
218. Enterprise JavaBeans 3 简称EJB3 ,是sun的JavaEE服务器端组件模型,设计目标与核心应用是部署分布式应用程序 。简单来说就是把已经编写好的程序(即:类)打包放在服务器上执行。凭借java跨平台的优势,用EJB技术部署的分布式系统可以不限于特定的平台。EJB适用于大型软件系统 ,比如证券系统,银行系统。EJB分类如下:
第35章 JPA规范
219. JPA(Java Persistence API,Java持久化API)与Hibernate等框架一样,都是Java持久化解决方案,负责把数据保存金数据库,不同的是JPA只是一种标准,规范,而不是框架,JPA自己并没有具体的实现。
220. JPA旨在规范ORM框架,使ORM框架有统一的接口,统一的用法。Hibernate、TopLink、OpenJPA都实现了JPA
第36章 WebService框架Xfire
221. Xfire已于2007年与Celtix合并,整个成为Apache的CXF 项目。
222. java中length,length(),size()区别
1 java中的length属性是针对数组说的,获取数组的长度则用到了length这个属性. 2 java中的length()方法是针对字符串的,获取字符串的长度则用到length()方法. 3.java中的size()方法是针对泛型集合说的, 调用此方法来查看集合元素个数
第37章 版本管理工具SVN
第38章 日志工具commons-logging与log4j
223. log4j应用最广泛。commons-logging没有日志功能,只是统一了JDK Logging(鸡肋)与Log4J的API,并把日志功能交给JDK Logging或者Log4j.
第39章 报表图形引擎JfreeChart
第40章 PDF组件iText