Spring4.X + Spring MVC + Mybatis3 零配置应用开发框架搭建详解 (3)

来源:互联网 发布:激光雷达避障算法 编辑:程序博客网 时间:2024/05/12 17:33

转自:http://blog.csdn.net/chwshuang/article/details/52182540

目录(?)[+]

Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(3) - 实现最基本的登录处理

1. 基本架构:        

        基础框架搭建完成后,我们开始进行Spring + SpringMVC + Mybatis的集成,来完成登录功能的处理。我们根据数据流向,来创建相应的内容,先看看大致的数据流向图:


        根据上面的数据流向图,需要创建用户登录页面、登录成功页面,权限管理模块、控制层、服务层、数据库持久层,下面我们分别来创建对应的内容:

2. 创建用户登录页面和登录后的页面

首先修改【webapp】下的【login.jsp】,添加一个需要输入登录信息的表单,然后在【WEB-INF】下创建【pages】目录,在【pages】目录下创建【index】目录,在【index】目录下创建【index.jsp】,不要问为什么创建那么多文件目录和层级,太麻烦,因为这是我的习惯,真正做项目后层级划分的好处以后你就懂。

login.jsp

[html] view plain copy
 print?
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>  
  2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>  
  3. <html>  
  4. <head>  
  5.     <title>登录</title>  
  6. </head>  
  7. <body>  
  8.   
  9. <h1>系统登录</h1>  
  10.   
  11. <div>  
  12.   <c:if test="${param.error != null}">  
  13.     <p>用户名密码错误!</p>  
  14.   </c:if>  
  15.   <c:if test="${param.logout != null}">  
  16.     <p>您已注销!</p>  
  17.   </c:if>  
  18. </div>  
  19. <c:url value="/login" var="loginUrl"/>  
  20. <form action="${loginUrl}" method="post" id="loginForm">  
  21.   <div>  
  22.     <input type="text" name="username" class="username" placeholder="用户名" autocomplete="off"/>  
  23.   </div>  
  24.   <div>  
  25.     <input type="password" name="password" class="password" placeholder="密码" oncontextmenu="return false" onpaste="return false"/>  
  26.   </div>  
  27.   <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>  
  28.   <button id="submit" type="submit">登录</button>  
  29. </form>  
  30.   
  31.   
  32. </body>  
  33. </html>  

index.jsp

[html] view plain copy
 print?
  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>  
  2. <!DOCTYPE html>  
  3. <html>  
  4. <head>  
  5.     <title>首页</title>  
  6. </head>  
  7.   
  8. <body>  
  9. <h1>首页</h1>  
  10.   
  11. <h2>登录成功</h2>  
  12. </body>  
  13. </html>  


3. 在pom.xml中添加依赖jar包

        首先在web项目下的pom.xml中添加公共的依赖库,以保证配置重用。

        下面主要添加的是Spring核心的几个公用依赖包和日志包,以及工具类。插件中主要配置指定编译JDK的版本,以及资源文件的配置。

提示:添加依赖包的时候要注意设置Maven源的事,如果你自己设置的源出现问题,可以看看我的这篇博文:Maven国内源设置 -  OSChina国内源失效了,别更新了

【Web项目下的pom.xml】

[sql] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <modelVersion>4.0.0</modelVersion>  
  6.   
  7.     <groupId>com.aitongyi.web</groupId>  
  8.     <artifactId>web</artifactId>  
  9.     <version>1.0-SNAPSHOT</version>  
  10.   
  11.     <!-- 将项目定义为公共项目 -->  
  12.     <packaging>pom</packaging>  
  13.   
  14.     <modules>  
  15.         <module>back</module>  
  16.         <module>dao</module>  
  17.         <module>bean</module>  
  18.         <module>cache</module>  
  19.         <module>service</module>  
  20.         <module>task</module>  
  21.     </modules>  
  22.   
  23.     <!-- 项目的依赖包 -->  
  24.     <dependencies>  
  25.         <dependency>  
  26.             <groupId>org.springframework</groupId>  
  27.             <artifactId>spring-core</artifactId>  
  28.             <version>4.1.6.RELEASE</version>  
  29.         </dependency>  
  30.         <dependency>  
  31.             <groupId>org.springframework</groupId>  
  32.             <artifactId>spring-context</artifactId>  
  33.             <version>4.1.6.RELEASE</version>  
  34.         </dependency>  
  35.         <dependency>  
  36.             <groupId>org.springframework</groupId>  
  37.             <artifactId>spring-web</artifactId>  
  38.             <version>4.1.6.RELEASE</version>  
  39.         </dependency>  
  40.         <dependency>  
  41.             <groupId>org.springframework</groupId>  
  42.             <artifactId>spring-beans</artifactId>  
  43.             <version>4.1.6.RELEASE</version>  
  44.         </dependency>  
  45.         <dependency>  
  46.             <groupId>org.springframework</groupId>  
  47.             <artifactId>spring-jdbc</artifactId>  
  48.             <version>4.1.6.RELEASE</version>  
  49.         </dependency>  
  50.         <dependency>  
  51.             <groupId>org.springframework</groupId>  
  52.             <artifactId>spring-context-support</artifactId>  
  53.             <version>4.1.6.RELEASE</version>  
  54.         </dependency>  
  55.         <dependency>  
  56.             <groupId>org.quartz-scheduler</groupId>  
  57.             <artifactId>quartz</artifactId>  
  58.             <version>2.2.2</version>  
  59.         </dependency>  
  60.         <dependency>  
  61.             <groupId>org.quartz-scheduler</groupId>  
  62.             <artifactId>quartz-jobs</artifactId>  
  63.             <version>2.2.2</version>  
  64.         </dependency>  
  65.   
  66.         <dependency>  
  67.             <groupId>ch.qos.logback</groupId>  
  68.             <artifactId>logback-core</artifactId>  
  69.             <version>1.1.3</version>  
  70.         </dependency>  
  71.         <dependency>  
  72.             <groupId>ch.qos.logback</groupId>  
  73.             <artifactId>logback-classic</artifactId>  
  74.             <version>1.1.3</version>  
  75.         </dependency>  
  76.         <dependency>  
  77.             <groupId>ch.qos.logback</groupId>  
  78.             <artifactId>logback-access</artifactId>  
  79.             <version>1.1.3</version>  
  80.         </dependency>  
  81.         <dependency>  
  82.             <groupId>org.slf4j</groupId>  
  83.             <artifactId>slf4j-api</artifactId>  
  84.             <version>1.6.6</version>  
  85.         </dependency>  
  86.         <dependency>  
  87.             <groupId>org.slf4j</groupId>  
  88.             <artifactId>jcl-over-slf4j</artifactId>  
  89.             <version>1.6.6</version>  
  90.         </dependency>  
  91.   
  92.         <dependency>  
  93.             <groupId>org.apache.commons</groupId>  
  94.             <artifactId>commons-lang3</artifactId>  
  95.             <version>3.3</version>  
  96.         </dependency>  
  97.         <dependency>  
  98.             <groupId>commons-io</groupId>  
  99.             <artifactId>commons-io</artifactId>  
  100.             <version>2.4</version>  
  101.         </dependency>  
  102.         <dependency>  
  103.             <groupId>mysql</groupId>  
  104.             <artifactId>mysql-connector-java</artifactId>  
  105.             <version>5.1.6</version>  
  106.         </dependency>  
  107.         <dependency>  
  108.             <groupId>org.mybatis</groupId>  
  109.             <artifactId>mybatis</artifactId>  
  110.             <version>3.3.0</version>  
  111.         </dependency>  
  112.         <dependency>  
  113.             <groupId>org.mybatis</groupId>  
  114.             <artifactId>mybatis-spring</artifactId>  
  115.             <version>1.2.3</version>  
  116.         </dependency>  
  117.         <dependency>  
  118.             <groupId>org.apache.commons</groupId>  
  119.             <artifactId>commons-dbcp2</artifactId>  
  120.             <version>2.1.1</version>  
  121.         </dependency>  
  122.   
  123.         <dependency>  
  124.             <groupId>commons-fileupload</groupId>  
  125.             <artifactId>commons-fileupload</artifactId>  
  126.             <version>1.2.2</version>  
  127.         </dependency>  
  128.         <dependency>  
  129.             <groupId>org.aspectj</groupId>  
  130.             <artifactId>aspectjweaver</artifactId>  
  131.             <version>1.8.6</version>  
  132.         </dependency>  
  133.   
  134.            
  135.         <dependency>  
  136.             <groupId>javax.servlet</groupId>  
  137.             <artifactId>jstl</artifactId>  
  138.             <version>1.2</version>  
  139.         </dependency>  
  140.         <dependency>  
  141.             <groupId>javax.servlet</groupId>  
  142.             <artifactId>javax.servlet-api</artifactId>  
  143.             <version>3.1.0</version>  
  144.             <scope>provided</scope>  
  145.         </dependency>  
  146.         <!-- end -->  
  147.     </dependencies>  
  148.   
  149.   
  150.     <!-- repositories节点是配置maven下载jar的中央仓库,  
  151.     默认的是国外的,下载奇慢无比,推荐使用自己搭建sonatype nexus中央仓库 -->  
  152.     <repositories>  
  153.         <repository>  
  154.             <id>central</id>  
  155.             <name>Central Repository</name>  
  156.             <url>http://repo1.maven.org/maven2/</url>  
  157.             <snapshots>  
  158.                 <enabled>false</enabled>  
  159.             </snapshots>  
  160.         </repository>  
  161.         <repository>  
  162.             <id>jboss-public-repository-group</id>  
  163.             <name>JBoss Public Repository Group</name>  
  164.             <url>http://repository.jboss.org/nexus/content/groups/public/</url>  
  165.             <layout>default</layout>  
  166.             <releases>  
  167.                 <enabled>true</enabled>  
  168.                 <updatePolicy>never</updatePolicy>  
  169.             </releases>  
  170.             <snapshots>  
  171.                 <enabled>true</enabled>  
  172.                 <updatePolicy>never</updatePolicy>  
  173.             </snapshots>  
  174.         </repository>  
  175.         <repository>  
  176.             <id>jboss-deprecated</id>  
  177.             <name>JBoss Deprecated</name>  
  178.             <url>https://repository.jboss.org/nexus/content/repositories/deprecated/</url>  
  179.             <layout>default</layout>  
  180.             <releases>  
  181.                 <enabled>true</enabled>  
  182.                 <updatePolicy>never</updatePolicy>  
  183.             </releases>  
  184.             <snapshots>  
  185.                 <enabled>false</enabled>  
  186.             </snapshots>  
  187.         </repository>  
  188.         <repository>  
  189.             <id>jboss-maven2-brew</id>  
  190.             <name>JBoss Maven 2 Brew Repository</name>  
  191.             <url>http://repository.jboss.org/maven2-brew/</url>  
  192.             <layout>default</layout>  
  193.             <releases>  
  194.                 <enabled>true</enabled>  
  195.                 <updatePolicy>never</updatePolicy>  
  196.             </releases>  
  197.             <snapshots>  
  198.                 <enabled>false</enabled>  
  199.             </snapshots>  
  200.         </repository>  
  201.   
  202.         <repository>  
  203.             <id>io.spring.repo.maven.release</id>  
  204.             <url>http://repo.spring.io/release/</url>  
  205.             <snapshots>  
  206.                 <enabled>false</enabled>  
  207.             </snapshots>  
  208.         </repository>  
  209.         <repository>  
  210.             <id>io.spring.repo.maven.milestone</id>  
  211.             <url>http://repo.spring.io/milestone/</url>  
  212.             <snapshots>  
  213.                 <enabled>false</enabled>  
  214.             </snapshots>  
  215.         </repository>  
  216.     </repositories>  
  217.      
  218.     <build>  
  219.         <plugins>  
  220.             <!-- 指定Maven编译插件,如果不设置,它就会用maven-compiler-plugin默认的jdk版本来进行处理 -->  
  221.             <!-- 这样就容易出现版本不匹配的问题,以至于可能导致编译不通过的问题 -->  
  222.             <plugin>  
  223.                 <groupId>org.apache.maven.plugins</groupId>  
  224.                 <artifactId>maven-compiler-plugin</artifactId>  
  225.                 <version>3.1</version>  
  226.                 <configuration>  
  227.                     <source>1.7</source>  
  228.                     <target>1.7</target>  
  229.                     <fork>true</fork>  
  230.                     <verbose>true</verbose>  
  231.                     <encoding>UTF-8</encoding>  
  232.                     <compilerArguments>  
  233.                         <sourcepath>${project.basedir}/src/main/java</sourcepath>  
  234.                     </compilerArguments>  
  235.                 </configuration>  
  236.             </plugin>  
  237.             <!--  maven-resources-plugin则用来处理资源文件。默认的主资源文件目录是src/main/resources,  
  238.             很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置maven-resources-plugin来实现。  
  239.             此外,资源文件过滤也是Maven的一大特性,你可以在资源文件中使用${propertyName}形式的Maven属性,  
  240.             然后配置maven-resources-plugin开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者Profile传入属性的值,  
  241.             以实现更为灵活的构建。  -->  
  242.             <plugin>  
  243.                 <groupId>org.apache.maven.plugins</groupId>  
  244.                 <artifactId>maven-resources-plugin</artifactId>  
  245.                 <version>2.6</version>  
  246.                 <configuration>  
  247.                     <encoding>UTF-8</encoding>  
  248.                 </configuration>  
  249.             </plugin>  
  250.         </plugins>  
  251.     </build>  
  252.   
  253. </project>  


然后我们再来配置【back】模块中pom.xml的内容:

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <parent>  
  6.         <artifactId>web</artifactId>  
  7.         <groupId>com.aitongyi.web</groupId>  
  8.         <version>1.0-SNAPSHOT</version>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.   
  12.     <artifactId>back</artifactId>  
  13.     <packaging>war</packaging>  
  14.     <properties>  
  15.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  16.     </properties>  
  17.   
  18.     <dependencies>  
  19.         <dependency>  
  20.             <groupId>com.aitongyi.web</groupId>  
  21.             <artifactId>dao</artifactId>  
  22.             <version>${project.version}</version>  
  23.         </dependency>  
  24.         <dependency>  
  25.             <groupId>com.aitongyi.web</groupId>  
  26.             <artifactId>bean</artifactId>  
  27.             <version>${project.version}</version>  
  28.         </dependency>  
  29.   
  30.         <!-- spring  -->  
  31.         <dependency>  
  32.             <groupId>org.springframework</groupId>  
  33.             <artifactId>spring-webmvc</artifactId>  
  34.             <version>4.1.6.RELEASE</version>  
  35.         </dependency>  
  36.         <dependency>  
  37.             <groupId>org.springframework.security</groupId>  
  38.             <artifactId>spring-security-web</artifactId>  
  39.             <version>4.0.2.RELEASE</version>  
  40.         </dependency>  
  41.         <dependency>  
  42.             <groupId>org.springframework.security</groupId>  
  43.             <artifactId>spring-security-config</artifactId>  
  44.             <version>4.0.2.RELEASE</version>  
  45.         </dependency>  
  46.         <dependency>  
  47.             <groupId>org.springframework.security</groupId>  
  48.             <artifactId>spring-security-taglibs</artifactId>  
  49.             <version>4.0.2.RELEASE</version>  
  50.         </dependency>  
  51.         <dependency>  
  52.             <groupId>org.springframework</groupId>  
  53.             <artifactId>spring-context-support</artifactId>  
  54.             <version>4.1.6.RELEASE</version>  
  55.         </dependency>  
  56.         <dependency>  
  57.             <groupId>org.quartz-scheduler</groupId>  
  58.             <artifactId>quartz</artifactId>  
  59.             <version>2.2.2</version>  
  60.         </dependency>  
  61.         <dependency>  
  62.             <groupId>org.quartz-scheduler</groupId>  
  63.             <artifactId>quartz-jobs</artifactId>  
  64.             <version>2.2.2</version>  
  65.         </dependency>  
  66.         <!-- end -->  
  67.   
  68.         <!-- serlvet & jstl -->  
  69.         <dependency>  
  70.             <groupId>javax.servlet</groupId>  
  71.             <artifactId>jstl</artifactId>  
  72.             <version>1.2</version>  
  73.         </dependency>  
  74.         <dependency>  
  75.             <groupId>javax.servlet</groupId>  
  76.             <artifactId>javax.servlet-api</artifactId>  
  77.             <version>3.1.0</version>  
  78.             <scope>provided</scope>  
  79.         </dependency>  
  80.         <!-- end -->  
  81.   
  82.         <dependency>  
  83.             <groupId>commons-io</groupId>  
  84.             <artifactId>commons-io</artifactId>  
  85.             <version>2.4</version>  
  86.         </dependency>  
  87.         <dependency>  
  88.             <groupId>commons-fileupload</groupId>  
  89.             <artifactId>commons-fileupload</artifactId>  
  90.             <version>1.2.2</version>  
  91.         </dependency>  
  92.         <dependency>  
  93.             <groupId>org.aspectj</groupId>  
  94.             <artifactId>aspectjweaver</artifactId>  
  95.             <version>1.8.6</version>  
  96.         </dependency>  
  97.   
  98.         <dependency>  
  99.             <groupId>mysql</groupId>  
  100.             <artifactId>mysql-connector-java</artifactId>  
  101.             <version>5.1.6</version>  
  102.         </dependency>  
  103.         <dependency>  
  104.             <groupId>org.mybatis</groupId>  
  105.             <artifactId>mybatis</artifactId>  
  106.             <version>3.3.0</version>  
  107.         </dependency>  
  108.         <dependency>  
  109.             <groupId>org.mybatis</groupId>  
  110.             <artifactId>mybatis-spring</artifactId>  
  111.             <version>1.2.3</version>  
  112.         </dependency>  
  113.         <dependency>  
  114.             <groupId>org.apache.commons</groupId>  
  115.             <artifactId>commons-dbcp2</artifactId>  
  116.             <version>2.1.1</version>  
  117.         </dependency>  
  118.   
  119.     </dependencies>  
  120. </project>  


4. 编写零配置代码

4.1 【back】项目        

        在【back】项目的【src/main/Java】目录下创建【com.aitongyi.web.back.conf】配置代码包、【com.aitongyi.web.back.controller】控制层代码包;

        在【dao】项目的【src/main/java】目录下创建【com.aitongyi.web.dao.conf】配置代码包、【com.aitongyi.web.dao.mapper】持久层代码包;

        在【service】项目的【src/main/java】目录下创建【com.aitongyi.web.service】服务层代码包;

        在【bean】项目的【src/main/java】目录下创建【com.aitongyi.web.bean】模型代码包


在【back】项目【com.aitongyi.web.back.conf】包中创建五个配置对象:

【BackConfig.java】:负责管理基本配置信息

[java] view plain copy
 print?
  1. import org.springframework.beans.factory.annotation.Configurable;  
  2. import org.springframework.context.annotation.Bean;  
  3. import org.springframework.context.annotation.PropertySource;  
  4. import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;  
  5. import org.springframework.scheduling.quartz.SchedulerFactoryBean;  
  6.   
  7. @Configurable  
  8. @PropertySource(value={"classpath:back.properties"})  
  9. public class BackConfig {  
  10.     @Bean  
  11.     public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {  
  12.         return new PropertySourcesPlaceholderConfigurer();  
  13.     }  
  14.       
  15.     @Bean(name="schedulerFactoryBean")  
  16.     public SchedulerFactoryBean schedulerFactoryBean(){  
  17.         return new SchedulerFactoryBean();  
  18.     }  
  19.   
  20. }  

【MvcConfig.java】:负责处理SpirngMVC的配置信息以及组件的加载

[java] view plain copy
 print?
  1. import org.mybatis.spring.annotation.MapperScan;  
  2. import org.springframework.context.annotation.Bean;  
  3. import org.springframework.context.annotation.ComponentScan;  
  4. import org.springframework.context.annotation.EnableAspectJAutoProxy;  
  5. import org.springframework.scheduling.annotation.EnableScheduling;  
  6. import org.springframework.web.multipart.commons.CommonsMultipartResolver;  
  7. import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;  
  8. import org.springframework.web.servlet.config.annotation.EnableWebMvc;  
  9. import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;  
  10. import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;  
  11. import org.springframework.web.servlet.view.InternalResourceViewResolver;  
  12.   
  13. @EnableWebMvc  
  14. @EnableAspectJAutoProxy  
  15. @EnableScheduling  
  16. @ComponentScan(basePackages = {"com.aitongyi.web.back.controller","com.aitongyi.web.service"})  
  17. @MapperScan("com.aitongyi.web.dao.mapper")  
  18. public class MvcConfig extends WebMvcConfigurerAdapter {  
  19.    
  20.     @Override  
  21.     public void addResourceHandlers(ResourceHandlerRegistry registry) {  
  22.   
  23.     }  
  24.    
  25.     @Override  
  26.     public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {  
  27.         configurer.enable();  
  28.     }  
  29.   
  30.     /** 
  31.      * jsp视图解析器 
  32.      * @return 
  33.      */  
  34.     @Bean  
  35.     public InternalResourceViewResolver jspViewResolver() {  
  36.         InternalResourceViewResolver bean = new InternalResourceViewResolver();  
  37.         bean.setViewClass(org.springframework.web.servlet.view.JstlView.class);  
  38.         bean.setPrefix("/WEB-INF/pages/");  
  39.         bean.setSuffix(".jsp");  
  40.         return bean;  
  41.     }  
  42.   
  43.     /** 
  44.      *  公共部分解析器 
  45.      * @return 
  46.      */  
  47.     @Bean(name="multipartResolver")  
  48.     public CommonsMultipartResolver commonsMultipartResolver(){  
  49.         CommonsMultipartResolver common = new CommonsMultipartResolver();  
  50.         common.setMaxUploadSize(10 * 1024 * 1024);//10M  
  51.         return common;  
  52.     }  
  53.       
  54. }  

【SecurityConfig.java】:负责安全相关的配置处理,其中有一段代码:

[java] view plain copy
 print?
  1. auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(md5Encoder);  

这是SpringSecurity安全框架自动处理的逻辑,首先是通过username查询users表中是否有记录,然后通过将密码进行MD5加密,去跟数据库中的密码比对,如果相同就让用户执行configure方法中配置的登陆策略。

[java] view plain copy
 print?
  1. import org.springframework.beans.factory.annotation.Autowired;  
  2. import org.springframework.security.authentication.encoding.Md5PasswordEncoder;  
  3. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
  4. import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;  
  5. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
  6. import org.springframework.security.config.annotation.web.builders.WebSecurity;  
  7. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  8. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
  9. import org.springframework.security.web.csrf.CsrfFilter;  
  10. import org.springframework.security.web.header.HeaderWriter;  
  11. import org.springframework.security.web.header.HeaderWriterFilter;  
  12. import org.springframework.web.filter.CharacterEncodingFilter;  
  13.   
  14. import javax.servlet.http.HttpServletRequest;  
  15. import javax.servlet.http.HttpServletResponse;  
  16. import javax.sql.DataSource;  
  17. import java.util.ArrayList;  
  18. import java.util.List;  
  19.   
  20. @EnableWebSecurity  
  21. @EnableGlobalMethodSecurity(prePostEnabled = true)  
  22. public class SecurityConfig extends WebSecurityConfigurerAdapter {  
  23.   
  24.     private static Md5PasswordEncoder md5Encoder = new Md5PasswordEncoder();  
  25.   
  26.     @Autowired  
  27.     private DataSource dataSource;  
  28.   
  29.     @Autowired  
  30.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {  
  31.         auth.jdbcAuthentication().dataSource(dataSource).passwordEncoder(md5Encoder);  
  32.     }  
  33.   
  34.     @Override  
  35.     public void configure(WebSecurity web) throws Exception {  
  36.         web.ignoring().antMatchers("/resource/**");  
  37.     }  
  38.   
  39.     @Override  
  40.     protected void configure(HttpSecurity http) throws Exception {  
  41.   
  42.         http  
  43. //              将login.jsp定为登陆页面,只处理/login这个请求  
  44.                 .formLogin().loginPage("/login.jsp").and().formLogin().loginProcessingUrl("/login")  
  45. //              如果登陆成功就跳转到/home这个地址,如果失败就跳转到/?error=1  
  46.                 .and().formLogin().defaultSuccessUrl("/home").and().formLogin().failureUrl("/?error=1");  
  47. //      这里配置的是登出的请求  
  48.         http.logout().logoutUrl("/logout")  
  49. //              登陆成功后跳转的地址,以及删除的cookie名称  
  50.                 .and().logout().logoutSuccessUrl("/")  
  51.                 .and().logout().deleteCookies("JSESSIONID");  
  52. //      配置记住我的过期时间  
  53.         http.rememberMe().tokenValiditySeconds(1209600)  
  54.                 .and().rememberMe().rememberMeParameter("remember-me");  
  55.         CharacterEncodingFilter encodeFilter = new CharacterEncodingFilter();  
  56.         encodeFilter.setEncoding("utf-8");  
  57.         encodeFilter.setForceEncoding(true);  
  58.         http.addFilterBefore(encodeFilter, CsrfFilter.class); // 放在csrf filter前面  
  59.         http.headers().disable();  
  60.         HeaderWriter headerWriter = new HeaderWriter() {  
  61.             public void writeHeaders(HttpServletRequest request, HttpServletResponse response) {  
  62.                 response.setHeader("Cache-Control""no-cache, no-store, max-age=0, must-revalidate");  
  63.                 response.setHeader("Expires""0");  
  64.                 response.setHeader("Pragma""no-cache");  
  65.                 response.setHeader("X-Frame-Options""SAMEORIGIN");  
  66.                 response.setHeader("X-XSS-Protection""1; mode=block");  
  67.                 response.setHeader("x-content-type-options""nosniff");  
  68.             }  
  69.         };  
  70.         List<HeaderWriter> headerWriterFilterList = new ArrayList<>();  
  71.         headerWriterFilterList.add(headerWriter);  
  72.         HeaderWriterFilter headerFilter = new HeaderWriterFilter(headerWriterFilterList);  
  73.         http.addFilter(headerFilter);  
  74.     }  
  75. }  

【WebApplicationInitializer.java】:这是整个项目的核心。Servlet3.0规范,支持将web.xml相关配置也硬编码到代码中[servlet,filter,listener,等等],并由javax.servlet.ServletContainerInitializer的实现类负责在容器启动时进行加载,

spring提供了一个实现类SpringServletContainerInitializer(在spring-web包中的org.springframework.web目录),该类会调用所有org.springframework.web.WebApplicationInitializer实现类的onStartup方法,将相关的组件注册到服务器;而我们的WebApplicationInitializer继承自AbstractAnnotationConfigDispatcherServletInitializer,而AbstractAnnotationConfigDispatcherServletInitializer就实现了org.springframework.web.WebApplicationInitializer的onStartup方法,所以WebApplicationInitializer就是整个项目的关键,我们的整个项目就是通过它来启动。

[java] view plain copy
 print?
  1. import com.aitongyi.web.dao.conf.DatabaseConfig;  
  2. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;  
  3.   
  4. import javax.servlet.Filter;  
  5.   
  6. public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {  
  7.     /** 
  8.      * 获取配置信息 
  9.      * @return 
  10.      */  
  11.     @Override  
  12.     protected Class<?>[] getRootConfigClasses() {  
  13.         return new Class[] { BackConfig.class, DatabaseConfig.class, SecurityConfig.class };  
  14.     }  
  15.     @Override  
  16.     protected Class<?>[] getServletConfigClasses() {  
  17.         return new Class[] { MvcConfig.class };  
  18.     }  
  19.   
  20.     @Override  
  21.     protected String[] getServletMappings() {  
  22.         return new String[] { "/" };  
  23.     }  
  24.   
  25.     @Override  
  26.     protected Filter[] getServletFilters() {  
  27.         return null;  
  28.     }  
  29. }  

【SecurityWebApplicationInitializer.java】:是安全方面的启动组件,与上面的WebApplicationInitializer继承关系类似,可以启动加载一些安全相关的配置和类。暂时不需要实现。

[java] view plain copy
 print?
  1. import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;  
  2.   
  3. public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {  
  4.   
  5. }  


【com.aitongyi.web.back.controller.UserController】:用户访问控制器

[java] view plain copy
 print?
  1. import com.aitongyi.web.service.UserService;  
  2. import org.slf4j.Logger;  
  3. import org.slf4j.LoggerFactory;  
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.security.access.prepost.PreAuthorize;  
  6. import org.springframework.stereotype.Controller;  
  7. import org.springframework.web.bind.annotation.RequestMapping;  
  8. import org.springframework.web.bind.annotation.RequestMethod;  
  9.   
  10. /** 
  11.  * 用户请求处理器 
  12.  * Created by admin on 16/8/6. 
  13.  */  
  14. @Controller  
  15. public class UserController {  
  16.     private static final Logger logger = LoggerFactory.getLogger(UserController.class);  
  17.   
  18.     @Autowired  
  19.     private UserService userService;  
  20.   
  21.     @RequestMapping(value = "/home", method = RequestMethod.GET)  
  22.     @PreAuthorize("isAuthenticated()")// isAuthenticated 如果用户不是匿名用户就返回true  
  23.     public String showHomePage() {  
  24.         try {  
  25.             userService.loadUserByUsername("admin");  
  26.             logger.info("load user ");  
  27.         }catch (Exception e){  
  28.             logger.error(e.getLocalizedMessage(), e);  
  29.         }  
  30.   
  31.         return "/index/index";  
  32.     }  
  33. }  


【日志文件】:logback.xml

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <configuration>  
  3.   
  4.      <appender name="default" class="ch.qos.logback.core.rolling.RollingFileAppender">  
  5.         <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
  6.             <fileNamePattern>/app/logs/back.%d{yyyy-MM-dd}.log</fileNamePattern>  
  7.             <maxHistory>3</maxHistory>  
  8.         </rollingPolicy>  
  9.         <encoder>  
  10.             <pattern>[%-5level][%d{HH:mm:ss}] - [%logger{15}] - %msg%n</pattern>  
  11.             <charset>UTF-8</charset>  
  12.         </encoder>  
  13.     </appender>  
  14.   
  15.     <appender name="console" class="ch.qos.logback.core.ConsoleAppender">  
  16.         <encoder>  
  17.             <pattern>[%-5level][%d{HH:mm:ss}] - [%logger] - %msg%n</pattern>  
  18.             <charset>UTF-8</charset>  
  19.         </encoder>  
  20.     </appender>  
  21.   
  22.     <logger name="org.springframework.jdbc" level="DEBUG" additivity="false">  
  23.         <appender-ref ref="console"/>  
  24.     </logger>  
  25.     <logger name="org.springframework" level="INFO" additivity="false">  
  26.         <appender-ref ref="console"/>  
  27.     </logger>  
  28.     <root level="DEBUG">  
  29.         <appender-ref ref="console"/>  
  30.     </root>  
  31.   
  32. </configuration>  

【数据库配置】:back.properties

[html] view plain copy
 print?
  1. #========= Mysql ============  
  2. jdbc.driver = com.mysql.jdbc.Driver  
  3. db.url = jdbc:mysql://127.0.0.1/web?useUnicode=true&characterEncoding=UTF-8  
  4. db.username = root  
  5. db.password = 123456  
  6. db.maxtotal = 150  
  7. db.minidle = 40  
  8. db.maxidle = 60  


由于配置了数据库信息,所以数据库是必须的,需要你安装一个MySQL,然后创建一个web数据库,创建一张users表,具体字段见下面数据库表创建文件:(登录密码是123456)

[sql] view plain copy
 print?
  1. CREATE TABLE `users` (  
  2.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  3.   `username` varchar(50) NOT NULL,  
  4.   `passwordvarchar(50) NOT NULL,  
  5.   `enabled` tinyint(1) NOT NULL,  
  6.   `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  7.   PRIMARY KEY (`id`),  
  8.   UNIQUE KEY `ix_username` (`username`)  
  9. ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;  


[sql] view plain copy
 print?
  1. INSERT INTO `users` (`id`, `username`, `password`, `enabled`, `create_date`)  
  2. VALUES  
  3.     (1,'admin','e10adc3949ba59abbe56e057f20f883e',1,'2016-06-24 13:17:23'),  
  4.     (2,'user','e10adc3949ba59abbe56e057f20f883e',1,'2016-06-24 13:20:05');  


另外还要创建一张权限表:

[plain] view plain copy
 print?
  1. CREATE TABLE `authorities` (  
  2.   `username` varchar(50) NOT NULL,  
  3.   `authority` varchar(50) NOT NULL,  
  4.   UNIQUE KEY `ix_auth_username` (`username`,`authority`),  
  5.   CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`)  
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  


写入数据:

[plain] view plain copy
 print?
  1. insert into(username, authority) value('admin','ROLE_ADMIN');  


如果你想自己定义密码,就使用

[plain] view plain copy
 print?
  1. String password = md5Encoder.encodePassword(明文密码, null);  

来获取一个数据库中的密码,将password替换数据库的password就可以了。



4.2 【bean】项目

【com.aitongyi.web.bean.User】:用户对象,主要是登陆时做安全验证使用。

[java] view plain copy
 print?
  1. import java.util.Date;  
  2.   
  3. /** 
  4.  * Created by admin on 16/8/8. 
  5.  */  
  6. public class User {  
  7.     private Integer id;  
  8.     private String username;  
  9.     private String password;  
  10.     private boolean enabled;  
  11.     private Date createDate;  
  12.   
  13.     public Date getCreateDate() {  
  14.         return createDate;  
  15.     }  
  16.   
  17.     public void setCreateDate(Date createDate) {  
  18.         this.createDate = createDate;  
  19.     }  
  20.   
  21.     public boolean isEnabled() {  
  22.         return enabled;  
  23.     }  
  24.   
  25.     public void setEnabled(boolean enabled) {  
  26.         this.enabled = enabled;  
  27.     }  
  28.   
  29.     public Integer getId() {  
  30.         return id;  
  31.     }  
  32.   
  33.     public void setId(Integer id) {  
  34.         this.id = id;  
  35.     }  
  36.   
  37.     public String getPassword() {  
  38.         return password;  
  39.     }  
  40.   
  41.     public void setPassword(String password) {  
  42.         this.password = password;  
  43.     }  
  44.   
  45.     public String getUsername() {  
  46.         return username;  
  47.     }  
  48.   
  49.     public void setUsername(String username) {  
  50.         this.username = username;  
  51.     }  
  52. }  


【pom.xml】

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <parent>  
  6.         <artifactId>web</artifactId>  
  7.         <groupId>com.aitongyi.web</groupId>  
  8.         <version>1.0-SNAPSHOT</version>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.   
  12.     <artifactId>bean</artifactId>  
  13.   
  14.   
  15. </project>  



4.3 【dao】项目

DatabaseConfig.java】:数据库配置类

[java] view plain copy
 print?
  1. import org.apache.commons.dbcp2.BasicDataSource;  
  2. import org.apache.ibatis.session.SqlSessionFactory;  
  3. import org.mybatis.spring.SqlSessionFactoryBean;  
  4. import org.slf4j.Logger;  
  5. import org.slf4j.LoggerFactory;  
  6. import org.springframework.beans.factory.annotation.Value;  
  7. import org.springframework.context.annotation.Bean;  
  8. import org.springframework.context.annotation.Configuration;  
  9. import org.springframework.jdbc.datasource.DataSourceTransactionManager;  
  10. import org.springframework.transaction.annotation.EnableTransactionManagement;  
  11.   
  12. import javax.sql.DataSource;  
  13.   
  14. /** 
  15.  * Created by admin on 16/8/8. 
  16.  */  
  17.   
  18. @Configuration  
  19. @EnableTransactionManagement  
  20. public class DatabaseConfig {  
  21.     private static final Logger logger = LoggerFactory.getLogger(DatabaseConfig.class);  
  22.   
  23.     @Value("${jdbc.driver}")  
  24.     private String jdbcDriver;  
  25.   
  26.     @Value("${db.url}")  
  27.     private String dbUrl;  
  28.   
  29.     @Value("${db.username}")  
  30.     private String username;  
  31.   
  32.     @Value("${db.password}")  
  33.     private String password;  
  34.   
  35.     @Value("${db.maxtotal}")  
  36.     private Integer maxTotal;  
  37.   
  38.     @Value("${db.minidle}")  
  39.     private Integer minIdle;  
  40.   
  41.     @Value("${db.maxidle}")  
  42.     private Integer maxIdle;  
  43.   
  44.     @Bean(destroyMethod = "close")  
  45.     public DataSource dataSource() {  
  46.         logger.info("mysql url:"+dbUrl);  
  47.         BasicDataSource dataSource = new BasicDataSource();  
  48.         dataSource.setDriverClassName(jdbcDriver);  
  49.         dataSource.setUrl(dbUrl);  
  50.         dataSource.setUsername(username);  
  51.         dataSource.setPassword(password);  
  52.         dataSource.setMaxTotal(maxTotal);  
  53.         dataSource.setMinIdle(minIdle);  
  54.         dataSource.setMaxIdle(maxIdle);  
  55.         return dataSource;  
  56.     }  
  57.   
  58.     @Bean  
  59.     public DataSourceTransactionManager txManager() {  
  60.         return new DataSourceTransactionManager(dataSource());  
  61.     }  
  62.   
  63.     @Bean  
  64.     public SqlSessionFactory sqlSessionFactory() throws Exception {  
  65.         SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();  
  66.         sessionFactory.setDataSource(dataSource());  
  67.         return sessionFactory.getObject();  
  68.     }  
  69. }  

UserMapper.java】:数据库持久层接口,主要是Mybatis管理

[java] view plain copy
 print?
  1. mport com.aitongyi.web.bean.User;  
  2. import org.apache.ibatis.annotations.Insert;  
  3. import org.apache.ibatis.annotations.Param;  
  4. import org.apache.ibatis.annotations.Select;  
  5.   
  6. /** 
  7.  * 用户数据映射 
  8.  * Created by admin on 16/8/8. 
  9.  */  
  10. public interface UserMapper {  
  11.   
  12.     @Select(value="select username,password,enabled from users where username = #{username}")  
  13.     User loadUserByUsername(@Param("username") String username);  
  14.     @Insert(value="insert into users (username, password, enabled, create_date) value(#{username},#{password},#{enabled},#{createDate})")  
  15.     void saveUser(User user);  
  16. }  

【pom.xml】

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <parent>  
  6.         <artifactId>web</artifactId>  
  7.         <groupId>com.aitongyi.web</groupId>  
  8.         <version>1.0-SNAPSHOT</version>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.   
  12.     <artifactId>dao</artifactId>  
  13.   
  14.   
  15.     <dependencies>  
  16.         <dependency>  
  17.             <groupId>com.aitongyi.web</groupId>  
  18.             <artifactId>bean</artifactId>  
  19.             <version>${project.version}</version>  
  20.         </dependency>  
  21.     </dependencies>  
  22. </project>  

4.4 【service】项目

【UserService】:用户服务接口

[java] view plain copy
 print?
  1. import com.aitongyi.web.bean.User;  
  2. import com.aitongyi.web.dao.mapper.UserMapper;  
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5. import org.springframework.beans.factory.annotation.Autowired;  
  6. import org.springframework.stereotype.Service;  
  7. import org.springframework.transaction.annotation.Transactional;  
  8.   
  9. /** 
  10.  * 用户服务接口 
  11.  * 
  12.  */  
  13. @Service  
  14. public class UserService {  
  15.     private static final Logger logger = LoggerFactory.getLogger(UserService.class);  
  16.    @Autowired  
  17.    private UserMapper userMapper;  
  18.   
  19.   
  20.     @Transactional  
  21.     public User loadUserByUsername(String username) {  
  22.         return userMapper.loadUserByUsername(username);  
  23.     }  
  24.       
  25.     @Transactional  
  26.     public void saveUser(User user) {  
  27.         userMapper.saveUser(user);  
  28. //        测试异常后数据是否回滚  
  29. //        getError();  
  30.     }  
  31.   
  32.     private void getError() {  
  33.         int i = 1 / 0;  
  34.         logger.info("i:{}" , i);  
  35.     }  
  36. }  

4.5 添加git过滤文件

右键选择项目,添加一个过滤文件,在文件中能匹配上的文件将不会通过版本控制软件进行版本控制。



到目前为止,项目的所有文件都已经创建完成,我们点击运行按钮,启动项目,输入用户名:admin,密码:123456,登录,就能看到登录成功

如果你会问,我们没有写登录验证的代码,为什么就自动登录了呢?你试着把密码输错,你会发现你登录不了了!就是这么神奇!

其实这是我们使用SpringSecurity安全框架的原因,安全框架自动会帮我们做一切登录验证的事!你看看日志中有这么一段:

[sql] view plain copy
 print?
  1. Executing prepared SQL statement [select username,password,enabled from users where username = ?]  
这句sql你没有写过吧?这就是安全框架自己做的!关于安全框架的事,就说到这里,展开了十篇文章不一定讲完,还是以后再写吧!

以上内容其实就已经搭建完成一个基本的零配置框架,今天就写到这里,由于时间的关系,我会继续补上以下内容:

1. 可以通过加入任务调度配置来执行任务调度。

2. 可以加入Redis缓存来实现缓存管理。

3. 可以集成shiro安全框架,也可以自己写(个人觉得目前的安全框架文档不全、配置繁琐、使用复杂)

4. 登录页面、首页样式需要调整



目录

        (一)基本介绍    
        (二)基础框架搭建
        (三)实现最基本的登录处理        
        (四)任务调度管理   
        (五)Redis缓存配置
        (六)安全框架集成

        (七) git版本源代码下载


阅读全文
0 0