Spring4.1.1_SpringMVC4_Hibernate4.3.6_Proxool0.9.1_Quartz2.2.1_Jackson2.5.0_Plupload2.1.2集成
----------------------------------------------------------------------------------------------------------
2015-01-15更新:
项目中使用SpringMVC,需要做用户不登录就被系统拦截请求的功能,走了不少弯路,现在分享一下:
【拦截请求】
1、如果使用自定义拦截器拦截请求,建议使用.do的后缀,而非/的后缀,因为自定义的拦载器会拦截静态资源,即使写了<mvc:resources>标签也没有用。。。不知道是不是Spring设计上的错误。。。
2、如果非要使用/的后缀来拦截,可以在web.xml中配置default的资源servlet,具体写法网上很多,但是要注意一点,每个应用服务器的写法不一样,比如tomcat与weblogic就不同。
3、还是那句话,改成.do的后缀吧,这样有两个优点:避免了自定义拦截器拦截静态资源、不用再写<mvc:resources>标签了。。。哎,打破了我之前写的那些例子,抱歉。
【拦截JSP直接访问】
1、SpringMVC无法直接对JSP进行拦截,除非使用/后缀配置自定义拦截器,但又会造成如上的问题。
2、建议在web.xml文件中使用Filter的方式来对JSP进行拦截,但要注意Filter必须在Spring加载前执行。这里推荐geloin写的博文:http://blog.csdn.net/geloin/article/details/7445441
----------------------------------------------------------------------------------------------------------
2015-01-07更新:
SpringMVC中的StringHttpMessageConverter默认编码是ISO-8859-1,如果在使用@ResponseBody来传递JSON数据时,如果JSON数据是一个String对象,则会出现乱码。。。
针对此问题,网上一大堆解决方法,什么重写方法都没用,最后,给大家带来亲测成功的方法:
<!-- 使用注解来配置Spring MVC,这里处理了Spring4.0中StringHttpMessageConverter带来的乱码问题 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
-----------------------------------------------------------------------------------------------------------
最近正在做一个项目,一个从头做起的项目,项目框架由我自己定。由于以前一直使用Struts2、Spring3、Hibernate3的MVC框架,现在想改改味口,去探索一下未知领域,增强自己的本事,决定学习SpringMVC。
但既然是全新的学习之旅,肯定要用最新的框架资源吧,于是下载了Spring4.1.1和Hibernate4.3.6。。学习了几天,发现新框架网上的资源实在是少得可怜,因此我自己写一篇博客,与广大程序猿交流交流,以下内容有更好的实现方式的话,欢迎大家灌水哦~
不用不知道,一用吓一跳。。。Struts2原来是个非常复杂的玩意,比起SpringMVC,个人感觉易用性上甩了Struts2几条街了,再加上Webwork公司对Struts更新缓慢,估计以后我再也不会去用Struts了。。。SpringMVC与Spring的集成度直接让开发过程变得十分流畅,先粘上相关的XML配置文件:
【web.xml】
<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 使用SpringMVC load-on-startup代表优先启动--><servlet><servlet-name>spring</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>spring</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!-- 让Action加载SpringIOC的监听器,默认查询/WEB-INF/applicationContext.xml --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 指定配置文件位置 --><context-param><param-name>contextConfigLocation</param-name><!-- <param-value>/WEB-INF/applicationContext-*.xml, classpath*:applicationContext-*.xml</param-value> --><param-value>classpath:beans.xml</param-value></context-param><!-- 使用Spring的编码过滤器解决乱码问题,在Struts2中不在此处配置; forceEncoding表是是否强制转码 --><filter><filter-name>springEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>springEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置Hibernate的Session在VIEW打开后再关闭,Filter有先后顺序,要注意 --><filter><filter-name>openSessionInView</filter-name><filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class><init-param><param-name>sessionFactoryBeanName</param-name><param-value>sessionFactory</param-value></init-param><init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>flushMode</param-name> <param-value>AUTO</param-value> </init-param></filter><filter-mapping><filter-name>openSessionInView</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- <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> --></web-app>
【beans.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:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 使用Spring的Annotation的配置 --> <context:annotation-config/> <!-- 除了Controller,Bean全部自动到包里面找 --> <context:component-scan base-package="com.qianye.terny.springmvc"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 开启占位符来配置Properties文件的值 --><bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <value>classpath:jdbc.properties</value> </property></bean><!-- 使用Proxool来配置JDBC --><bean id="proxoolDataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource"><property name="alias"><value>mysql</value></property><property name="driver"><value>${driverClassName}</value></property><property name="driverUrl"><value>${url}</value></property><property name="user"><value>${username}</value></property><property name="password"><value>${password}</value></property><!-- 最大连接数(默认5个),超过了这个连接数,再有请求时,就排在队列中等候 --><property name="maximumConnectionCount"><value>20</value></property><!-- 最小连接数(默认2个)--><property name="minimumConnectionCount"><value>3</value></property><!-- 最少保持的空闲连接数(默认2个) --><property name="prototypeCount"><value>3</value></property><!-- 是否记录数据库的每一步操作 --><property name="trace"><value>true</value></property><!-- 是否同时记录多个STUFF,会产生多个日志 --><property name="verbose"><value>true</value></property><!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 默认30秒 --><property name="houseKeepingSleepTime"><value>90000</value></property><!-- 保持数据库连接所使用的SQL语句 --><property name="houseKeepingTestSql"><value>SELECT CURRENT_DATE</value></property><!-- 在使用之前测试 --><property name="testBeforeUse"><value>true</value></property><property name="testAfterUse"><value>true</value></property></bean> <!-- Hibernate4 Annotation配置,XML配置在文档中有 --><bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"><property name="dataSource" ref="proxoolDataSource"/><!-- 这里是手动添加Hibernate的Entity类<property name="annotatedClasses"><list><value>com.terny.spring.model.User</value><value>com.terny.spring.model.Log</value></list></property>--><!-- 直接扫描这个包里面的Entity类,建议使用 --><property name="packagesToScan"><list><value>com.qianye.terny.springmvc.model</value></list></property><!-- Hibernate配置中的各种属性,具体请查询HinbernateDOC文档 --><property name="hibernateProperties"><props><prop key="hibernate.dialect">${hibernateDialect}</prop><prop key="hibernate.show_sql">${hibernateShowSQL}</prop><!-- 是否使用CGLIB动态代理对象(小而快,推荐,需要CGLIB包,建议配合Proxool使用) --><prop key="hibernate.bytecode.use_reflection_optimizer">true</prop><!-- 指定Hibernate在何时释放JDBC连接 --> <prop key="hibernate.connection.release_mode">auto</prop></props></property></bean> <!-- 使用Hibernate模板,极大简化Hibernate的开发 --> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate4.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 自动Hibernate事务处理,自动Rollback,自动TryCatch --> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"><!-- 把SessionFactory注给Tx --><property name="sessionFactory" ref="sessionFactory" /></bean> <!-- 以下是使用Quartz来进行任务自动处理 --> <!-- 对任务进行装配执行哪一个类 --> <bean id="remindTask" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- 使Job类持久化,否则会无法装载触发器 --> <property name="Durability" value="true"/><property name="jobClass" value="com.qianye.terny.springmvc.job.Jobs"></property> </bean> <!-- 简单触发器bean,类似定时器任务 --> <bean id="remindTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <!-- 运行哪一个任务,注入进来 --> <property name="jobDetail" ref="remindTask" /> <!-- 多少毫秒执行一次 --> <property name="repeatInterval" value="5000" /> <!-- 第一次执行时延迟多少毫秒 --> <property name="startDelay" value="10000" /> </bean> <!-- 配置调度工厂,核心 --> <bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="remindTrigger"/> </list> </property> <!-- 在Quartz中无法直接使用Spring管理的Bean,在这里注入 --> <property name="schedulerContextAsMap"> <map> <!-- spring 管理的service需要放到这里,才能够注入成功 --> <description>schedulerContextAsMap</description> <entry key="userService" value-ref="userServiceImpl"></entry> </map> </property> </bean> <!-- 配置事务管理 --> <tx:annotation-driven transaction-manager="txManager"/> <!-- 配置Transcation 自动处理,属于切面编程 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="exist*" read-only="true"/> <tx:method name="get*" read-only="true"/> <tx:method name="add*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 配置拦截方法,用于解决Quartz中找不到CurrentSession的问题 --> <aop:config> <aop:pointcut expression="execution(public * com.qianye.terny.springmvc.service..*.*(..))" id="userService"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="userService"/> </aop:config> <!-- 手动进行动态代理切面 --> <!-- 定义切面类的Bean,相当于@Component --> <!--<bean id="logInterceptor" class="com.terny.spring.aop.LogInterceptor"></bean> --><!-- 开始配置 --> <!--<aop:config> --><!-- 定义PointCut全局变量 --> <!--<aop:pointcut id="daoImplCut" expression="execution(* com.terny.spring.dao..*.*(..))"/> --><!-- 将切面定义到相应的BEAN上,相当于@Aspect --> <!--<aop:aspect id="logAspect" ref="logInterceptor"> --><!-- 定义PointCut局部变量 --> <!--<aop:pointcut id="serviceImplCut" expression="execution(* com.terny.spring.service..*.*(..))"/> --><!-- 定义Advice, method是类LogInterceptor中的 --> <!--<aop:before method="beforeStart" pointcut-ref="daoImplCut"/> <aop:after-returning method="after" pointcut="execution(* com.terny.spring.dao..*.*(..))"/> <aop:after-throwing method="afterThrowing" pointcut-ref="serviceImplCut" throwing="ex"/> </aop:aspect> </aop:config>--></beans>
【spring-servlet.xml】<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 使用注解来配置Spring MVC --> <mvc:annotation-driven/> <!-- 扫描目录中的Controller --> <context:component-scan base-package="com.qianye.terny.springmvc.controller" /> <!-- 静态资源访问,防止图片等文件被拦截 ,若使用.do的Controller,则不必考虑--> <mvc:resources location="/image/" mapping="/image/**"></mvc:resources> <mvc:resources location="/images/" mapping="/images/**"></mvc:resources> <mvc:resources location="/js/" mapping="/js/**"></mvc:resources> <mvc:resources location="/css/" mapping="/css/**"></mvc:resources> <mvc:resources location="/theme/" mapping="/theme/**"></mvc:resources> <mvc:resources location="/back/" mapping="/back/**"></mvc:resources> <!-- Spring MVC视图分解器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean><!-- 使用Jackson2处理JSON数据转换的 --><!-- 为了处理返回的JSON数据的编码,默认是ISO-88859-1的,这里把它设置为UTF-8,解决有乱码的情况 --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> </list> </property></bean><!-- SpringMVC中的上传文件配置,在这里配置上传文件大小限制不够灵活,建议使用jQuery框架来配置,这样可以节省服务器的压力 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="defaultEncoding" value="utf-8"/><property name="maxUploadSize" value="10485760000"/><property name="maxInMemorySize" value="40960"/></bean> <!-- Spring MVC的单Controller XML配置 <bean name="/xmlconfig" class="com.qianye.terny.springmvc.controller.XmlController"></bean>--></beans>
【jdbc.properties】driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/study?characterEncoding=utf8username=rootpassword=adminhibernateDialect=org.hibernate.dialect.MySQL5DialecthibernateShowSQL=true
这些配置文件解释我就不说了,全部在注释中,花了我很本心血,查询了很多资料才搞定的,先来说说Hibernate吧。Hibernate问题汇总
1、本次我不再使用HibernateTemplate来进行数据处理,原因很简单。。。太不原生态了,虽然简化了Hibernate的开发,但是如果想使用NativeSQL或者复杂的HQL查询方式的话,要重写的接口很多,而且MyEclipse还对部分代码搞一堆黄色的下标线,太难看了,推荐使用SessionFactory来获取CurrentSession。
2、使用Proxool来管理连接池,原因就在于如果才时间没有数据请求,MySQL数据库会释放所有链接,就像进行了休眠一样。。。用Proxool可以轻松保持连接。。。当然,使用Quartz也是可以的。Proxool还有很多强大的配置,这些在Hibernate中设置比较麻烦,所以果断Proxool吧。
3、与Hibernate3不同,Hibernate4中主推Annotation注解配置Model层,并且可以设置MySQL5的HQL方言。来看看一个Model层中的Entity吧:
【User.java】
package com.qianye.terny.springmvc.model;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="t_user")public class User {@Id@GeneratedValueprivate int id;@Columnprivate String name;@Columnprivate int age;@Columnprivate int display = 1;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getDisplay() {return display;}public void setDisplay(int display) {this.display = display;}}
4、可能有些朋友会说,注解应该要加到get方法上,这是以前某老师说的。。但是现在的情况不同,集成SpringMVC后,SpringMVC中的POJO传值方式会使用到Entity中的set/get方法,如果上面有注解,SpringMVC就不认了。。。这个问题困扰了我好久才解决。。。Spring问题汇总
1、听说Spring4比起Spring3多了一个REST风格的支持,但是对我来说,风格已经固定,而且从Struts跳到SpringMVC,我已经是风格大变了。。。所以,这个REST以后再研究吧。
2、Spring4对Hibernate4的兼容大大提高,增加了Hibernate4专用的HibernateTemplate,但还是由于原生态问题,不推荐使用。。另外,Hibernate3的HibernateTemplate.find()方法是不需要进行范形转换的,在Spring4中就行不通了,大家要注意。
3、加几张DAO与Service的代码吧:
【UserDAOImpl.java】
package com.qianye.terny.springmvc.dao.impl;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.qianye.terny.springmvc.dao.UserDAO;import com.qianye.terny.springmvc.model.User;@Componentpublic class UserDAOImpl implements UserDAO {@Autowiredprivate SessionFactory sessionFactory;@Overridepublic void addUser(User u) {// TODO Auto-generated method stubsessionFactory.getCurrentSession().save(u);sessionFactory.getCurrentSession().flush();}@Overridepublic User getUserById(int id) {// TODO Auto-generated method stubreturn (User) sessionFactory.getCurrentSession().get(User.class, id);}}
【UserServiceImpl.java】package com.qianye.terny.springmvc.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import com.qianye.terny.springmvc.dao.UserDAO;import com.qianye.terny.springmvc.model.User;import com.qianye.terny.springmvc.service.UserService;@Componentpublic class UserServiceImpl implements UserService {@Autowiredprivate UserDAO userDAO;@Overridepublic void addUser(User u) {// TODO Auto-generated method stubuserDAO.addUser(u);}@Overridepublic User getUserById(int id) {// TODO Auto-generated method stubreturn userDAO.getUserById(id);}}
SpringMVC问题汇总1、我配置的SpringMVC不是那种*.do的,是直接用/来区分每一个URI的,因此对于静态文件(例如JS、CSS文件)它并不会去区分是否为一个RequestMapping,于是就出现了静态文件无法访问的情况。所以配置一下静态资源的访问即可。。详细配置请参考上面的代码,都是有注释的,不必我过多解释了。
2、在通过form表单传数据时存在乱码问题。。GET方法导致的乱码我知道可以在tomcat里面设置,但是在SpringMVC中居然出现了通过POST方法导致的乱码。。。查了很多资料,需要在web.xml中配置一个Filter来过滤强制转码。。。具体代码在上面也有提到。
3、JSON+AJAX的异步传输非常常用,尤其是在使用了Ext等前端框架的项目中更是必不可少。但是,查阅了不少资料,SpringMVC中从前端传送JSON到后端还算容易,但是从后端传到前端就非常麻烦了,不仅要自己拼接JSON自符串,还要对response对象写数据。就算使用了JSONObject来处理,也还是要对Response写对象。。。后来用到了Jackson2.5.0,这玩意才叫爽嘛,直接对方法写个注解@ResponseBody,让SpringMVC认为此方法返回的对象就是JSON,这才叫方便嘛。。。具体Bean配置请参考上面的代码,若需要完整项目源码,请参考页面下方的链接。
粘一张对比代码,大家看看哪个爽
【使用Jackson与不使用的区别】
//此处为使用AJAX+JSON+POJO的方式来处理数据@RequestMapping("/ajaxLoadUser")public void ajaxLoadUser(User u, HttpServletRequest req, HttpServletResponse res){System.out.println(u.getName());String json = "{\"name\":\""+u.getName()+"\",\"age\":\""+u.getAge()+"\"}";PrintWriter out = null;res.setContentType("application/json");try {out = res.getWriter();out.write(json);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//此处为使用AJAX+JSON+POJO+JACKSON的方式来处理数据@RequestMapping(value="/ajaxAddUser")@ResponseBodypublic Object ajaxAddUser(User u){userService.addUser(u);Map<String, Object> hm = new HashMap<String, Object>();hm.put("user", u);hm.put("flag", "OK");return hm;}
Plupload问题汇总1、Plupload是前端AJAX上传文件的框架,为什么写在这里,是我觉得这个异步上传框架比其它的框架都强大,而且是非常强大,易用性极强。。。不过这么好的东西在网上的资源非常稀少,并且版本过老,大多是2.0以前的版本。在这里,给大家送上福利,查阅了官方API,我写了一个例子,完整代码请下载我的附件,谢谢!
2、Plupload提供了多种运行环境runtime,建议优先使用sliverlight,因为这个环境可以使文件选择过滤器真正的生效,比如我定义的图片文件:jpg/bmp/gif/png与压缩文件:zip/rar,其它的运行环境我都测试过了,没有sliverlight强大。。。。不过第二优先级建议flash和html5吧,因为这两个太常见了。。
3、推荐使用Plupload2,因为网上文档资源稀少,而官方文档大多是在说Plupload2。。。与时俱进,总不会错的。
【upload.jsp】
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><script type="text/javascript" src="js/jquery-2.1.1.min.js" ></script><script type="text/javascript" src="js/plupload2.1.2/plupload.full.min.js" ></script><script type="text/javascript" src="js/plupload2.1.2/i18n/zh_CN.js" ></script><script type="text/javascript">$(function(){var uploader = new plupload.Uploader({runtimes : 'silverlight,html5,flash,html4',//运行环境,按顺序优先加载browse_button : 'pickfiles', //打开文件浏览窗口container: 'container', //哪一个容器max_file_size : '1gb',//最大文件大小,100b, 10kb, 10mb, 1gbchunk_size : '100mb',//分块大小,小于这个大小的不分块url: "file/ajaxLoadFile",//上传地址flash_swf_url : 'js/plupload2.1.2/Moxie.swf',//FLASH控件加载地址silverlight_xap_url : 'js/plupload2.1.2/Moxie.xap',//Sliverlight控件加载地址resize : { width : 320, height : 240, quality : 90 },//如果可以的话压缩图片multi_selection: true,//是否可以多选文件(多文件上传)filters : [{title : "图片文件(jpg,gif,png,jpeg)", extensions : "jpg,gif,png,jpeg"},{title : "压缩文件(zip,rar)", extensions : "zip,rar"}],//文件过滤器init: {PostInit: function(up) {//初始化时$('#filelist').html("已检测到支持的运行环境:"+up.runtime);$('#uploadfiles').get(0).onclick = function() {//给上传按钮绑定点击事件uploader.start();return false;};},FilesAdded: function(up, files) {//选择文件后plupload.each(files, function(file) {$('#filelist').get(0).innerHTML += '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b></div>';});},UploadProgress: function(up, file) {//上传文件时的进度$('#'+file.id).get(0).getElementsByTagName('b')[0].innerHTML = '<span>' + file.percent + "%</span>";},FileUploaded: function(up, file, info){//上传完成后执行服务器的返回信息var response = $.parseJSON(info.response);alert(response.msg);},Error: function(up, err) {//出错时$('#console').get(0).innerHTML += "\nError #" + err.code + ": " + err.message;}}});uploader.init();});</script> </head> <body> <h1>普通非AJAX上传文件</h1> <form id="formMain" action="file/uploadFile" method="post" enctype="multipart/form-data"> 选择文件:<input type="file" name="file"/> <br/> <input type="submit" value="上传"/> </form> <br/> <h1>AJAX上传文件之Plupload2.1.2 上传实例</h1><div id="filelist">你的浏览器不支持上传文件</div><br /><div id="container"> <button id="pickfiles">选择文件</button> <button id="uploadfiles">上传</button></div><br /><pre id="console"></pre> </body></html>
Quartz问题汇总
1、Quartz作为任务调度框架,可以使用项目周期性自动处理各种事务。例如项目每天早上2:00要对数据进行汇总处理。而从Spring3.0以后对Quartz2的支持度会更好。在此我们使用最新的Quartz2.2.1。
2、使用Quartz时,由于加载机制不同,Quartz是不会有WEB request的,导致Quartz中的Service无法让Spring自动装配,在这个问题上我研究了好久,网上一大堆Quartz1的例子在Quart2上都不好使了。最后查阅API,才发现应该使用SchedulerContextAsMap来将Spring管理的Bean放入这个Map中,具体的写法请看上面的配置代码。最后在Job类中去继承QuartzJobBean,从上下文中才能获取Spring管理的Bean。大家一定要注意key是service接口,value-ref是service的实现类。
3、还是由于加载机制不同,Quartz中的Service获取不到Hibernate的currentSession,如果使用openSession,没有问题。。。但是需要手动关闭Session就很让我烦心了,于是使用了Spring中的AOP和事务管理去拦截Service中的方法,让Spring帮Quartz完成对数据库的访问。。。在这点不知道这么做会不会有什么影响,总之现在程序是能跑通的,先这么着吧。。
【Jobs.java】
package com.qianye.terny.springmvc.job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.SchedulerContext;import org.springframework.scheduling.quartz.QuartzJobBean;import com.qianye.terny.springmvc.model.User;import com.qianye.terny.springmvc.service.UserService;public class Jobs extends QuartzJobBean{private UserService userService;//执行调度,由于Spring与Quartz的执行顺序,无法使用自动装配功能,需要自己去调度上下文中找Bean,否则无法与Hibernate交互@Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {// TODO Auto-generated method stubtry {//获取调度上下文SchedulerContext sc = context.getScheduler().getContext();//在上下文中找到Spring已实例化好的BeanuserService = (UserService) sc.get("userService");//doQuartz();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}//周期调度方法public void doQuartz() throws Exception{User u = userService.getUserById(1);System.out.println(u.getName());}}
以上的所有程序我都是调试OK了的,也弥补一下网上相关集成文档资源稀缺,以及版本低的问题,欢迎网友批评指正,另外,附下我的整个工程源代码及集成的jar包:
http://download.csdn.net/detail/wltj920/8031971
原文:http://m.blog.csdn.net/article/details?id=40019489
0 0