SpringMVC+spring-security+sitemesh+hibernate+freemarker整合

4 篇文章 0 订阅
2 篇文章 0 订阅
SpringMVC-4.1.6
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" ?>
 
 
     < 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" ?>
 
     <!--需要进行 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" >&times;</ 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" ?>
 
     < 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" ?>
< web-app  xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     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 >
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值