TeRny's Blog

Love JAVA&WRX

Spring4、SpringMVC4、Jackson2、Hibernate4、Quartz2、Plupload2、Proxool0.9集成

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.Driver
url=jdbc:mysql://localhost:3306/study?characterEncoding=utf8
username=root
password=admin
hibernateDialect=org.hibernate.dialect.MySQL5Dialect
hibernateShowSQL=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
	@GeneratedValue
	private int id;
	
	@Column
	private String name;
	
	@Column
	private int age;
	
	@Column
	private 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;

@Component
public class UserDAOImpl implements UserDAO {
	
	@Autowired
	private SessionFactory sessionFactory;

	@Override
	public void addUser(User u) {
		// TODO Auto-generated method stub
		sessionFactory.getCurrentSession().save(u);
		sessionFactory.getCurrentSession().flush();
	}

	@Override
	public User getUserById(int id) {
		// TODO Auto-generated method stub
		return (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;

@Component
public class UserServiceImpl implements UserService {
	
	@Autowired
	private UserDAO userDAO;

	@Override
	public void addUser(User u) {
		// TODO Auto-generated method stub
		userDAO.addUser(u);
	}

	@Override
	public User getUserById(int id) {
		// TODO Auto-generated method stub
		return 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 block
			e.printStackTrace();
		}
	}
	
	//此处为使用AJAX+JSON+POJO+JACKSON的方式来处理数据
	@RequestMapping(value="/ajaxAddUser")
	@ResponseBody
	public 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, 1gb
			chunk_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交互
	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		// TODO Auto-generated method stub
		try {
			//获取调度上下文
			SchedulerContext sc = context.getScheduler().getContext();
			
			//在上下文中找到Spring已实例化好的Bean
			userService = (UserService) sc.get("userService");
			//doQuartz();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.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



本文为原创文章,如需转载请注明出处,谢谢!

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

Spring4、SpringMVC4、Jackson2、Hibernate4、Quartz2、Plupload2、Proxool0.9集成

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭