不赞成特?/strong>
Struts1.1中已l有很多构造不再赞成用。许多已l被删除了。所以在升?.2.4Ӟ请clean-compile 你的应用Qƈ且deprecation warnings 被打开。在升?.2.4之前强烈解决所有decprecated 的用法。最可能应用开发h员的用法是:
虽然没有被删除也没有被标明ؓ不赞成用,最好还是将ActionErrors 替换为ActionMessages 以确保正的操作?
TagUtils ?/strong>ModuleUtils
许多以前在org.apache.struts.utils.RequestUtils中找到的工具Ҏ如今UdCorg.apache.struts.taglibs.TagUtils 或org.apache.struts.utils.ModuleUtils包中?
GenericDataSource / GenericConnection 实现被删?/strong>
datasources manager 仍然支持Q但是我们自qdatasource implementationis q不被支持。很Ƣ迎你插入自qDataSource 实现Q但是我们没有资源来l护我们自己的实现。如果你的容器不支持DataSource实现Q推荐用Jakarta Commons?DBCP package?
Validator 增强
Struts Validator 如今支持ValidWhen 规则Q以便一个验证可以依赖于另一个验证?/p>
DigestingPlugIn
一个新的标准PlugIn 可以帮助你在application范围内创Z自己的对象图Qobject graphQ。这是创ZAction调用的业务对象的快捷方式。请参见最新的MailReader CZ来看如何使用DigestingPlugin?
ModuleConfigVerifier
虽然不是全新的,一个标准类Q用来验证模块配|,位于PlugIn 包。ModuleConfigVerifier 主要认Struts对象囄各中lg被蝲入。但是,开发h员可扩展此类来检查确保Struts 配置文g的内部一致性?
提供了支持Maven的项目文?/strong>.
新的配置DTD
推荐使用struts-config_1_2.dtd。新的DTD d了两个新的元?lt;display-name> ?<description> 到struts-config 元素中。这些元素可用于struts配置文g工具和文档生工兗在Struts 1.2.x 中,已有的Struts 配置文g可以使用两个版本的DTD 都可载入?
新的Taglib URIs
标签库的URI已经被修改已反映Struts从Jakarta Ud了Apache 的顶U项目。ؓ了兼容,使用旧的URI的TLD仍然有效Q但是鼓׃用新的URI?
Struts-Chain
试验性的Q这个新?contrib" package 使用了Jakarta Sandbox中的Responsibilty package 的Chainin 来创Z个新的RequestProcessor的Breed。未来版本可能会成ؓ默认实现?
MappingDispatchAction
一个新的标准ActionQ将控制转发到ActionMapping 参数命名的一个方法?
Cancel handlers
DispatchAction, LookupDispatchAction, ?MappingDispatchAction Q如今提供了默认的可以覆写的cancel handler。也可以指定默认的handler name?
Session-scoped ActionMessages
现在你可以将ActionMessages 保存在session 中and have them cleaned up after the first use。现在除了Action.saveMessages() 消息保存在session中还有了另外一U选择。在消息已经被访问过一ơ之后ActionMessages.isAccessed() q回true。RequestProcessor.processCachedMessages() 查询isAccessed() 已决定是否应该将消息从session中删除?
JA Mailreader
Struts Mailreader Example 应用现在包含Japanese 资源文g?
Tiles EL
Tiles tags 如今可以通过Struts EL taglib使用ELQ后者基于JSTL?
Wildcard Mappings
现在可以在actiponMapping中用通配W。详l信息参见Struts Mailreader Example application?
Action attributes
html img tag d了Action 属性,以匹配html link tag?
Module attribute
Forward元素以及多个核心标签中新增一?module" 属性。这个属性允怽通过名称Q或者前~Q指定另一个模块来创徏模块间的直接链接。新的module 属性优于contextRelative属性,q且可以常用?SwitchAction"中?
Struts 对下列组件的依赖性发生了改变Q?
依赖? |
新的版本 |
Commons BeanUtils |
Version 1.7.0 |
Commons Digester |
Version 1.6 |
Commons Validator |
Version 1.1.4 |
Commons Collections |
removed |
Commons Lang |
removed |
在action也新增了一个方法[saveErrors(HttpSession, ActionMessages)]来将errors 保存在Session 中,q且在其W一ơ被讉K之后被自动从Session中删除。这是等同于1.2.4 中message上新增的功能?
ActionRedirect 是ActionForward 的一个子c,其设计来用于重定向请求,支持在运行时d参数?
DownloadAction 是一个提供了下蝲文g的具体细节的抽象Action?
ActionDispatcher 是一个提?em>DispatchAction cd的行Z是不必承自DispatchAction?
DynaBean 风格的ActionFormQ它不需要其属性被定义Qƈ提供Lazy List ?em>Lazy Map 行ؓ?
配置文g(? Struts config, Validator config ?Tiles 配置文g)现在可以被保存在jars。Struts 会像以前一h查servlet contextQ但是如果没扑ֈQ?Struts 会尝试classloader L找?
Struts现在可以使用HTML Input Tags上的 errorKey, errorStyle, errorStyleClass ?errorStyleId 属性自动高亮错误字Dc?
现在可以使用<html:form> tag?em>readonly ?em>disabled属性来止或者全部的字D只诅R?br />N.B. readonly 属性只影响<html:text>, <html:textarea> ?<html:password> as per the HTML 4 specification?
许多HTML标签都被重构了,以便更易使用?/p>
bundle 属性被dC下列标签QButtonTag, CancelTag, CheckboxTag, FileTag, FrameTag, HiddenTag, LinkTag, MultiboxTag, PasswordTag, RadioTag, ResetTag, SelectTag, SubmitTag, TextTag, TextareaTag?
现在新增?strong>header, footer, prefix, suffix属性?/strong>
Validator 配置文g?e.g. validation.xml)?lt;msg> ?<arg> 元素?em>bundle 属性现在随?lt;msg> ?em>resource 属性一起得到支持?
struts-examples webapp 中添加了新的面来展C对Resource Bundle 的支持?/em>
Struts 1.2.8 的主要改变是修正?em>Cross Site Scripting (XSS) q?
Struts 1.0 的配|DTD 已经不赞成用,引入了新的struts-config_1_1.dtd。在Struts 1.1 中,已有的Struts 配置文g可以使用q两个版本的DTD载入?
在Struts中用了多个Apache Jarkarta commons的组Ӟ而Commonslgq不仅仅可以用来构徏Struts应用。在Struts1.1中,所使用的Commonslg已经重构来外部依赖于Jarkarta Commons目Q而不?.0中的内部版本?
下面的Commons包包括了对相应的Struts 1.0 中的cȝ替代Q?
下面q几个包现在仍然被Struts框架的各U组件用:
另外Q?/strong>Struts 1.1 需要符合JAXP/1.1 (而不是JAXP/1.0) API的XML解析器,比如JAXP/1.1 参考实现和Xerces 1.3.1+?
如果需要从源代码开始构建StrutsQ请使用Ant 1.4 以上版本?
一个新的Commons Validatorlg被集成到Struts 1.1中,包含在新的Validator包中?
引入了一个新的JSP模板l装机制TilesQ通过标签库提供集成?
Nested taglib l定CStruts1.1中,增强了现有Struts标签的功能?
Struts1.1发布包中包括了针对Validator 和Tiles的新的示例?
CVS源代码库中新增了一个目录contribQ包含了很有用的Q但是没有集成到标准代码Z的扩展?
基本的控制器框架 [org.apache.struts.action]新增了一下特征:
文g上传c[org.apache.struts.upload]新增了一下特征:
工具QutilityQ类 [org.apache.struts.util]新增了以下特征:
struts-bean 标签库[org.apache.struts.taglib.bean]中新增了以下特征Q?
struts-html [org.apache.struts.taglib.html]加入了如下新特征Q?
struts-logic 标签库[org.apache.struts.taglib.logic]加入了如下新特征Q?
无变化,但无赞成使用。推荐用Tiles.
基本框架(org.apache.struts.action)q行了如下修Ҏ者修正:
utilities (package org.apache.struts.util)发生如下修改和修正:
struts-html 标签?package org.apache.struts.taglib.html)发生了如下修改和修正Q?
Struts Documentation 应用(对应Struts |站的内?发生了如下修改:
Struts MailReader Example Application 发生如下修改和修正:
Struts Exercise Taglib Example Application 发生了如下修改和修正Q?
q里列出1.0?.1中新增的cd已经不赞成用的c:
action
actions
taglib.html
taglib.logic
upload
util
action.Action
action.ActionServlet
taglib.html.BaseHandlerTag
action
action.Action
ActionServlet
public class HibernatePlugIn implements PlugIn{
private String configFile;
// This method will be called at application shutdown time
public void destroy() {
System.out.println("Entering HibernatePlugIn.destroy()");
//Put hibernate cleanup code here
System.out.println("Exiting HibernatePlugIn.destroy()");
}
//This method will be called at application startup time
public void init(ActionServlet actionServlet, ModuleConfig config)
throws ServletException {
System.out.println("Entering HibernatePlugIn.init()");
System.out.println("Value of init parameter " +
getConfigFile());
System.out.println("Exiting HibernatePlugIn.init()");
}
public String getConfigFile() {
return name;
}
public void setConfigFile(String string) {
configFile = string;
}
}
<struts-config>
...
<!-- Message Resources -->
<message-resources parameter=
"sample1.resources.ApplicationResources"/>
<!-- Declare your plugins -->
<plug-in className="com.sample.util.HibernatePlugIn">
<set-property property="configFile"
value="/hibernate.cfg.xml"/>
</plug-in>
</struts-config>
public void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// Wrap multipart requests with a special wrapper
request = processMultipart(request);
// Identify the path component we will
// use to select a mapping
String path = processPath(request, response);
if (path == null) {
return;
}
if (log.isDebugEnabled()) {
log.debug("Processing a '" + request.getMethod() +
"' for path '" + path + "'");
}
// Select a Locale for the current user if requested
processLocale(request, response);
// Set the content type and no-caching headers
// if requested
processContent(request, response);
processNoCache(request, response);
// General purpose preprocessing hook
if (!processPreprocess(request, response)) {
return;
}
// Identify the mapping for this request
ActionMapping mapping =
processMapping(request, response, path);
if (mapping == null) {
return;
}
// Check for any role required to perform this action
if (!processRoles(request, response, mapping)) {
return;
}
// Process any ActionForm bean related to this request
ActionForm form =
processActionForm(request, response, mapping);
processPopulate(request, response, form, mapping);
if (!processValidate(request, response, form, mapping)) {
return;
}
// Process a forward or include specified by this mapping
if (!processForward(request, response, mapping)) {
return;
}
if (!processInclude(request, response, mapping)) {
return;
}
// Create or acquire the Action instance to
// process this request
Action action =
processActionCreate(request, response, mapping);
if (action == null) {
return;
}
// Call the Action instance itself
ActionForward forward =
processActionPerform(request, response,
action, form, mapping);
// Process the returned ActionForward instance
processForwardConfig(request, response, forward);
}
<controller>
<set-property property="locale" value="false"/>
</controller>
<controller>
<set-property property="contentType" value="text/plain"/>
</controller>
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 1);
<controller>
<set-property property="noCache" value="true"/>
</controller>
<action path="/newcontact" type="com.sample.NewContactAction"
name="newContactForm" scope="request">
<forward name="sucess" path="/sucessPage.do"/>
<forward name="failure" path="/failurePage.do"/>
</action>
<form-bean name="newContactForm"
type="org.apache.struts.action.DynaActionForm">
<form-property name="firstName"
type="java.lang.String"/>
<form-property name="lastName"
type="java.lang.String"/>
</form-bean>
<action forward="/Login.jsp" path="/loginInput"/>
<action include="/Login.jsp" path="/loginInput"/>
public class CustomRequestProcessor
extends RequestProcessor {
protected boolean processPreprocess (
HttpServletRequest request,
HttpServletResponse response) {
HttpSession session = request.getSession(false);
//If user is trying to access login page
// then don't check
if( request.getServletPath().equals("/loginInput.do")
|| request.getServletPath().equals("/login.do") )
return true;
//Check if userName attribute is there is session.
//If so, it means user has allready logged in
if( session != null &&
session.getAttribute("userName") != null)
return true;
else{
try{
//If no redirect user to login Page
request.getRequestDispatcher
("/Login.jsp").forward(request,response);
}catch(Exception ex){
}
}
return false;
}
protected void processContent(HttpServletRequest request,
HttpServletResponse response) {
//Check if user is requesting ContactImageAction
// if yes then set image/gif as content type
if( request.getServletPath().equals("/contactimage.do")){
response.setContentType("image/gif");
return;
}
super.processContent(request, response);
}
}
<controller>
<set-property property="processorClass"
value="com.sample.util.CustomRequestProcessor"/>
</controller>
<web-app >
<servlet>
<servlet-name>action=</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<!-- All your init-params go here-->
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app >
A中可含映文件的配置Q而B中hard codes加映文件?/P>
A。Configuration config=new Configuration().config();
B. Configuration config=new Configuration();
config.addClass(TUser.class);
2.你不必一定用hibernate.cfg.xml或hibernate.propertiesq两文g名,
你也不一定非得把配置文g攑֜Classes下,
File file=new File("c:\\sample\\myhibernate.xml");
Configuration config=new Configuration().config(file);
3. session.Flush()
强制数据库立卛_步,当用事务Ӟ不必用flush,事务提交自动调用flush
在session关闭时也会调用flush
4. HibernateL使用对象cd作ؓ字段cd
5. XDoclet专门建立了hibernate doclet,是在java代码上加上一?
java docTagQ后来再让XDoclet分析该java代码Q生成映文?
6.HQL子句本n大小写无养I但是其中出现的类名和属性名必须注意大小写区分?/P>
7.关系Q?
Constrained : U束Q表明主控表的主键上是否存在一个外键(foreigh keyQ?
对其q行U束?
property-ref:兌cM用于与主控类相关联的属性名Q默认ؓ兌cȝ主键属性名
单向一对多需在一斚w|,双向一对多需在双方进行配|?/P>
8.lazy=false:被动方的记录由hibernate负责记取Q之后存攑֜LҎ定的
Collectioncd属性中
9. java.util.Set或net.sof.hibernate.collecton.Bagcd的Collection
10.重要Qinverse:用于标识双向兌中的被动方一端?
inverse=false的一方(L方)负责l护兌关系.默认|false
11.batch-size:采用延迟加蝲特征Ӟ一ơ读入的数据数昨?/P>
12.一对多通过LҎ斎ͼL方ؓ一ҎQ?/P>
user.getAddresses().add(addr);
session.save(user);//通过L对象U联更新
13.在one-to-many 关系中,many 一方设Z动方Qinverse=falseQ将有助性能
的改善。在一方设|关pLQinverse=true,卛_L权交l多方,
q样多方可主动从一方获得foreign key,然后一ơinsert卛_完工?
addr.setUser(user);//讄兌的TUser对象
user.getAddresses().add(addr);
session.save(user);//U联更新
14.只有设ؓL方的一Ҏ兛_Q访问)Ҏ的属性,被动Ҏ不关心对方的属性的?/P>
15.one-to-many与many-to-one节点的配|属性不同:
一对多关系多了lazy和inverse两个属?
多对多节点属性:column:中间映射表中Q关联目标表的关联字D?
class:cdQ关联目标类
outer-join:是否使用外联?nbsp;
注意:access是设|属性值的d方式?/P>
column是设|关联字Dc?
16.多对多,注意两方都要讄inverse和lazy,cascade只能设ؓinsert-update
多对多关pMQ由于关联关pL两张表相互引用,因此在保存关pȝ态时必须对双方同时保存?
group1.getRoles().add(role1);
role1.getGroups().add(group1);
session.save(role1);
session.save(group1);
17.关于vo和po
vol过hibernate定w处理Q就变成了po(该vo的引用将被容器保存,q且在session关闭时flush,因此po如果再传到其它地Ҏ变了Q就危险?
vo和po怺转换QBeanUtils.copyProperties(anotherUser,user);
18.对于save操作而言Q如果对象已l与Session相关联(卛_l被加入Session的实体容器中Q,则无需q行具体的操作。因Z后的Session.flushq程中,Hibernate
会对此实体容器中的对象进行遍历,查找出发生变化的实体Q生成ƈ执行相应的update
语句?
19.如果我们采用了gq加载机Ӟ但希望在一些情况下Q实现非延迟?
载时的功能,也就是说Q我们希望在Session关闭后,依然允许操作user的addresses
属?
Hibernate.initializeҎ可以通过强制加蝲兌对象实现q一功能Q?
q也正是我们Z么在~写POJOӞ必须用JDK Collection接口Q如Set,MapQ?
而非特定的JDK Collection实现c(如HashSet、HashMapQ申明Collection属性的
原因?
20.事务Q从sessionFactory获得session,其自动提交属性就已经关闭(AutoCommit=false),此时若执行了jdbc操作Q如果不昑ּ调用session.BeginTransaction(),是不会执行事务操作的?/P>
jdbc transaction:Z同一个session(是同一个connection)的事?
jta transaction:跨sessionQ跨connectionQ事?
对于jta事务Q有三种实现ҎQ?
A。UserTransaction tx=new InitialContext().lookup("...");
tx.commit();
B. 使用hibernate装的方法:(不推?
Transaction tx=session.beginTransaction();
tx.commit();
C. 使用ejb之sessionBean的事务技持方法,你只要在把需要在发布描述W中Q把需要jta事务的方法声明ؓrequire卛_
21.悲观锁,乐观锁:
乐观锁一般通过version来实玎ͼ注意version节点必须出现在id后?
22.Hibernate中,可以通过Criteria.setFirstResult和Criteria.setFetchSizeҎ讑֮分页范围?
Query接口中也提供了与其一致的ҎQhibernate主要在dialectcM实现在这个功能?
23.cache
<hibernate-configuration>
<session-factory>
…?
<property name="hibernate.cache.provider_class">
net.sf.ehcache.hibernate.Provider
</property>
q需对ecache本nq配|?
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000" //Cache中最大允怿存的数据数量
eternal="false" //Cache中数据是否ؓ帔R
timeToIdleSeconds="120" //~存数据钝化旉
timeToLiveSeconds="120" //~存数据的生存时?
overflowToDisk="true" //内存不Ӟ是否启用盘~存
/>
</ehcache>
之后在映文件中指定各个映射实体的cache{略
<class name=" org.hibernate.sample.TUser" .... >
<cache usage="read-write"/>
....
<set name="addresses" .... >
<cache usage="read-only"/>
....
</set>
</class>
*****************************************************
Query.list()跟Query.iterate()的不同:
对于query.list()L通过一条sql语句获取所有记?然后其dQ填入pojoq回;
但是query.iterate()Q则是首先通过一条Select SQL 获取所有符合查询条件的记录?
idQ再对这个id 集合q行循环操作Q通过单独的Select SQL 取出每个id 所对应的记
录,之后填入POJO中返回?
也就是说Q对于list 操作Q需要一条SQL 完成。而对于iterate 操作Q需要n+1
条SQL。,listҎ不会从Cache中读取数据。iterator却会?
24.ThreadLocal:它会为每个线E维护一个私有的变量I间。实际上Q?
其实现原理是在JVM 中维护一个MapQ这个Map的key 是当前的线E对象,而value则是
U程通过ThreadLocal.setҎ保存的对象实例。当U程调用ThreadLocal.getҎӞ
ThreadLocal会根据当前线E对象的引用Q取出Map中对应的对象q回?
q样QThreadLocal通过以各个线E对象的引用作ؓ区分Q从而将不同U程的变量隔d
来?
25.Hibernate官方开发手册标准示?
public class HibernateUtil {
private static SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new
Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException(
"Configuration problem: " + ex.getMessage(),
ex
);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException
{
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
26.通过filter实现session的重用:
public class PersistenceFilter implements Filter
{
protected static ThreadLocal hibernateHolder = new ThreadLocal();
public void doFilter(ServletRequest request, ServletResponse
response, FilterChain chain)
throws IOException, ServletException
{
hibernateHolder.set(getSession());
try
{
…?
chain.doFilter(request, response);
…?
}
finally
{
Session sess = (Session)hibernateHolder.get();
if (sess != null)
{
hibernateHolder.set(null);
try
{
sess.close();
}
catch (HibernateException ex) {
throw new ServletException(ex);
}
}
}
}
……}
27.Spring的参数化事务理功能相当强大Q笔者徏议在ZSpring Framework的应?
开发中Q尽量用容器管理事务,以获得数据逻辑代码的最佛_L?
public class UserDAO extends HibernateDaoSupport implements IUserDAO
{
public void insertUser(User user) {
getHibernateTemplate().saveOrUpdate(user);
}
}
上面的UserDAO实现了自定义的IUserDAO接口Qƈ扩展了抽象类Q?
HibernateDaoSupport
HibernateSupport实现了HibernateTemplate和SessionFactory实例的关联?
HibernateTemplate对Hibernate Session操作q行了封装,?
HibernateTemplate.executeҎ则是一装机制的核?
*在spring的配|文仉Q移植了整个hibernate.cfg.xml的内宏V?/P>