web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>myssh</display-name>
<!--========================================================================
Context Params
=========================================================================-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml,classpath*:applicationContext*.xml</param-value>
</context-param>
<!-- log4j config -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.properties</param-value>
</context-param>
<!--========================================================================
Filters
=========================================================================-->
<!-- 著名 Character Encoding filter -->
<filter>
<filter-name>encodingFilter</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>
</filter>
<!-- Hibernate Open Session in View Filter-->
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter>
<filter-name>acegiFilterChain</filter-name>
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
</init-param>
</filter>
<!-- 做上传文件的时候,如果不增加,会发生第一次上传取不到文件的情况 -->
<filter>
<filter-name>struts-cleanup</filter-name>
<filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>acegiFilterChain</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>acegiFilterChain</filter-name>
<url-pattern>*.jspx</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts-cleanup</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--========================================================================
Listeners
=========================================================================-->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Spring ApplicationContext 载入 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring 刷新Introspector防止内存泄露 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<!-- 支持session scope的Spring bean -->
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<!-- 用于发布HttpSessionApplicationEvents和HttpSessionDestroyedEvent事件给spring的applicationcontext -->
<listener>
<listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
</listener>
<!--========================================================================
Servlets
=========================================================================-->
<!--AJAX 配置开始-->
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<!-- 1.0 -->
<!--servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class-->
<!-- 2.0 -->
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<!--AJAX 配置结束-->
<!--========================================================================
Session
=========================================================================-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
applicationContext.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: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-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/jdbc.properties</value>
<value>/WEB-INF/smtp.properties</value>
</list>
</property>
</bean>
<!-- EhCache 管理器,同时指明缓存策略的资源文件-->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>classpath:ehcache.xml</value>
</property>
</bean>
<!--========================================================================
DataSource
Using Spring provided DriverManagerDataSource;
For deployment, using container-managed JNDI DataSource instead.
=========================================================================-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--========================================================================
Hibernate config
=========================================================================-->
<!-- Using LocalSessionFactoryBean -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>net/infoisme/myssh/vo/Account.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.jdbc.fetch_size">10</prop>
</props>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Using HibernateTemplate, and shared by all DAO object because it is thread-safe -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
<property name="fetchSize" value="20" />
</bean>
<!-- TransactionManager -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!--========================================================================
Make all @Transactional beans
=========================================================================-->
<tx:annotation-driven transaction-manager="transactionManager" />
<!--========================================================================
Mail configuration
=========================================================================-->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${smtp.host}" />
<property name="port" value="${smtp.port}" />
<property name="username" value="${smtp.username}" />
<property name="password" value="${smtp.password}" />
<property name="defaultEncoding" value="${smtp.encoding}" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">${smtp.auth}</prop>
</props>
</property>
</bean>
<!--========================================================================
JMS configuration
=========================================================================-->
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jms/factory" />
</bean>
<bean id="jmsDestination" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jms/queue" />
</bean>
<!-- JMS listener wrapper -->
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="jmsDestination" />
<property name="messageListener" ref="mailListener" />
</bean>
<bean id="mailListener" class="net.infoisme.myssh.mail.MailListener">
<property name="mailSender" ref="mailSender"/>
</bean>
<bean id="mailService" class="net.infoisme.myssh.business.impl.MailServiceImpl">
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="destination" ref="jmsDestination"/>
<property name="from"><value>liuyanyong@cnnic.cn</value></property>
</bean>
<!--========================================================================
Make businessService secured
=========================================================================-->
<bean id="serviceSecurityInterceptor"
class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
<property name="validateConfigAttributes" value="true" />
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="objectDefinitionSource">
<bean class="org.acegisecurity.intercept.method.MethodDefinitionAttributes">
<property name="attributes">
<bean class="org.acegisecurity.annotation.SecurityAnnotationAttributes" />
</property>
</bean>
</property>
</bean>
<!-- 利用Spring的自动代理功能实现AOP代理 -->
<bean id="autoProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="interceptorNames">
<list>
<value>serviceSecurityInterceptor</value>
</list>
</property>
<property name="beanNames">
<list>
<value>businessService</value>
</list>
</property>
</bean>
<bean id="userDao" class="net.infoisme.myssh.dao.hibernate.UserDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
<bean id="businessService" class="net.infoisme.myssh.business.impl.BusinessServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="exambean" class="net.infoisme.myssh.action.ExampleAction" scope='prototype'></bean>
<bean id="regbean" class="net.infoisme.myssh.action.registryAction" scope='prototype'>
<property name="businessService" ref="businessService"/>
<property name="mailService" ref="mailService"/>
</bean>
</beans>
applicationContext-security.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!--========================================================================
认证管理器
=========================================================================-->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref bean="daoAuthenticationProvider" />
<ref bean="rememberMeAuthenticationProvider" />
</list>
</property>
</bean>
<!-- 基于DAO验证的AuthenticationProvider -->
<bean id="daoAuthenticationProvider"
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="userDetailsService" />
<!-- property name="passwordEncoder" ref="passwordEncoder"/-->
</bean>
<bean id="userDetailsService"
class="net.infoisme.myssh.security.JdbcUserDetailsService">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="passwordEncoder" class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"/>
<!-- 基于RememberMe验证的AuthenticationProvider -->
<bean id="rememberMeAuthenticationProvider"
class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="RememberMeAtLiveBookstore" />
</bean>
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="userDetailsService" />
<property name="parameter" value="j_remember_me" />
<property name="key" value="RememberMeAtLiveBookstore" />
</bean>
<!--========================================================================
决策管理器
=========================================================================-->
<bean id="accessDecisionManager"
class="org.acegisecurity.vote.AffirmativeBased">
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter" />
</list>
</property>
<property name="allowIfAllAbstainDecisions" value="false" />
</bean>
<!--========================================================================
过滤器链
=========================================================================-->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=sessionIntegrationFilter,logoutFilter,authenticationFilter,rememberMeFilter,exceptionFilter,securityInterceptor
</value>
</property>
</bean>
<bean id="sessionIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />
<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<!-- URL redirected to after logout -->
<constructor-arg value="/helloWorld.jsp" />
<constructor-arg>
<list>
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler" />
<ref bean="rememberMeServices" />
</list>
</constructor-arg>
<property name="filterProcessesUrl" value="/logout.jspx" />
</bean>
<bean id="authenticationFilter"
class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="authenticationFailureUrl" value="/login.jsp?login_error=%E6%97%A0%E6%95%88%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E6%88%96%E5%8F%A3%E4%BB%A4" />
<property name="defaultTargetUrl" value="/helloWorld.jsp" />
<property name="filterProcessesUrl" value="/login.jspx" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>
<bean id="rememberMeFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="rememberMeServices" ref="rememberMeServices" />
</bean>
<!-- 处理登录异常或权限异常的Filter -->
<bean id="exceptionFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<!-- 出现AuthenticationException时的登录入口 -->
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/login.jsp" />
<property name="forceHttps" value="false" />
</bean>
</property>
<!-- 出现AccessDeniedException时的Handler -->
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl" />
</property>
</bean>
<!-- 基于URL的安全拦截器 -->
<bean id="securityInterceptor"
class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<property name="authenticationManager" ref="authenticationManager" />
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/admin/**=ROLE_ADMIN
/user/**=ROLE_USER
</value>
</property>
</bean>
</beans>
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="struts-default.xml"/>
<package name="default" extends="struts-default">
<action name="example" class="exambean">
<result name="input">/test.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/success.jsp</result>
</action>
<action name="registry" class="regbean">
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
ehcache.xml
<ehcache>
<diskStore path="java.io.tmpdir"/>
<defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true"/>
</ehcache>
struts.properties
struts.custom.i18n.resources=globalMessages
struts.locale=zh_CN
struts.i18n.encoding=utf-8
struts.objectFactory = spring