SpringMVC-4.1.6
spring-security-4.0.0
sitemesh-3.0.0
hibernate-4.3.8
freemarker-2.3.22 1. [文件] beans.xm
2. [文件] MySiteMeshFilter.java
3. [文件] springmvc.xml
4. [文件] Index.java
6. [文件] index.jsp
7. [文件] spring-security.xml
8. [文件] web.xml
spring-security-4.0.0
sitemesh-3.0.0
hibernate-4.3.8
freemarker-2.3.22
1. [文件] beans.xm
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation="http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang-4.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<
bean
id
=
"propertyConfigurer"
class
=
"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
>
<
property
name
=
"locations"
>
<
list
>
<
value
>classpath:jdbc.properties</
value
>
<
value
>classpath:mail.properties</
value
>
</
list
>
</
property
>
</
bean
>
<!-- 如果 sprinmvc 和 spring ioc 扫描的包有重合就会把类初始化2次 context:component-scan -->
<!-- beans可以引用springmvc的类,但是springmvc不能引用spring的类 -->
<!-- Springmvc 的ioc容器中的bean可以引用spring 的ioc容器的bean,反之不可以 -->
<
context:component-scan
base-package
=
"com.sniper.springmvc.hibernate.*,com.sniper.springmvc.scheduler"
>
<!-- 不扫描的带有这些注解的类 -->
<
context:exclude-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Controller"
/>
<
context:exclude-filter
type
=
"annotation"
expression
=
"org.springframework.web.bind.annotation.ControllerAdvice"
/>
</
context:component-scan
>
<!-- 配置数据源,其他框架 -->
<!-- 分库配置 master -->
<
bean
id
=
"dataSource_main"
class
=
"com.mchange.v2.c3p0.ComboPooledDataSource"
>
<
property
name
=
"driverClass"
value
=
"${jdbc.driverClass}"
/>
<
property
name
=
"jdbcUrl"
value
=
"${jdbc.jdbcUrl}"
/>
<
property
name
=
"user"
value
=
"${jdbc.user}"
/>
<
property
name
=
"password"
value
=
"${jdbc.password}"
/>
<
property
name
=
"idleConnectionTestPeriod"
value
=
"${c3p0.idleConnectionTestPeriod}"
/>
<
property
name
=
"preferredTestQuery"
value
=
"${c3p0.preferredTestQuery}"
/>
<
property
name
=
"testConnectionOnCheckin"
value
=
"${c3p0.testConnectionOnCheckin}"
/>
<
property
name
=
"testConnectionOnCheckout"
value
=
"${c3p0.testConnectionOnCheckout}"
/>
<
property
name
=
"maxPoolSize"
value
=
"${c3p0.maxPoolSize}"
/>
<
property
name
=
"minPoolSize"
value
=
"${c3p0.minPoolSize}"
/>
<
property
name
=
"initialPoolSize"
value
=
"${c3p0.initialPoolSize}"
/>
<
property
name
=
"acquireIncrement"
value
=
"${c3p0.acquireIncrement}"
/>
</
bean
>
<!-- 分库配置 slave -->
<
bean
id
=
"dataSource_salve_1"
parent
=
"dataSource_main"
>
<
property
name
=
"jdbcUrl"
value
=
"${jdbc.jdbcUrl}"
/>
</
bean
>
<!-- 配置数据源路由器 -->
<
bean
id
=
"dataSourceRouter"
class
=
"com.sniper.springmvc.datasource.DataSourceRouter"
>
<
property
name
=
"targetDataSources"
>
<
map
>
<
entry
key
=
"master"
value-ref
=
"dataSource_main"
/>
<
entry
key
=
"salve_a"
value-ref
=
"dataSource_salve_1"
/>
</
map
>
</
property
>
<!-- 默认数据源集合 -->
<
property
name
=
"defaultTargetDataSource"
ref
=
"dataSource_main"
/>
</
bean
>
<!-- 呢目的会话工厂bean(spring整合hinernate的核心入口) -->
<
bean
id
=
"sessionFactory"
class
=
"org.springframework.orm.hibernate4.LocalSessionFactoryBean"
>
<!-- 配置路由数据源 -->
<
property
name
=
"dataSource"
ref
=
"dataSourceRouter"
/>
<
property
name
=
"configLocation"
value
=
"classpath:hibernate.cfg.xml"
/>
<!-- 注解 -->
<
property
name
=
"packagesToScan"
>
<
list
>
<
value
>com.sniper.springmvc.model</
value
>
</
list
>
</
property
>
</
bean
>
<!-- hibernate事务管理器,用来在service层面上实现事务管理,实现平台无关行 -->
<
bean
id
=
"transactionManager"
class
=
"org.springframework.orm.hibernate4.HibernateTransactionManager"
>
<
property
name
=
"sessionFactory"
ref
=
"sessionFactory"
/>
</
bean
>
<!-- 事物通知 -->
<!-- rollback-for回滚事物,果存在一个事务,则支持当前事务。如果没有事务则开启 -->
<!-- aopalliance-1.0 需要这个包否则报错,这个包在struts里面 -->
<
tx:advice
id
=
"txAdvice"
transaction-manager
=
"transactionManager"
>
<
tx:attributes
>
<
tx:method
name
=
"save*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"delete*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"update*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"batch*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"execute*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"get*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
read-only
=
"true"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"load*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
read-only
=
"true"
rollback-for
=
"Exception"
/>
<
tx:method
name
=
"find*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
read-only
=
"true"
rollback-for
=
"Exception"
/>
<!-- <tx:method name="*" propagation="NOT_SUPPORTED" isolation="DEFAULT"
read-only="true"/> -->
<
tx:method
name
=
"*"
propagation
=
"REQUIRED"
isolation
=
"DEFAULT"
/>
</
tx:attributes
>
</
tx:advice
>
<!-- 切入点通知 -->
<!-- 日志记录 -->
<
bean
id
=
"logger"
class
=
"com.sniper.springmvc.advice.Logger"
/>
<!-- EhCache library setup -->
<
bean
id
=
"ehcache"
class
=
"org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:config-location
=
"classpath:ehcache.xml"
/>
<
bean
id
=
"cacheManager"
class
=
"org.springframework.cache.ehcache.EhCacheCacheManager"
p:cache-manager-ref
=
"ehcache"
/>
<!-- 自定义生成缓存key -->
<
bean
id
=
"surveyKey"
class
=
"com.sniper.springmvc.cache.SurveyKey"
></
bean
>
<
cache:advice
id
=
"cacheAdvice"
cache-manager
=
"cacheManager"
key-generator
=
"surveyKey"
>
<!-- -->
<
cache:caching
cache
=
"SurveyAdminRight"
>
<!-- 缓存方法 保存的key -->
<
cache:cacheable
method
=
"getC*"
/>
<
cache:cacheable
method
=
"loadC*"
/>
<
cache:cacheable
method
=
"findC*"
/>
<!-- 删除缓存的方法 就是当执行下面方法的时候除掉缓存 需要配合aop切入点才管用 -->
<
cache:cache-evict
method
=
"save*"
all-entries
=
"true"
/>
<
cache:cache-evict
method
=
"update*"
all-entries
=
"true"
/>
<
cache:cache-evict
method
=
"delete*"
all-entries
=
"true"
/>
<
cache:cache-evict
method
=
"clear*"
all-entries
=
"true"
/>
<
cache:cache-evict
method
=
"toggle*"
all-entries
=
"true"
/>
<
cache:cache-evict
method
=
"move*"
all-entries
=
"true"
/>
<
cache:cache-evict
method
=
"batch*"
all-entries
=
"true"
/>
</
cache:caching
>
</
cache:advice
>
<
aop:config
>
<!-- order 值越大优先值越低 -->
<!-- 事务切入点通知 -->
<
aop:advisor
advice-ref
=
"txAdvice"
pointcut
=
"execution(* *..*Service.*(..))"
order
=
"1"
/>
<!-- 缓存切入点通知 -->
<
aop:advisor
advice-ref
=
"cacheAdvice"
pointcut="(execution(* *..*Service.getC*(..))
or execution(* *..*Service.findC*(..))
or execution(* *..*Service.loadC*(..))
or execution(* *..*Service.save*(..))
or execution(* *..*Service.update*(..))
or execution(* *..*Service.delete*(..))
or execution(* *..*Service.move*(..))
or execution(* *..*Service.toggle*(..))
or execution(* *..*Service.clear*(..)))
and !bean(myUserDetail)
"
order
=
"0"
/>
<!-- logger切面 -->
<
aop:aspect
id
=
"loggerAspect"
ref
=
"logger"
order
=
"0"
>
<
aop:around
method
=
"record"
pointcut="(execution(* *..*Service.save*(..))
or execution(* *..*Service.update*(..))
or execution(* *..*Service.delete*(..))
or execution(* *..*Service.batch*(..))
or execution(* *..*Service.new*(..))
or execution(* *..*Service.move*(..))
or execution(* *..*Service.clear*(..))
or execution(* *..*Service.toggle*(..)))
and !bean(logService)
" />
</
aop:aspect
>
</
aop:config
>
<
bean
id
=
"mailSender"
class
=
"org.springframework.mail.javamail.JavaMailSenderImpl"
>
<
property
name
=
"defaultEncoding"
value
=
"${mail.smtp.encoding}"
/>
<
property
name
=
"host"
value
=
"${mail.smtp.host}"
/>
<
property
name
=
"username"
value
=
"${mail.smtp.username}"
/>
<
property
name
=
"password"
value
=
"${mail.smtp.password}"
/>
<
property
name
=
"javaMailProperties"
>
<
props
>
<!-- 是否开启验证 -->
<
prop
key
=
"mail.smtp.auth"
>${mail.smtp.auth}</
prop
>
<
prop
key
=
"mail.debug"
>true</
prop
>
<!-- 设置发送延迟 -->
<
prop
key
=
"mail.smtp.timeout"
>${mail.smtp.timeout}</
prop
>
</
props
>
</
property
>
</
bean
>
<!-- 设置计划人物扫描 -->
<
task:annotation-driven
/>
<!--加载 -->
<
bean
id
=
"springContextHelper"
class
=
"com.sniper.springmvc.security.SpringContextUtil"
></
bean
>
</
beans
>
2. [文件] MySiteMeshFilter.java
package
com.sniper.springmvc.sitemesh3;
import
org.sitemesh.builder.SiteMeshFilterBuilder;
import
org.sitemesh.config.ConfigurableSiteMeshFilter;
public
class
MySiteMeshFilter
extends
ConfigurableSiteMeshFilter {
@Override
protected
void
applyCustomConfiguration(SiteMeshFilterBuilder builder) {
builder.addDecoratorPath(
"/admin/**"
,
"/WEB-INF/template/admin/main.jsp"
)
.addExcludedPath(
"/admin/login**"
)
.addExcludedPath(
"/admin/admin-print**"
)
.addExcludedPath(
"/admin/file-upload**"
)
.addDecoratorPath(
"/*"
,
"/WEB-INF/template/home/main.jsp"
)
.addExcludedPath(
"/myfiles/*"
);
}
}
3. [文件] springmvc.xml
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xmlns:aop
=
"http://www.springframework.org/schema/aop"
xmlns:cache
=
"http://www.springframework.org/schema/cache"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:context
=
"http://www.springframework.org/schema/context"
xmlns:p
=
"http://www.springframework.org/schema/p"
xmlns:task
=
"http://www.springframework.org/schema/task"
xmlns:tx
=
"http://www.springframework.org/schema/tx"
xmlns:lang
=
"http://www.springframework.org/schema/lang"
xsi:schemaLocation="http://www.springframework.org/schema/langhttp://www.springframework.org/schema/lang/spring-lang-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--需要进行 spring整合springmvc么 还是需要加入spring的ioc容器 是否需要在web.xml中配置springioc容器的ContextLoaderListener
1.需要:通常情况下,类似于数据源,事务,整合其他框架都是放在spring配置文件中(而不是放在springmv里面) 2.不需要都放在springmvc的配置文件中,也可以分多个Spring
的配置文件然后import 节点导入其他的配置文件 实际上 -->
<
context:component-scan
base-package
=
"com.sniper.springmvc"
>
<!-- 不扫描的带有这些注解的类 -->
<
context:exclude-filter
type
=
"annotation"
expression
=
"org.springframework.stereotype.Service"
/>
</
context:component-scan
>
<!-- 配置 freemarker解析器 -->
<
bean
class
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"
>
<
property
name
=
"viewClass"
value
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerView"
/>
<
property
name
=
"suffix"
value
=
""
/>
<
property
name
=
"viewNames"
value
=
"*.ftl"
/>
<
property
name
=
"prefix"
value
=
""
/>
<
property
name
=
"cache"
value
=
"false"
/>
<
property
name
=
"contentType"
value
=
"text/html;charset=UTF-8"
/>
<
property
name
=
"exposeRequestAttributes"
value
=
"true"
/>
<
property
name
=
"exposeSessionAttributes"
value
=
"true"
/>
<
property
name
=
"exposeSpringMacroHelpers"
value
=
"true"
/>
<!-- 此变量值为pageContext.request, 页面使用方法:base.contextPath -->
<
property
name
=
"requestContextAttribute"
value
=
"base"
/>
<
property
name
=
"order"
value
=
"200"
/>
</
bean
>
<
bean
id
=
"fmXmlEscape"
class
=
"freemarker.template.utility.XmlEscape"
></
bean
>
<
bean
id
=
"freemarkerConfig"
class
=
"org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"
>
<
property
name
=
"templateLoaderPath"
value
=
"/WEB-INF/template/"
/>
<
property
name
=
"defaultEncoding"
value
=
"UTF-8"
/>
<
property
name
=
"freemarkerVariables"
>
<
map
>
<
entry
key
=
"xml_escape"
value-ref
=
"fmXmlEscape"
/>
</
map
>
</
property
>
<
property
name
=
"freemarkerSettings"
>
<
props
>
<
prop
key
=
"tag_syntax"
>auto_detect</
prop
>
<
prop
key
=
"template_update_delay"
>5</
prop
>
<
prop
key
=
"defaultEncoding"
>UTF-8</
prop
>
<
prop
key
=
"url_escaping_charset"
>UTF-8</
prop
>
<
prop
key
=
"locale"
>zh_CN</
prop
>
<
prop
key
=
"boolean_format"
>true,false</
prop
>
<
prop
key
=
"datetime_format"
>yyyy-MM-dd HH:mm:ss</
prop
>
<
prop
key
=
"date_format"
>yyyy-MM-dd</
prop
>
<
prop
key
=
"time_format"
>HH:mm:ss</
prop
>
<
prop
key
=
"number_format"
>0.######</
prop
>
<
prop
key
=
"whitespace_stripping"
>true</
prop
>
<!--空值处理<prop key="classic_compatible">true</prop> -->
<!-- <prop key="auto_import">/ftl/tags/index.ftl as p,/ftl/spring.ftl
as s</prop> -->
</
props
>
</
property
>
</
bean
>
<!-- 配置试图解析器 -->
<
bean
class
=
"org.springframework.web.servlet.view.InternalResourceViewResolver"
>
<
property
name
=
"prefix"
value
=
"/WEB-INF/template/"
/>
<!-- 下面2个都不允许设置 -->
<!-- <property name="suffix" value="" /> -->
</
bean
>
<
bean
id
=
"localeResolver"
class
=
"org.springframework.web.servlet.i18n.CookieLocaleResolver"
>
<
property
name
=
"cookieName"
value
=
"clientlanguage"
/>
<
property
name
=
"cookieMaxAge"
value
=
"-1"
/>
</
bean
>
<!-- id 必须是 messageSource否则出错 -->
<!-- 使用jstl 资源国际化的设置 -->
<
bean
id
=
"messageSource"
class
=
"org.springframework.context.support.ResourceBundleMessageSource"
>
<
property
name
=
"basename"
value
=
"i18n"
/>
</
bean
>
<!--配置试图 beanNameViewResolver解析器 ,使用试图的名字来解析试图 -->
<!-- 通过order来设置 试图解析器的优先级,只要配置都会被默认的小 -->
<
bean
class
=
"org.springframework.web.servlet.view.BeanNameViewResolver"
>
<
property
name
=
"order"
value
=
"100"
/>
</
bean
>
<!-- 配置直接转发的页面 -->
<!-- 直接响应转发的页面不经过handler的方法 ,如果不加上下面的配置以前的 url都会失效 -->
<
mvc:view-controller
path
=
"/success"
view-name
=
"success"
/>
<!-- 取消对静态资源的解释,这样可以直接访问静态资源,这里判断访问资源是否被映射过 -->
<!-- 这样不会出现找不到匹配资源的情况 -->
<
mvc:default-servlet-handler
/>
<!-- 静态文件映射 -->
<
mvc:resources
location
=
"/myfiles/"
mapping
=
"/myfiles/**"
/>
<!-- 下面是我学习是写的可以把你们没有的删除即可 -->
<!-- 在实际开发中都通常需要配置 mvc:annotion-driven 标签 -->
<!-- 加上这个配置就不会除了mvc之外的url都不能使用 -->
<!-- 作用有很多会住测三个bean 支持实例对表单参数类型转换 支持很多类型注解数据类型的格式化 -->
<!-- -->
<
mvc:annotation-driven
/>
<!-- 下面的写法可以使用自定义转换器,自定义类型转换器和系统类型转换器一起使用 -->
<!-- <mvc:annotation-driven conversion-service="conversionService" /> -->
<!-- 配置 conversionService -->
<!-- org.springframework.context.support.ConversionServiceFactoryBean -->
<
bean
id
=
"conversionService"
class
=
"org.springframework.format.support.FormattingConversionServiceFactoryBean"
>
<
property
name
=
"converters"
>
<
set
>
<!-- 使用 @Component注册 用spring扫描 -->
<
ref
bean
=
"userConverter"
/>
</
set
>
</
property
>
</
bean
>
<!-- 验证 -->
<
bean
id
=
"validationFactoryBean"
class
=
"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"
>
</
bean
>
<!-- 配置 SessionLocaleResolver -->
<
bean
id
=
"localResolver"
class
=
"org.springframework.web.servlet.i18n.SessionLocaleResolver"
/>
<!-- 下面的拦截器可以指定url开始的 -->
<!-- 配置链接修改语言环境的 拦截器 org.springframework.web.servlet.i18n.LocaleChangeInterceptor -->
<
mvc:interceptors
>
<!-- 配置自定义拦截器,controller的使用时间 -->
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<
mvc:exclude-mapping
path
=
"/myfiles/**"
/>
<
mvc:exclude-mapping
path
=
"/verify**"
/>
<
bean
class
=
"com.sniper.springmvc.interceptions.RunTimeInterceptor"
/>
<!-- 链接改变语言环境的session拦截器 -->
</
mvc:interceptor
>
<
mvc:interceptor
>
<
mvc:mapping
path
=
"/**"
/>
<
mvc:exclude-mapping
path
=
"/myfiles/**"
/>
<
mvc:exclude-mapping
path
=
"/verify**"
/>
<!-- 链接改变语言环境的session拦截器 -->
<
bean
class
=
"com.sniper.springmvc.interceptions.MyLocaleChangeInterceptor"
/>
</
mvc:interceptor
>
<
mvc:interceptor
>
<!-- 拦截器管用的路径 -->
<
mvc:mapping
path
=
"/springmvc"
/>
<!-- 那个拦截器使用此条规则 -->
<
bean
class
=
"com.sniper.springmvc.interceptions.SecondInterceptor"
/>
<!-- 拦截器不管用的路径 -->
<!-- <mvc:exclude-mapping path="/abc"/> -->
</
mvc:interceptor
>
</
mvc:interceptors
>
<!-- 上传文件配置 -->
<
bean
id
=
"multipartResolver"
class
=
"org.springframework.web.multipart.commons.CommonsMultipartResolver"
>
<
property
name
=
"defaultEncoding"
value
=
"UTF-8"
/>
<
property
name
=
"maxUploadSize"
value
=
"10485760"
/>
</
bean
>
<!-- 配置错误处理页面 -->
<!-- 通过 SimpleMappingExceptionResolver处理错误页面 -->
<
bean
class
=
"org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
>
<!-- 更改试图中exception的名称 -->
<!-- <property name="exceptionAttribute" value="ex"></property> <property
name="exceptionMappings"> <props> <prop key="java.lang.ArrayIndexOutOfRoundsException"></prop>
</props> </property> -->
<!-- <property name="exceptionMappings"> <props> <prop key="java.lang.Throwable">500</prop>
</props> </property> <property name="warnLogCategory" value="WARN"></property>
<property name="defaultErrorView" value="500"></property> <property name="defaultStatusCode"
value="500"></property> <property name="statusCodes"> <props> <prop key="404">404</prop>
<prop key="500">500</prop> </props> </property> -->
</
bean
>
</
beans
>
4. [文件] Index.java
package
com.sniper.springmvc.action.home;
import
java.util.Date;
import
java.util.Map;
import
org.springframework.stereotype.Controller;
import
org.springframework.web.bind.annotation.RequestBody;
import
org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.ResponseBody;
import
com.sniper.springmvc.model.SystemConfig;
@Controller
public
class
Index
extends
BaseAction<SystemConfig> {
@RequestMapping
(
"/"
)
public
String index(Map<String, Object> map) {
System.out.println(model.getClass());
System.out.println(
"执行我的次数"
);
return
"home/index/index.jsp"
;
}
/**
* 数据下载例子
*
* @param map
* @return
*/
@RequestMapping
(
"goto"
)
public
String download(Map<String, Object> map) {
map.put(
"path"
,
"/approot/soft/ffmpeg-2.5.2.tar.bz2"
);
return
"redirect:download"
;
}
@RequestMapping
(
"toupload"
)
public
String upload() {
return
"home/index/index.jsp"
;
}
@RequestMapping
(
"freemarker"
)
public
String freemarker() {
return
"home/index/index.ftl"
;
}
@ResponseBody
public
String reponseBody(
@RequestBody
String body) {
// 返回客户端一个字符串
System.out.println(body);
return
"aa"
+
new
Date();
}
}
5. [文件] index.ftl
<!
DOCTYPE
html>
<
html
lang
=
"zh-cn"
>
<
head
>
<
meta
charset
=
"utf-8"
>
<
title
>登录</
title
>
<
base
href
=
"${baseHref.baseHref}"
>
<
meta
name
=
"viewport"
content
=
"width=device-width, initial-scale=1.0"
>
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=edge"
>
<
script
type
=
"text/javascript"
src
=
"myfiles/js/jquery-1.11.1.min.js"
></
script
>
<
script
type
=
"text/javascript"
src
=
"myfiles/Plugin/Bootstrap/js/bootstrap.min.js"
></
script
>
<
link
href
=
"myfiles/Plugin/Bootstrap/css/bootstrap.min.css"
media
=
"screen"
rel
=
"stylesheet"
type
=
"text/css"
>
<
link
href
=
"myfiles/Plugin/Bootstrap/css/bootstrap-theme.min.css"
media
=
"screen"
rel
=
"stylesheet"
type
=
"text/css"
>
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="myfiles/Plugin/Bootstrap/js/html5shiv.min.js"></script>
<![endif]-->
<
script
type
=
"text/javascript"
src
=
"myfiles/js/jquery.backstretch.min.js"
></
script
>
<
style
type
=
"text/css"
>
.form-signin {
margin: 0 auto;
max-width: 330px;
padding: 15px;
}
</
style
>
</
head
>
<
body
>
<
div
class
=
"container"
>
<
form
data-status
=
''
class
=
"form-signin"
role
=
"form"
name
=
"login"
action
=
"login_check"
method
=
"post"
>
<
h2
class
=
"form-signin-heading"
>登录</
h2
>
<
input
type
=
"hidden"
name
=
"${_csrf.parameterName}"
value
=
"${_csrf.token}"
/>
<#if loginError??>
<
div
class
=
"alert alert-warning alert-dismissible"
role
=
"alert"
>
<
button
type
=
"button"
class
=
"close"
data-dismiss
=
"alert"
>
<
span
aria-hidden
=
"true"
>×</
span
><
span
class
=
"sr-only"
>Close</
span
>
</
button
>
${loginError}
</
div
>
</#if>
<
div
class
=
"form-group input-group-lg"
>
<
label
for
=
"username"
>用户名</
label
>
<
input
type
=
"text"
id
=
"username"
value
=
"${lastLoginName!''}"
name
=
"username"
class
=
"form-control"
placeholder
=
""
required autofocus>
</
div
>
<
div
class
=
"form-group input-group-lg"
>
<
label
for
=
"password"
>密码</
label
>
<
input
id
=
"password"
type
=
"password"
name
=
"password"
class
=
"form-control"
placeholder
=
""
name
=
""
required>
</
div
>
<#if loginNum?? && loginNum?eval gt 300 >
<
div
class
=
"form-group input-group-lg"
>
<
label
for
=
"verifycode"
class
=
"col-sm-2 control-label sr-only"
>
验证码
</
label
>
<
input
type
=
"text"
name
=
"sessionVerifyName"
style
=
" display: inline;width: 44%; float: left;"
placeholder
=
""
id
=
"verifycode"
class
=
"form-control"
>
<
img
alt
=
""
style
=
"cursor: pointer; margin-left:2%"
src
=
"verify"
class
=
"fl"
>
</
div
>
</#if>
<
div
class
=
"form-group input-group-lg"
>
<
label
class
=
""
>
<
input
type
=
"checkbox"
name
=
"remember-me"
> Remember me
</
label
>
</
div
>
<
button
class
=
"btn btn-lg btn-primary btn-block"
type
=
"submit"
>
登录
</
button
>
<
p
class
=
"text-muted pull-right"
><
a
href
=
"password/getPassword"
>忘记密码?</
a
></
p
>
</
form
>
</
div
>
<!-- /container -->
<
script
language
=
"javascript"
>
$(function() {
$('form img').click(function() {
fleshVerify();
});
});
function fleshVerify() {
var timenow = new Date().getTime();
var src = $('form img').attr("src");
var indexof = src.indexOf("?");
if (indexof != -1) {
src = src.substring(0, src.indexOf("?"));
}
$('form img').attr("src", src + '?d=' + timenow);
}
</
script
>
</
body
>
</
html
>
6. [文件] index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!
DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
<
head
>
<
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"
>
</
head
>
<
body
>
</
body
>
</
html
>
7. [文件] spring-security.xml
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xmlns:beans
=
"http://www.springframework.org/schema/beans"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<
global-method-security
pre-post-annotations
=
"enabled"
/>
<
http
pattern
=
"/myfiles/**"
security
=
"none"
/>
<
http
pattern
=
"/attachments/**"
security
=
"none"
/>
<
http
pattern
=
"/verify**"
security
=
"none"
/>
<
http
disable-url-rewriting
=
"true"
use-expressions
=
"false"
entry-point-ref
=
"authenticationProcessingFilterEntryPoint"
>
<!-- 匿名授权 -->
<
access-denied-handler
error-page
=
"/WEB-INF/template/error/error_no_right.jsp"
/>
<!--auto-config = true 则使用from-login. 如果不使用该属性 则默认为http-basic(没有session). -->
<!-- lowercase-comparisons:表示URL比较前先转为小写。 -->
<!-- path-type:表示使用Apache Ant的匹配模式。 -->
<!--access-denied-page:访问拒绝时转向的页面。 -->
<!-- access-decision-manager-ref:指定了自定义的访问策略管理器。 -->
<
intercept-url
pattern
=
"/**"
access
=
"IS_AUTHENTICATED_ANONYMOUSLY"
/>
<
intercept-url
pattern
=
"/admin**"
access
=
"ROLE_ADMIN"
/>
<!-- <form-login /> -->
<!-- username-parameter="j_username" password-parameter="j_password" login-processing-url="j_spring_security_check" -->
<!-- <form-login login-page="/admin/login" authentication-failure-url="/admin/login?error=true"
default-target-url="/admin" username-parameter="username" password-parameter="password"
/> -->
<!--login-page:指定登录页面。 -->
<!-- login-processing-url:指定了客户在登录页面中按下 Sign In 按钮时要访问的 URL。 -->
<!-- authentication-failure-url:指定了身份验证失败时跳转到的页面。 -->
<!-- default-target-url:指定了成功进行身份验证和授权后默认呈现给用户的页面。 -->
<!-- always-use-default-target:指定了是否在身份验证通过后总是跳转到default-target-url属性指定的URL。 -->
<!-- /j_spring_security_logout, 注销页面 -->
<!--logout-url:指定了用于响应退出系统请求的URL。其默认值为:/j_spring_security_logout。 -->
<!-- logout-success-url:退出系统后转向的URL。 -->
<!-- invalidate-session:指定在退出系统时是否要销毁Session。 -->
<
logout
logout-success-url
=
"/admin/login"
logout-url
=
"/logout"
delete-cookies
=
"JSESSIONID"
/>
<!-- 表单中的name是 remember_me -->
<!-- services-ref="rememberMeServices" -->
<
remember-me
remember-me-parameter
=
"_spring_security_remember_me"
remember-me-cookie
=
"SPRING_SECURITY_REMEMBER_ME_COOKIE"
/>
<!-- <http-basic /> -->
<
csrf
disabled
=
"false"
/>
<
headers
disabled
=
"false"
>
<
cache-control
/>
<
content-type-options
/>
<
hsts
/>
<!-- <frame-options /> -->
<
xss-protection
/>
<!-- 静态头部信息 -->
<!-- <header name="Content-Security-Policy" value="default-src 'self'"
/> <header name="Content-Security-Report-Only" value="default-src 'self'"
/> -->
</
headers
>
<!-- 检测session是否可用的地址 max-sessions=1配合单用户登录最大session个数=1 -->
<!-- session-fixation-protection 解决session伪造 -->
<!-- error-if-maximum-exceeded 解决单一登录,不提出第一个登录 -->
<!-- max-sessions:允许用户帐号登录的次数。范例限制用户只能登录一次。 -->
<!-- 此值表示:用户第二次登录时,前一次的登录信息都被清空。 -->
<!-- 需要在web.xml添加监听器 org.springframework.security.web.session.HttpSessionEventPublisher -->
<
session-management
session-fixation-protection
=
"none"
>
<
concurrency-control
max-sessions
=
"1"
error-if-maximum-exceeded
=
"true"
/>
</
session-management
>
<!-- 设置验证filter -->
<!-- <custom-filter ref="csrfFilter" before="CSRF_FILTER" /> -->
<
custom-filter
ref
=
"myLoginFilter"
before
=
"FORM_LOGIN_FILTER"
/>
<
custom-filter
ref
=
"mySniperFilter"
before
=
"FILTER_SECURITY_INTERCEPTOR"
/>
<!-- cas单点登录配置 -->
<!-- <custom-filter ref="myLogoutFilter" before="LOGOUT_FILTER"/> <custom-filter
ref="myCasFilter" before="CAS_FILTER"/> -->
</
http
>
<!-- <beans:bean id="requestDataValueProcessor" class="org.springframework.security.web.servlet.support.csrf.CsrfRequestDataValueProcessor"
/> <beans:bean id="csrfFilter" class="org.springframework.security.web.csrf.CsrfFilter">
<beans:constructor-arg> <beans:bean class="org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository">
<beans:property name="headerName" value="X-SECURITY" /> </beans:bean> </beans:constructor-arg>
</beans:bean> -->
<
beans:bean
id
=
"rememberMeServices"
class
=
"org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices"
>
<
beans:constructor-arg
name
=
"userDetailsService"
ref
=
"myUserDetail"
/>
<
beans:constructor-arg
name
=
"key"
value
=
"remember_me"
/>
<
beans:property
name
=
"alwaysRemember"
value
=
"true"
/>
<
beans:property
name
=
"tokenValiditySeconds"
value
=
"86400"
/>
<
beans:property
name
=
"parameter"
value
=
"remember_me"
/>
<
beans:property
name
=
"cookieName"
value
=
"spring_security_remember_me_cookies"
/>
</
beans:bean
>
<!-- 配置过滤器 -->
<
beans:bean
id
=
"mySniperFilter"
class
=
"com.sniper.springmvc.security.MyFilterSecurityInterceptor"
>
<!-- 用户拥有的权限 -->
<
beans:property
name
=
"authenticationManager"
ref
=
"authenticationManager"
/>
<!-- 用户是否拥有所请求资源的权限 -->
<
beans:property
name
=
"accessDecisionManager"
ref
=
"myAccessDecisionManagerBean"
/>
<!-- 资源与权限对应关系 -->
<
beans:property
name
=
"securityMetadataSource"
ref
=
"securityMetadataSource"
/>
</
beans:bean
>
<!-- 认真管理器,实现用户认证的入口,主要实现USerDetailsService 接口即可 -->
<
authentication-manager
alias
=
"authenticationManager"
>
<
authentication-provider
user-service-ref
=
"myUserDetail"
>
<!-- 因为用户登录自定义,密码加密在自定义里面加密过了所以这里不用设置加密 -->
<!-- <password-encoder hash="md5"> -->
<!-- <salt-source user-property="username"/> <salt-source user-property="password"/> -->
<!-- </password-encoder> -->
</
authentication-provider
>
</
authentication-manager
>
<!-- 读取用户的密码,角色信息,是否锁定,账号是否过期 -->
<
beans:bean
id
=
"myUserDetail"
class
=
"com.sniper.springmvc.security.MyUserDetailsService"
>
<
beans:constructor-arg
name
=
"adminUserService"
ref
=
"adminUserService"
/>
</
beans:bean
>
<!-- 访问决策其,决定那个用户具有的角色,是否足够权限访问 -->
<
beans:bean
id
=
"myAccessDecisionManagerBean"
class
=
"com.sniper.springmvc.security.myAccessDecisionManagerBean"
/>
<!-- 资源数据定义,将所有的资源和权限对应关系建立起来,及定义木易资源可以被大写橘色访问 -->
<
beans:bean
id
=
"securityMetadataSource"
class
=
"com.sniper.springmvc.security.MySecurityMetadataSource"
>
<
beans:property
name
=
"adminRightService"
ref
=
"adminRightService"
/>
</
beans:bean
>
<!-- 自定义登录filter -->
<
beans:bean
id
=
"myLoginFilter"
class
=
"com.sniper.springmvc.security.MyUsernamePasswordAuthenticationFilter"
>
<!-- 处理登录 -->
<
beans:property
name
=
"filterProcessesUrl"
value
=
"/login_check"
/>
<!-- 处理登录成功之后的处理 -->
<
beans:property
name
=
"authenticationSuccessHandler"
ref
=
"loginLogAuthenticationSuccessHandler"
/>
<!-- 验证失败 -->
<
beans:property
name
=
"authenticationFailureHandler"
ref
=
"simpleUrlAuthenticationFailureHandler"
/>
<
beans:property
name
=
"authenticationManager"
ref
=
"authenticationManager"
/>
<!-- 注入用户dao -->
<
beans:property
name
=
"adminUserService"
ref
=
"adminUserService"
/>
<!-- <beans:property name="rememberMeServices" ref="rememberMeServices"
/> -->
</
beans:bean
>
<!-- 登录成功后跳转页面 -->
<
beans:bean
id
=
"loginLogAuthenticationSuccessHandler"
class
=
"org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler"
>
<
beans:property
name
=
"defaultTargetUrl"
value
=
"/admin/"
/>
</
beans:bean
>
<!-- 登录失败后跳转页面 -->
<
beans:bean
id
=
"simpleUrlAuthenticationFailureHandler"
class
=
"org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"
>
<!-- 可以配置相应的跳转方式。属性forwardToDestination为true采用forward false为sendRedirect -->
<
beans:property
name
=
"defaultFailureUrl"
value
=
"/admin/login?error=true"
/>
</
beans:bean
>
<!-- This filter handles a Single Logout Request from the CAS Server -->
<!-- <beans:bean id="myCasFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"></beans:bean> -->
<!-- This filter redirects to the CAS Server to signal Single Logout should
be performed -->
<!-- <beans:bean id="myLogoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<constructor-arg value="https://localhost:9443/cas/logout"/> <constructor-arg>
<bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
</constructor-arg> <property name="filterProcessesUrl" value="/j_spring_cas_security_logout"/>
</beans:bean> -->
<!-- 未登录用户跳转页面 -->
<
beans:bean
id
=
"authenticationProcessingFilterEntryPoint"
class
=
"org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint"
>
<
beans:constructor-arg
value
=
"/admin/login"
/>
</
beans:bean
>
</
beans:beans
>
8. [文件] web.xml
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
xsi:schemaLocation
=
"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id
=
"WebApp_ID"
version
=
"3.1"
>
<
display-name
>springmvc_food</
display-name
>
<
description
>springmvc_food</
description
>
<
context-param
>
<
param-name
>webAppRootKey</
param-name
>
<
param-value
>app.root.food</
param-value
>
</
context-param
>
<
context-param
>
<
param-name
>privateKey</
param-name
>
<
param-value
>MIIBUwIBADANBgkqhkiG9w0BAQEFAASCAT0wggE5AgEAAkEAmbcvGVNGREmiuQPehURivFsMFwanlqAr8PGzdMSQMW1bPHd8jfGUkSQMey0G7BH3rFZjQITBt1NICN2wVznBAwIDAQABAj80PQzEjohSrLOgLLBymcr0N/zj1l8d0VEdkQZrqGFYakkh5FbLBS/wveLuLBTwoeNDEh8D680psFgCq0XDVeECIQDnr5LM8vo6UjwjsjESOjwYVJDzIZwseepeJDFMvrP4EQIhAKnY4Fsy66PsuVafncJXdUakZiZN3VokbU7S+wE4kpvTAiB9rCoIC+CZlBPVFQozJe2FERITH+8T3Qm5CQ7I30TF0QIgKcg6WPUL1sWTSmX1rytIpFoo7t9UxqoTYcKxELnUBxUCIQC3mJSmwP6dXijCy10aiBm/b4pfpdveA5dj4yegZnLYPw==</
param-value
>
<
description
></
description
>
</
context-param
>
<
context-param
>
<
param-name
>publicKey</
param-name
>
<
param-value
>MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJm3LxlTRkRJorkD3oVEYrxbDBcGp5agK/Dxs3TEkDFtWzx3fI3xlJEkDHstBuwR96xWY0CEwbdTSAjdsFc5wQMCAwEAAQ==</
param-value
>
<
description
></
description
>
</
context-param
>
<
context-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>
classpath:beans.xml,
classpath:spring-security.xml
</
param-value
>
</
context-param
>
<!-- spring 整合索赔日内个mvc的时候是否需要写ContextLoaderListener -->
<
listener
>
<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>
</
listener
>
<
filter
>
<
filter-name
>characterEncodingFilter</
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
>characterEncodingFilter</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<!-- 登录验证权限 -->
<
filter
>
<
filter-name
>springSecurityFilterChain</
filter-name
>
<
filter-class
>org.springframework.web.filter.DelegatingFilterProxy</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>springSecurityFilterChain</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<!--配置 HiddenHttpMethodFilter请可以把post请求转为delete请求或者post请求改成put -->
<
filter
>
<
filter-name
>hiddenHttpMethodfilter</
filter-name
>
<
filter-class
>org.springframework.web.filter.HiddenHttpMethodFilter</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>hiddenHttpMethodfilter</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<!-- sitemesh 配置 -->
<
filter
>
<
filter-name
>sitemesh</
filter-name
>
<
filter-class
>com.sniper.springmvc.sitemesh3.MySiteMeshFilter</
filter-class
>
</
filter
>
<
filter-mapping
>
<
filter-name
>sitemesh</
filter-name
>
<
url-pattern
>/*</
url-pattern
>
</
filter-mapping
>
<!-- springmvc 配置 -->
<
servlet
>
<
servlet-name
>springDispatcherServlet</
servlet-name
>
<
servlet-class
>org.springframework.web.servlet.DispatcherServlet</
servlet-class
>
<
init-param
>
<
param-name
>contextConfigLocation</
param-name
>
<
param-value
>classpath:springmvc.xml</
param-value
>
</
init-param
>
<!-- 加载时创建 -->
<
load-on-startup
>1</
load-on-startup
>
</
servlet
>
<
servlet-mapping
>
<
servlet-name
>springDispatcherServlet</
servlet-name
>
<
url-pattern
>/</
url-pattern
>
</
servlet-mapping
>
<
jsp-config
>
<
jsp-property-group
>
<
url-pattern
>*.jsp</
url-pattern
>
<
url-pattern
>*.ftl</
url-pattern
>
<
trim-directive-whitespaces
>true</
trim-directive-whitespaces
>
</
jsp-property-group
>
</
jsp-config
>
</
web-app
>