??xml version="1.0" encoding="utf-8" standalone="yes"?> 分钟Q?~59Q?/font> 时Q?~23Q?/font> 天(月)(j)Q?~31Q但是你需要考虑你月的天敎ͼ(j) 月(0~11Q?/font> 天(星期Q(1~7 1=SUN ?SUNQMONQTUEQW(xu)EDQTHUQFRIQSATQ?/font> 7.q䆾Q?970Q?099Q?br />
0 0 10,14,16 * * ? 每天上午10点,下午2点,4?br />
0 0/30 9-17 * * ??? 朝九(ji)晚五工作旉内每半小?br />
0 0 12 ? * WED 表示每个星期三中?2?/font> 有些子表辑ּ能包含一些范围或列表 例如Q子表达式(天(星期Q?/strong>Q可以ؓ(f) “MON-FRI”Q?#8220;MONQW(xu)EDQFRI”Q?#8220;MON-WED,SAT” “*”字符代表所有可能的?/font> 因此Q?#8220;*”在子表达式(?/strong>Q里表示每个月的含义Q?#8220;*”在子表达式(天(星期Q?/strong>Q表C星期的每一?/font> ? “/”字符用来指定数值的增量 例如Q在子表辑ּQ分钟)(j)里的“0/15”表示从第0分钟开始,?5分钟 ?????? ? 在子表达式(分钟Q里?#8220;3/20”表示从第3分钟开始,?0分钟Q它?#8220;3Q?3Q?3”Q的含义一?/font> ?个子表达式其中之一被指定了(jin)g后,Z(jin)避免冲突Q需要将另一个子表达式的D?#8220;Q?#8221; ? “L” 字符仅被用于天(月)(j)和天Q星期)(j)两个子表辑ּQ它是单?#8220;last”的羃?/font> 但是它在两个子表辑ּ里的含义是不同的?/font> 在天Q月Q子表达式中Q?#8220;L”表示一个月的最后一?/font> 在天Q星期)(j)自表辑ּ中,“L”表示一个星期的最后一天,也就是SAT 如果?#8220;L”前有具体的内容,它就h其他的含义了(jin) 例如Q?#8220;6L”表示q个月的倒数W6天,“QRQL”表示q个月的最一个星期五 注意Q在使用“L”参数Ӟ不要指定列表或范_(d)因ؓ(f)q会(x)D问题 它有两种配置方式OpenSessionInViewInterceptorOpenSessionInViewFilter(具体参看SpringSide)web.xmlapplication.xml Open Session In Viewrequestsessionthreadhibernate sessionopensessionrequestViewPOlazy loading ${ company.employees }View FilterdoFilterInterceptorpostHandlesession
OpenSessionInViewFilter配置 很多人在使用OpenSessionInViewq程中提?qing)一个错误:(x) 看看OpenSessionInViewFilter里的opensessionҎ(gu) 可以看到OpenSessionInViewFilter在getSession的时??x)把获取回来的session的flush mode 设ؓ(f)FlushMode.NEVER。然后把该sessionFactoryl定到TransactionSynchronizationManagerQrequest的整个过E都使用同一个sessionQ在hq后再接除该sessionFactory的绑定,最?span class="me1">closeSessionIfNecessary 也即是,如果有不是readOnly的transaction可以由Flush.NEVER转ؓ(f)Flush.AUTO,拥有insert,update,delete操作权限Q如果没有transactionQƈ且没有另外h为地设flush model的话Q则doFilter的整个过E都是Flush.NEVER。所以受transaction保护的方法有写权限,没受保护的则没有?/p>
采用spring的事务声?使方法受transaction控制 对于上例Q则以save,add,update,remove开头的Ҏ(gu)拥有可写的事务,如果当前有某个方法,如命名ؓ(f)importExcel()Q则因没有transaction而没有写权限Q这时若Ҏ(gu)内有insert,update,delete操作的话Q则需要手动设|flush model为Flush.AUTO,?/p>
管Open Session In View看v来还?sh)错Q其实副作用不少。看回上面OpenSessionInViewFilter的doFilterInternalҎ(gu)代码Q这个方法实际上是被父类的doFilter调用的,因此Q我们可以大U了(jin)解的OpenSessionInViewFilter调用程: request(h)->open sessionq开始transaction->controller->View(Jsp)->l束transactionqclose session. 一切看h很正,其是在本地开发测试的时候没出现问题Q但试想下如果流E中的某一步被d的话Q那在这期间connection׃直被占用而不释放。最有可能被d的就是在写Jspq步Q一斚w可能是页面内容大Qresponse.write的时间长Q另一斚w可能是网速慢Q服务器与用户间传输旉久。当大量q样的情况出现时Q就有连接池q接不Q造成面假死现象?/p>
Open Session In View是个双刃剑,攑֜公网上内容多量大的|站h用?/p>
hibernate open session in view 抛出异常解决Ҏ(gu) 在用open-session-in-view的时候,如果使用不当Q有可能抛出两种异常按顺序依ơؓ(f)
U(0~59Q?/font>
其中每个元素可以是一个??),一个连l区?9-12),一个间隔时?8-18/4)(/表示每隔4时),一个列?1,3,5),通配W。由?月䆾中的日期"?星期中的日期"q两个元素互斥的,必须要对其中一个设|?.
“Q?#8221;字符仅被用于天(月)(j)和天Q星期)(j)两个子表辑ּQ表CZ指定?/font>
]]>
]]><beans>
<bean name="openSessionInViewInterceptor" class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
<property name="mappings">
...
</property>
</bean> ...
</beans>
<web-app>
...
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </filter-class>
<!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
...
</web-app>
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.NEVER);
return session;
}
<bean id="baseTransaction" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"/>
<property name="proxyTargetClass" value="true"/>
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="userService" parent="baseTransaction">
<property name="target">
<bean class="com.phopesoft.security.service.impl.UserServiceImpl"/>
</property>
</bean>
session.setFlushMode(FlushMode.AUTO);
session.save(user);
session.flush();
1QNonUniqueObjectException
2Q在配合spring使用的时候会(x)可能?x)抛出org.springframework.dao.InvalidDataAccessApiUsageException
先说1Q这个异常的抛出原因和解军_法见q里Q?br />
javaeye上有?jin)很好的事?http://www.javaeye.com/topic/11581
解决办法可以用mergeQ也可以别的办法?br />
出现的原因,可以参考一下我前边的文章中merge和update的区别的内容?br />
http://www.aygfsteel.com/dreamstone/archive/2007/07/29/133071.html
2的解军_法:(x)在这?br />
springside的一文章做?jin)详l说?br />
http://calvin.blog.javascud.org/post/46.htm
好了(jin)Q现在问题解决了(jin)Q但关于open-session-in-view的用还有一些探讨,是否应该使用Q用的好处与坏处?br />
见这两篇jdon上的文章:
http://www.jdon.com/jivejdon/thread/22374.html
http://www.jdon.com/jivejdon/thread/28955.html
]]>
]]>
举例Q假设有在一个应用系l中Q有一个共享的数据必须被ƈ发同时访问,首先Q将q个数据装在数据对象中Q称为Data ClassQ同Ӟ有多个讉Kc,专门用于在同一时刻讉Kq同一个数据对象?br />
Z(jin)完成上述q发讉K同一资源的功能,需要引入锁Lock的概念,也就是说Q某个时刻,当有一个访问类讉Kq个数据对象Ӟq个数据对象必须上锁LockedQ用完后q卌锁unLockedQ再供其它访问类讉K?br />
使用传统的编E习(fn)惯,我们?x)创Z个抽象类Q所有的讉Kcȝ(h)承这个抽象父c,如下Q?br />
abstract class Worker{
abstract void locked();
abstract void accessDataObject();
abstract void unlocked();
}
~点Q?/font>
* accessDataObject()Ҏ(gu)需要有“?#8221;状态之cȝ相关代码?br /> * Java只提供了(jin)单(h)承,因此具体讉Kcd能(h)承这个父c,如果具体讉Kc还要(h)承其它父c,比如另外一个如Worker的父c,无法方便实现?br /> * 重用被打折扣Q具体访问类因ؓ(f)也包?#8220;?#8221;状态之cȝ相关代码Q只能被重用在相x(chng)“?#8221;的场合,重用范围很窄(jing)?/font>
仔细研究q个应用?#8220;?#8221;Q它其实有下列特性:(x)
* “?#8221;功能不是具体讉Kcȝ首要或主要功能,讉KcM要功能是讉K数据对象Q例如读取数据或更改动作?nbsp;
“?#8221;行ؓ(f)其实是和具体讉Kcȝ主要功能可以独立、区分开来的
“?#8221;功能其实是这个系l的一个纵向切面,涉及(qing)许多cR许多类的方法?nbsp;
因此Q一个新的程序结构应该是x(chng)pȝ的纵向切面,例如q个应用?#8220;?#8221;功能Q这个新的程序结构就是aspectQ方面)(j)
在这个应用中Q?#8220;?#8221;斚wQaspectQ应该有以下职责Q?br />
提供一些必备的功能Q对被访问对象实现加锁或解锁功能。以保证所有在修改数据对象的操作之前能够调用lock()加锁Q在它用完成后Q调用unlock()解锁?br />
AOP应用范围
很明显,AOP非常适合开发J2EE容器服务器,目前JBoss 4.0正是使用AOP框架q行开发?br />
具体功能如下Q?br />
Authentication 权限
Caching ~存
Context passing 内容传?br />
Error handling 错误处理
Lazy loading 懒加?br />
Debugging 调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence 持久?br />
Resource pooling 资源?br />
Synchronization 同步
Transactions 事务
AOP有必要吗Q?br />
当然Q上q应用范例在没有使用AOP情况下,也得C(jin)解决Q例如JBoss 3.XXX也提供了(jin)上述应用功能Q但是没有用AOP?br />
但是Q用AOP可以让我们从一个更高的抽象概念来理解Y件系l,AOP也许提供一U有价值的工具。可以这么说Q因Z用AOPl构Q现在JBoss 4.0的源码要比JBoss 3.XҎ(gu)理解多了(jin)Q这对于一个大型复杂系l来说是非常重要的?br />
从另外一个方面说Q好像不是所有的人都需要关?j)AOPQ它可能是一U架构设计的选择Q如果选择J2EEpȝQAOPx(chng)的上q通用斚w都已l被J2EE容器实现?jin),J2EE应用pȝ开发者可能需要更多地x(chng)行业应用斚waspect?/font>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="mappingResources">
<list>
<value>org/appfteaching/model/TArticleclass.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
</bean>
2.其次,在src目录下的ehcache.xml中配|如下信?如果是默认ehcache.xml则会(x)?lt;cache name="sampleCache1">?lt;cache name="sampleCache2>",L)
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="4200"
overflowToDisk="true"
/>
<!-- Sample cache named sampleCache2
This cache contains 1000 elements. Elements will always be held in memory.
They are not expired. -->
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/>
3.你要缓存的model加进ehcache.xml?/p>
<cache name="org.appfteaching.model.TArticleclass"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="100"
timeToLiveSeconds="4200"
overflowToDisk="true"
/>
4.最后一?在TArticleclass.hbm.xml里加?/p>
<cache usage="read-write"/>
启动Tomcat,如发现如下错?/p>
Could not find configuration [org.hibernate.cache.UpdateTimestampsCache]; using defaults.
Could not find configuration [org.hibernate.cache.StandardQueryCache]; using defaults.
则是W二步没有做,加上卛_.配置完毕
配置非常单,在web.xml中增加:(x) <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> 或:(x) <servlet> <servlet-name>context</servlet-name> <servlet-class> org.springframework.web.context.ContextLoaderServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> |
通过以上配置QW(xu)eb容器?x)自动加?WEB-INF/applicationContext.xml初始?
ApplicationContext实例Q如果需要指定配|文件位|,可通过context-param加以指定Q?
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myApplicationContext.xml</param-value>
</context-param>
配置完成之后Q即可通过
WebApplicationContextUtils.getWebApplicationContextҎ(gu)在Web应用中获取ApplicationContext引用?
如:(x)ApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext();
LoginAction action=(LoginAction)ctx.getBean("action");
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessagePreparator;
public class SpringMail {
public static void main(String[] args) throws Exception {
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"applicationContext.xml");
JavaMailSender sender = (JavaMailSender) ctx.getBean("mailSender");
SpringMail springMail = new SpringMail();
//试发送只有文本信息的单测?br> springMail.sendTextMail(sender);
//试发送带附g的邮?br> springMail.sendMimeMessage(sender);
}
/** *//**
* 试发送只有文本信息的单测?br> * @param sender 邮g发送器
* @throws Exception
*/
private void sendTextMail(JavaMailSender sender) throws Exception {
SimpleMailMessage mail = new SimpleMailMessage();
mail.setTo("superman_wshm@126.com");
mail.setFrom("superman_wshm@126.com");
mail.setSubject("test by amigo");
mail.setText("spring Mail的简单测?);
sender.send(mail);
System.out.println("成功发送文本文Ӟ");
}
/** *//**
* 发送带附g的邮?br> * @param sender 邮g发送器
* @throws Exception
*/
private void sendMimeMessage(final JavaMailSender sender) throws Exception {
//附g文g集合
final List files = new ArrayList();
MimeMessagePreparator mimeMail = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws MessagingException {
mimeMessage.setRecipient(Message.RecipientType.TO,
new InternetAddress("superman_wshm@126.com"));
mimeMessage.setFrom(new InternetAddress("superman_wshm@126.com"));
mimeMessage.setSubject("Spring发送带附g的邮?, "gb2312");
Multipart mp = new MimeMultipart();
//向Multipartd正文
MimeBodyPart content = new MimeBodyPart();
content.setText("内含spring邮g发送的例子Q请查收!");
//向MimeMessagedQMultipart代表正文Q?br> mp.addBodyPart(content);
files.add("com/action/SpringMail.java");
files.add("applicationContext.xml");
//向Multipartd附g
Iterator it = files.iterator();
while(it.hasNext()) {
MimeBodyPart attachFile = new MimeBodyPart();
String filename = it.next().toString();
FileDataSource fds = new FileDataSource(filename);
attachFile.setDataHandler(new DataHandler(fds));
attachFile.setFileName(fds.getName());
mp.addBodyPart(attachFile);
}
files.clear();
//向MultipartdMimeMessage
mimeMessage.setContent(mp);
mimeMessage.setSentDate(new Date());
}
};
//发送带附g的邮?br> sender.send(mimeMail);
System.out.println("成功发送带附g邮g!");
}
}
<beans>
Spring配置文gapplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host">
<value>smtp.126.com</value>
</property>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.timeout">25000</prop>
</props>
</property>
<property name="username">
<value>superman_wshm</value>
</property>
<property name="password">
<value>******</value>
</property>
</bean>
</beans>
刚才发现一bugQ当附g名ؓ(f)中文Ӟ?x)出C文ؕ码问题,对sendMimeMessageҎ(gu)q行?jin)部分修改,如下Q?br> sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
files.add("src/SpringMail.java");
files.add("src/applicationContext.xml");
files.add("src/谢星?xml");
//向Multipartd附g
Iterator it = files.iterator();
while (it.hasNext())
{
MimeBodyPart attachFile = new MimeBodyPart();
String filename = it.next().toString();
FileDataSource fds = new FileDataSource(filename);
attachFile.setDataHandler(new DataHandler(fds));
attachFile.setFileName("=?GBK?B?"+enc.encode(fds.getName().getBytes())+"?=");
mp.addBodyPart(attachFile);
}
]]>
(tng) (tng) (tng) (tng) (tng) (tng)MVC框架如Struts、WebworkQ都在Servlet的基上创Z(jin)一个自ql对I间Q在自己的空间里定义MVC世界和规则。无个世界定义得是否漂亮Q程序员都有一个学?fn)世界的q程?/p>
(tng) (tng) (tng) (tng) (tng) 而Spring MVC则完全保留着Servlet概念中的requestQresponse和sessionQƈ没有强制建立一个自q概念模型Q当?dng)他也有很烂的SimpleFormControllerQ但你完全可以把它踢在一旁不)(j)Q也不强刉要FormBean和一堆XML定义?/p>
(tng) (tng) (tng) (tng) (tng) 同时Q它透明完成?jin)与Spring的集成,Multi-action的派发,提供?jin)绑定request数据用的binder{基本API?/p>
(tng) (tng) (tng) (tng) (tng) (tng)所以,如果想简单,使用Spring MVC的原始Ş态是一个很好的Q类gRoR中ActionPack的方案?/p>
(tng) (tng) (tng) (tng) (tng) 推荐使用一个Controller响应一l相兛_作的MultiActionController。同Ӟ虽然一点不喜欢FormController定义的概忉|型,但还是不影响发挥拿来MQ在共性比较明昑台管理模块,定义MultiActionFormControllerQ自动完成某些共同的Form程?/p>
(tng) (tng) (tng) (tng) (tng) 你还是很喜欢WebWork?好在我们也提供了(jin)sampleQ见2.4 WebWork ?/p>
(tng) (tng) (tng) (tng) (tng) 也许Q所有程序员都先放下自己框架里的概念模型Q还原回一个JSP/ServletE序员的角度Q思考一个JSP/Servlet框架需要的功能?/p>
(tng) (tng) (tng) (tng) (tng)0. (tng)配置文g
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Spring的配|文仉认ؓ(f)WEB-INF/xxxx-servelet.xml?/p>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 其中xxx为web.xml中org.springframework.web.servlet.DispatcherServlet的servlet-name?/p>
(tng) (tng) (tng) (tng) 1. 与Spring集成?qing)IOC
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 天然兮,由DispatcherServlet完成?/p>
(tng) (tng) (tng) (tng) (tng) 2. Action?qing)Multi-Action 分发
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Spring按照配|文件定义的URLQMapping到具体Controllerc,再根据URL里的action= xxx或其他参敎ͼ利用反射调用Controller里对应的ActionҎ(gu)?/p>
(tng) (tng) (tng) (tng) (tng) 3. 输入数据l定
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Spring提供Binder 通过名字的一一对应反射l定PojoQ也可以直接从request.getParameter()取数据?/p>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 如果没有另外加入框架装Q需要手工调用Binder.
(tng) (tng) (tng) (tng) (tng) 4. 输入数据验证
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Sping 提供?a >Validator接口Q而Spring Moduleq整合了(jin)Commons-Validaor ?/p>
(tng) (tng) (tng) (tng) (tng) 5. l果数据攑֛View
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 有个ModelAndView的概念,代表?jin)返回的View名及(qing)数据(ModelQ一个Map)。可以用modelAndView.addObject()攑օ数据。当?dng)也可以直接request.setAttribute()?/p>
(tng) (tng) (tng) (tng) (tng) 6. Interceptor
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) AOP概念Q其实Servlet里面早有Filter概念Q不qInteceptor可以更灵zȝMappingQ另提供postHandle的插入点
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) preHandle() handler开工之前?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)postHandle() hander开工之后,但DispatchServletq没有渲染页面?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)afterCompletion() 一切完工之后?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
(tng) (tng) (tng) (tng) (tng) 7. RedirectQForward面?qing)Token防止重复提交?/strong>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Spring提供 "redirect:index.jsp", "forward:index.jsp"q样的简写?/p>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) Spring Simple Form提供?jin)防止重复提交的机制?/p>
(tng) (tng) (tng) (tng) (tng) 8. 如果想直接编写Responseq回字符? 而不是返回一个View
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) 函数的q回cd设ؓ(f)voidQ用ss装?rendText(response,String text)函数?/p>
<bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">
(tng) (tng) (tng) (tng) (tng) (tng) (tng) <property name="paramName">
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <value>method</value>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) </property>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) <property name="defaultMethodName">
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <value>index</value> (tng) (tng) (tng) (tng) (tng) (tng) (tng) </property> </bean>
以上配置按xxx.do?method= list 调用controller的list()Ҏ(gu)
不过q要争取早日改ؓ(f)Web2.0式的写法./book/list.htm 要优?sh)?book.do?action= list?/p>
其余配置和其他Spring MVC配置差不多,L(fng)bookstore-servlet.xmlQ留意下面几个关键节?br /><bean id="exceptionResolver">
<bean id="methodNameResolver">
<bean id="viewResolver">
<bean id="urlMapping">(留意最新的urlMapping写语?)
(tng) (tng) (tng)l承于Spring的MultiActionController, 对其作了(jin)量扩展--主要是对数据l定的扩展,q加?jin)一个SaveMessage函数?/p>
(tng) (tng) (tng)1.Ҏ(gu)据绑定的扩展Q?/strong>
(tng) (tng) a.InitBinder() 初始化BinderQ注册日期类q允许数字类为空?/p>
(tng) (tng) (tng)b.对Bind and Validate函数的再包装
(tng) (tng)本来Spring已有bind函数完成bind and validate, 但这个函C来没有用BindException作返回D是抛出一个ServletException只好自己另外实现一个bindObject()函数?/p>
(tng) (tng) (tng)c.另外E稍扩展?jin)一些函C其更好用?/p>
2.SaveMessage():
如果是redirect的关p,message信息攑֜request.attribute()׃(x)丢失QSaveMessage()其攑֜session?br /> (tng)配合messageFilterQ在渲染面前,把它从session又移回request?
(tng) (tng)Spring MVC中的SimpleFormController中的交互机制有值得参考的部分Q但其只有一个onSubmit函数不能很好的表达CRUD的语义,所以将两者结合成Multi-ActionFormController是比较好的方法。通过U定命名Q在基类实现l(f)ist()Qcreate(){函数和默认程Q而在子类实现onList(),onCreate()函数?/p>
(tng) (tng) 目前只是初步l合两者,q有很大的改q空间?/p>
(tng) (tng)参考了(jin)RoR中的命名。BaseManageControllerx(chng)照此命名定义基类?/p>