spring boot + mybatis + spring security(自定义登录界面)环境搭建

概述

在前不久用了spring boot、mybatis、spring security搭建了一个工程,中间经历了各种坑,最后得到一条经验:spring的文档很详细,入门最好以官方文档为准。

这里讲的是以mav作为依赖管理工具

pom

搭建spring boot应用快捷的方式是在pom.xml中引入spring-boot-starter-parent 作为parent,如下:
[java]  view plain  copy
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.     <modelVersion>4.0.0</modelVersion>  
  4.     <groupId>com.tw</groupId>  
  5.     <artifactId>twboot</artifactId>  
  6.     <packaging>war</packaging>  
  7.     <version>0.0.1-SNAPSHOT</version>  
  8.     <name>twboot Maven Webapp</name>  
  9.     <url>http://maven.apache.org</url>  
  10.   
  11.     <properties>  
  12.         <mybatis-spring-boot>1.2.0</mybatis-spring-boot>  
  13.     </properties>  
  14.   
  15.     <!-- Spring Boot 启动父依赖 -->  
  16.     <parent>  
  17.         <groupId>org.springframework.boot</groupId>  
  18.         <artifactId>spring-boot-starter-parent</artifactId>  
  19.         <version>1.5.9.RELEASE</version>  
  20.     </parent>  
  21.   
  22.     <dependencies>  
  23.         <!-- 模板引擎jar包, 已经包括了spring-boot-starter-web -->  
  24.         <dependency>  
  25.             <groupId>org.springframework.boot</groupId>  
  26.             <artifactId>spring-boot-starter-thymeleaf</artifactId>  
  27.         </dependency>  
  28.   
  29.         <!-- Spring Boot Test 依赖 -->  
  30.         <dependency>  
  31.             <groupId>org.springframework.boot</groupId>  
  32.             <artifactId>spring-boot-starter-test</artifactId>  
  33.             <scope>test</scope>  
  34.         </dependency>  
  35.   
  36.         <!-- security -->  
  37.         <dependency>  
  38.             <groupId>org.springframework.boot</groupId>  
  39.             <artifactId>spring-boot-starter-security</artifactId>  
  40.         </dependency>  
  41.           
  42.         <!-- 用于thymeleaf中使用security的标签 -->  
  43.         <dependency>  
  44.             <groupId>org.thymeleaf.extras</groupId>  
  45.             <artifactId>thymeleaf-extras-springsecurity4</artifactId>  
  46.         </dependency>  
  47.   
  48.         <!-- Spring Boot Mybatis 依赖 -->  
  49.         <dependency>  
  50.             <groupId>org.mybatis.spring.boot</groupId>  
  51.             <artifactId>mybatis-spring-boot-starter</artifactId>  
  52.             <version>${mybatis-spring-boot}</version>  
  53.         </dependency>  
  54.   
  55.         <!-- Junit -->  
  56.         <dependency>  
  57.             <groupId>junit</groupId>  
  58.             <artifactId>junit</artifactId>  
  59.         </dependency>  
  60.   
  61.         <!-- 上传组件包 -->  
  62.         <dependency>  
  63.             <groupId>commons-fileupload</groupId>  
  64.             <artifactId>commons-fileupload</artifactId>  
  65.             <version>1.3.1</version>  
  66.         </dependency>  
  67.   
  68.         <dependency>  
  69.             <groupId>commons-io</groupId>  
  70.             <artifactId>commons-io</artifactId>  
  71.             <version>2.4</version>  
  72.         </dependency>  
  73.           
  74.         <dependency>  
  75.                 <groupId>javax.servlet</groupId>  
  76.                 <artifactId>servlet-api</artifactId>  
  77.                 <version>2.5</version>  
  78.         </dependency>  
  79.   
  80.     </dependencies>  
  81.   
  82.     <build>  
  83.         <finalName>twboot</finalName>  
  84.     </build>  
  85. </project>  

application.yml

spring boot 中默认会获取classpath下的application.yml或者application.propertis文件作为配置文件
我用的前者
[java]  view plain  copy
  1. server:  
  2.   port: 80  
  3. spring:  
  4.   datasource:  
  5.     username: xyz  
  6.     password: xyz  
  7.     driver-class-name: oracle.jdbc.driver.OracleDriver  
  8.     url: jdbc:oracle:thin:@127.0.0.1:1521:XE  
  9.     dbcp2:  
  10.       max-idle: 10  
  11.       validation-query: select 1 from dual  
  12.     
  13.   thymeleaf:  
  14.     cache: false  
  15.     prefix: classpath:/templates/  
  16.     suffix: .html  
  17.       
  18. mybatis:  
  19.   type-aliases-package: com.tw.entity  
  20.   mapper-locations:  
  21.     - classpath:mapping/*.xml  
  22.           

上面的server.port 表示spring boot内置tomcat启动的端口是80,view层显示用的thymeleaf模板,模板前后缀也在配置文件中定义,这个和spring mvc那种配置类似;

另工程中只用用一种view表示方式,用了thymeleaf就不要用jsp了,网上说的两种模板解析链是有先后处理顺序的,也就是说是有优先级;

Springboot启动类

在我们的package最顶层新建一个继承SpringBootServletInitializer的类(内容如下),这样一个spring boot项目就搭建好了

[java]  view plain  copy
  1. package com.tw;  
  2.   
  3. import org.mybatis.spring.annotation.MapperScan;  
  4. import org.springframework.boot.SpringApplication;  
  5. import org.springframework.boot.autoconfigure.SpringBootApplication;  
  6. import org.springframework.boot.builder.SpringApplicationBuilder;  
  7. import org.springframework.boot.web.support.SpringBootServletInitializer;  
  8.   
  9. @SpringBootApplication  
  10. @MapperScan("com.tw.dao")  
  11. public class StartApp extends SpringBootServletInitializer {  
  12.     public static void main(String[] args) {  
  13.         SpringApplication.run(StartApp.class);  
  14.     }  
  15.   
  16.     //添加Tomcat支持  
  17.     @Override  
  18.     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  
  19.         return application.sources(StartApp.class);  
  20.     }  
  21. }  

上面的
@SpringBootApplication 表面这是一个springboot应用,
@MapperScan("com.tw.dao")  这个表示 mybatis自动扫描dao接口的包名
这个包下的接口会自动和spring boot配置项mapper-locations中的mybatis sql配置文件映射

Controller

在spring boot中controller分为两类,一种是返回数据的Controller,一种是返回视图的Controller,分别注解是

@RestController
@Controller
我这里写一个简单的controller
[java]  view plain  copy
  1. package com.tw.controller;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.UnsupportedEncodingException;  
  5. import java.util.Map;  
  6.   
  7. import javax.servlet.ServletResponse;  
  8.   
  9. import org.springframework.security.access.prepost.PreAuthorize;  
  10. import org.springframework.stereotype.Controller;  
  11. import org.springframework.ui.Model;  
  12. import org.springframework.web.bind.annotation.RequestMapping;  
  13.   
  14. @Controller  
  15. public class CommonController {  
  16.   
  17.     @PreAuthorize("hasRole('RRR')")  
  18.     @RequestMapping(value={"/","/home"})  
  19.     public String index() {  
  20.         return "home/home";  
  21.     }  
  22.       
  23.     @RequestMapping("/login")  
  24.     public String login(Model model) {  
  25.         System.out.println("to login----");  
  26.         return "login/login";  
  27.     }  
  28.       
  29.     @RequestMapping("/thymeleaf")  
  30.     public String test(Map<String,Object> map,ServletResponse response) throws UnsupportedEncodingException, IOException{  
  31.         map.put("name""test");  
  32.         System.out.println("thymeleaf----");  
  33.         return "thymeleaf/hello2";  
  34.     }  
  35.       
  36.     /** 
  37.      * 功能描述:角色管理 
  38.      * CHENY037 2017年11月29日 
  39.      * @return 
  40.      */  
  41.     @RequestMapping("/roleManage")  
  42.     @PreAuthorize("hasRole('ROLE_MANAGE')")  
  43.     public String roleManage(){  
  44.         return "home/role";  
  45.     }  
  46.       
  47. }  

spring security

自定义登录界面和自定义用户名密码校验
配置类:
[java]  view plain  copy
  1. package com.tw.config.Security;  
  2.   
  3.   
  4. import org.springframework.beans.factory.annotation.Autowired;  
  5. import org.springframework.context.annotation.Bean;  
  6. import org.springframework.context.annotation.Configuration;  
  7. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;  
  8. import org.springframework.security.config.annotation.web.builders.HttpSecurity;  
  9. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;  
  10. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;  
  11. import org.springframework.security.core.session.SessionRegistry;  
  12. import org.springframework.security.core.session.SessionRegistryImpl;  
  13. import org.springframework.security.crypto.password.PasswordEncoder;  
  14.   
  15.   
  16. /** 
  17.  * 配置类: 
  18.  * 配置security的登录页面和传递的参数,公共路径权限属性等 
  19.  *  
  20.  * @author CHENY037 
  21.  * 
  22.  */  
  23. @Configuration  
  24. @EnableWebSecurity  
  25. public class WebSecurityConfig extends WebSecurityConfigurerAdapter {  
  26.   
  27.     @Autowired  
  28.     private UrlUserService urlUserService;  
  29.       
  30.     @Autowired  
  31.     SessionRegistry sessionRegistry;  
  32.   
  33.     @Override  
  34.     protected void configure(HttpSecurity http) throws Exception {  
  35.         http.csrf().disable()  
  36.                 .authorizeRequests()  
  37.                 .antMatchers("/login").permitAll()  
  38. //                .antMatchers("/logout").permitAll()  
  39.                 .antMatchers("/img/**").permitAll()  
  40.                 .antMatchers("/js/**").permitAll()  
  41.                 .antMatchers("/css/**").permitAll()  
  42.                 .antMatchers("/bootstrap/**").permitAll()  
  43.                 .antMatchers("/fonts/**").permitAll()  
  44.                 .antMatchers("/favicon.ico").permitAll()  
  45.                 .anyRequest().authenticated()  
  46.                 //登录相关  
  47.                 .and().formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/home")  
  48.                 .and().sessionManagement().maximumSessions(1).sessionRegistry(sessionRegistry)  
  49.                 .and().and()  
  50.                 .logout()  
  51.                 .invalidateHttpSession(true)  
  52.                 .clearAuthentication(true)  
  53.                 .and()  
  54.                 .httpBasic();  
  55.     }  
  56.       
  57.       
  58.     @Autowired  
  59.     public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {  
  60.         //这里是新增一个默认用户  
  61.         auth.inMemoryAuthentication().withUser("huahua").password("hello").roles("ADMIN");  
  62.     }  
  63.   
  64.     @Override  
  65.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {  
  66.         auth.userDetailsService(urlUserService).passwordEncoder(new PasswordEncoder() {  
  67.   
  68.             @Override  
  69.             public String encode(CharSequence rawPassword) {  
  70.                 return (String)rawPassword;//MD5Util.encode((String) rawPassword);  
  71.             }  
  72.   
  73.             @Override  
  74.             public boolean matches(CharSequence rawPassword, String encodedPassword) {  
  75.                 System.out.println(encodedPassword + "---" + (String)rawPassword);  
  76.                 return encodedPassword.equals((String) rawPassword);  
  77.             }  
  78.         });  
  79.     }  
  80.   
  81.     @Bean  
  82.     public SessionRegistry getSessionRegistry(){  
  83.         SessionRegistry sessionRegistry = new SessionRegistryImpl();  
  84.         return sessionRegistry;  
  85.     }  
  86. }  
自定义用户名密码校验类
[java]  view plain  copy
  1. package com.tw.config.Security;  
  2.   
  3.   
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.security.core.GrantedAuthority;  
  9. import org.springframework.security.core.authority.SimpleGrantedAuthority;  
  10. import org.springframework.security.core.userdetails.User;  
  11. import org.springframework.security.core.userdetails.UserDetails;  
  12. import org.springframework.security.core.userdetails.UserDetailsService;  
  13. import org.springframework.security.core.userdetails.UsernameNotFoundException;  
  14. import org.springframework.stereotype.Service;  
  15.   
  16. import com.tw.dao.RoleDao;  
  17. import com.tw.dao.UserDao;  
  18. import com.tw.entity.role.TwRole;  
  19. import com.tw.entity.role.TwUser;  
  20.   
  21. /** 
  22.  * 自定义用户名密码校验实现 
  23.  *  
  24.  * @author CHANY037 2017-11 
  25.  * 
  26.  */  
  27. @Service  
  28. public class UrlUserService implements UserDetailsService {  
  29.       
  30.     @Autowired  
  31.     UserDao userDao;  
  32.       
  33.     @Autowired  
  34.     RoleDao roleDao;  
  35.       
  36.     /** 
  37.      * employeeId 用户工号,在数据库中保证存储唯一 
  38.      */  
  39.     @Override  
  40.     public UserDetails loadUserByUsername(String employeeId) { //重写loadUserByUsername 方法获得 userdetails 类型用户  
  41.   
  42.         TwUser user = userDao.findByEmployeeId(employeeId);  
  43.           
  44.         if(user == null){  
  45.             throw new UsernameNotFoundException(employeeId + " do not exist!");  
  46.         } else {  
  47.             System.out.println(user.getPassword() + " --pw-- ");  
  48.             List<TwRole> roles = roleDao.findRoleByEmployeeId(employeeId);  
  49.             List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();  
  50.               
  51.             //写入用户的角色  ***  切记 由于框架原因 角色名称要以 ROLE_ 开头 **** 血泪史 ****  
  52.             //源码:org.springframework.security.access.expression.SecurityExpressionRoot hasAnyRole()  
  53.             for (TwRole role : roles) {  
  54.                 if (role != null && role.getRoleName() != null) {  
  55.                     SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority(role.getRoleCode());  
  56.                     grantedAuthorities.add(grantedAuthority);  
  57.                 }  
  58.             }  
  59.             org.springframework.security.core.userdetails.User uu = new User(employeeId, user.getPassword(), grantedAuthorities);  
  60.             return uu;  
  61.         }  
  62.     }  
  63. }  

登录界面html 即 上面
[java]  view plain  copy
  1. CommonController 里定义的login方法返回的视图  
[java]  view plain  copy
  1.   
[java]  view plain  copy
  1. <!doctype html>  
  2. <html lang="en" class="no-js"   
  3.          xmlns="http://www.w3.org/1999/xhtml"   
  4.          xmlns:th="http://www.thymeleaf.org"  
  5.          xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">  
  6. <head>  
  7. <meta charset="UTF-8"/>  
  8.   
  9. <title>Login</title>  
  10. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>  
  11. <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />  
  12. <!--  thymeleaf 默认从resources 下的 static目录获取 -->  
  13. <link rel="stylesheet" th:href="@{bootstrap/css/bootstrap.min.css}"/>  
  14. <script th:src="@{js/jquery.min.js}"></script>  
  15. <script th:src="@{bootstrap/js/bootstrap.min.js}"></script>  
  16. <style>  
  17. .form-control{  
  18. width: 200px;  
  19. }  
  20. </style>  
  21. </head>  
  22.   
  23. <body style="background: url(img/login.jpg);width: 98%;">  
  24.   
  25. <div style="margin-top: 150px;margin-left: 800px;margin-bottom: 160px;" >  
  26.   
  27.     <form class="form-horizontal" method="post" th:action="@{/login}">  
  28.             <div class="form-group">  
  29.                 <label for="inputEmail3" class="col-sm-2 control-label">用户名</label>  
  30.                 <div class="col-sm-10"><input autocomplete="off" type="text" class="form-control" name="username" /></div>  
  31.             </div>  
  32.             <div class="form-group">  
  33.                 <label for="inputPassword3" class="col-sm-2 control-label">密码</label>  
  34.                 <div class="col-sm-10">  
  35.                 <input type="text" class="form-control" name="password" οnfοcus="this.type='password'"/>  
  36.                 </div>  
  37.             </div>  
  38.             <div class="form-group">  
  39.                 <div class="col-sm-offset-2 col-sm-10">  
  40.                     <div class="checkbox">  
  41.                          <label><input type="checkbox" />Remember me</label><!-- 功能暂未实现 -->  
  42.                     </div>  
  43.                 </div>  
  44.             </div>  
  45.             <div class="form-group">  
  46.                 <div class="col-sm-offset-2 col-sm-10">  
  47.                      <button type="submit" class="btn btn-default">登录</button>  
  48.                 </div>  
  49.             </div>  
  50.     </form>  
  51. </div>  
  52.   
  53. <!-- 引入 页脚 -->  
  54. <div th:replace="common/footer :: footer"></div>  
  55.   
  56. </body>  
  57. </html>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值