├── .gitignore ├── README.md ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── pjb │ │ ├── SpringbootMybatisShiroApplication.java │ │ ├── config │ │ ├── MyShiroRealm.java │ │ └── ShiroConfig.java │ │ ├── controller │ │ ├── HomeController.java │ │ └── UserInfoController.java │ │ ├── entity │ │ ├── SysPermission.java │ │ ├── SysRole.java │ │ └── UserInfo.java │ │ ├── mapper │ │ ├── SysPermissionMapper.java │ │ ├── SysRoleMapper.java │ │ └── UserInfoMapper.java │ │ └── service │ │ ├── UserInfoService.java │ │ └── impl │ │ └── UserInfoServiceImpl.java └── resources │ ├── application.yml │ ├── com │ └── pjb │ │ └── mapper │ │ ├── SysPermissionMapper.xml │ │ ├── SysRoleMapper.xml │ │ └── UserInfoMapper.xml │ ├── ehcache-shiro.xml │ └── templates │ ├── 403.html │ ├── index.html │ ├── login.html │ ├── userInfo.html │ ├── userInfoAdd.html │ └── userInfoDel.html └── test └── java └── com └── pjb └── SpringbootMybatisShiroApplicationTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | 12 | ### IntelliJ IDEA ### 13 | .idea 14 | *.iws 15 | *.iml 16 | *.ipr 17 | 18 | ### NetBeans ### 19 | nbproject/private/ 20 | build/ 21 | nbbuild/ 22 | dist/ 23 | nbdist/ 24 | .nb-gradle/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Springboot-Mybatis-Shiro 2 | Springboot+Mybatis+Shiro实现角色权限管理 3 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.pjb 7 | springboot-mybatis-shiro 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | springboot-mybatis-shiro 12 | Demo project for Spring Boot 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.6.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.mybatis.spring.boot 30 | mybatis-spring-boot-starter 31 | 2.1.0 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-thymeleaf 36 | 37 | 38 | 39 | net.sourceforge.nekohtml 40 | nekohtml 41 | 1.9.22 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-web 46 | 47 | 48 | 49 | mysql 50 | mysql-connector-java 51 | 52 | 53 | org.projectlombok 54 | lombok 55 | true 56 | 57 | 58 | 59 | org.apache.shiro 60 | shiro-all 61 | 1.4.1 62 | pom 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-starter-test 67 | test 68 | 69 | 70 | 71 | 72 | 73 | 74 | org.springframework.boot 75 | spring-boot-maven-plugin 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/SpringbootMybatisShiroApplication.java: -------------------------------------------------------------------------------- 1 | package com.pjb; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | @SpringBootApplication 8 | @MapperScan("com.pjb.mapper") 9 | public class SpringbootMybatisShiroApplication { 10 | 11 | public static void main(String[] args) { 12 | SpringApplication.run(SpringbootMybatisShiroApplication.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/config/MyShiroRealm.java: -------------------------------------------------------------------------------- 1 | package com.pjb.config; 2 | 3 | import com.pjb.entity.UserInfo; 4 | import com.pjb.mapper.SysPermissionMapper; 5 | import com.pjb.mapper.SysRoleMapper; 6 | import com.pjb.service.UserInfoService; 7 | import org.apache.shiro.authc.AuthenticationException; 8 | import org.apache.shiro.authc.AuthenticationInfo; 9 | import org.apache.shiro.authc.AuthenticationToken; 10 | import org.apache.shiro.authc.SimpleAuthenticationInfo; 11 | import org.apache.shiro.authz.AuthorizationInfo; 12 | import org.apache.shiro.authz.SimpleAuthorizationInfo; 13 | import org.apache.shiro.realm.AuthorizingRealm; 14 | import org.apache.shiro.subject.PrincipalCollection; 15 | import org.apache.shiro.util.ByteSource; 16 | import org.springframework.beans.factory.annotation.Autowired; 17 | 18 | /** 19 | * @author jinbin 20 | * @date 2017-12-01 21:25 21 | */ 22 | public class MyShiroRealm extends AuthorizingRealm { 23 | @Autowired 24 | UserInfoService userInfoService; 25 | @Autowired 26 | SysRoleMapper sysRoleMapper; 27 | @Autowired 28 | SysPermissionMapper sysPermissionMapper; 29 | @Override 30 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { 31 | System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()"); 32 | SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); 33 | UserInfo userInfo = (UserInfo)principal.getPrimaryPrincipal(); 34 | sysRoleMapper.findRoleByUsername(userInfo.getUsername()).stream().forEach( 35 | sysRole -> { 36 | authorizationInfo.addRole(sysRole.getRole()); 37 | sysPermissionMapper.findPermissionByRoleId(sysRole.getId()).stream().forEach( 38 | sysPermission -> { 39 | authorizationInfo.addStringPermission(sysPermission.getPermission()); 40 | } 41 | ); 42 | } 43 | ); 44 | return authorizationInfo; 45 | } 46 | 47 | @Override 48 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 49 | //获取用户的输入的账号. 50 | String username = (String)token.getPrincipal(); 51 | System.out.println(token.getCredentials()); 52 | //通过username从数据库中查找 User对象,如果找到,没找到. 53 | //实际项目中,这里可以根据实际情况做缓存,如果不做,Shiro自己也是有时间间隔机制,2分钟内不会重复执行该方法 54 | UserInfo userInfo = userInfoService.findByUsername(username); 55 | System.out.println("----->>userInfo="+userInfo); 56 | if(userInfo == null){ 57 | ////没有返回登录用户名对应的SimpleAuthenticationInfo对象时,就会在LoginController中抛出UnknownAccountException异常 58 | return null; 59 | } 60 | return new SimpleAuthenticationInfo( 61 | userInfo, //用户名 62 | userInfo.getPassword(), //密码 63 | ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt 64 | getName() //realm name 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/config/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.pjb.config; 2 | 3 | import org.apache.shiro.authc.credential.HashedCredentialsMatcher; 4 | import org.apache.shiro.cache.ehcache.EhCacheManager; 5 | import org.apache.shiro.mgt.SecurityManager; 6 | import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 7 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 8 | import org.apache.shiro.web.mgt.CookieRememberMeManager; 9 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 10 | import org.apache.shiro.web.servlet.SimpleCookie; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; 14 | 15 | import java.util.LinkedHashMap; 16 | import java.util.Map; 17 | import java.util.Properties; 18 | 19 | /** 20 | * @author jinbin 21 | * @date 2017-12-01 21:31 22 | */ 23 | @Configuration 24 | public class ShiroConfig { 25 | @Bean 26 | public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { 27 | 28 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 29 | shiroFilterFactoryBean.setSecurityManager(securityManager); 30 | 31 | Map filterChainDefinitionMap = new LinkedHashMap<>(); 32 | filterChainDefinitionMap.put("/logout", "logout"); 33 | filterChainDefinitionMap.put("/index", "user"); 34 | filterChainDefinitionMap.put("/", "user"); 35 | filterChainDefinitionMap.put("/favicon.ico", "anon"); 36 | filterChainDefinitionMap.put("/**", "authc"); 37 | //authc表示需要验证身份才能访问,还有一些比如anon表示不需要验证身份就能访问等。 38 | shiroFilterFactoryBean.setLoginUrl("/login"); 39 | shiroFilterFactoryBean.setSuccessUrl("/index"); 40 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); 41 | return shiroFilterFactoryBean; 42 | } 43 | 44 | 45 | //SecurityManager 是 Shiro 架构的核心,通过它来链接Realm和用户(文档中称之为Subject.) 46 | @Bean 47 | public SecurityManager securityManager() { 48 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 49 | securityManager.setRealm(myShiroRealm()); //将Realm注入到SecurityManager中。 50 | securityManager.setCacheManager(ehCacheManager()); //注入缓存对象。 51 | securityManager.setRememberMeManager(cookieRememberMeManager());//注入rememberMeManager; 52 | return securityManager; 53 | } 54 | 55 | @Bean 56 | public MyShiroRealm myShiroRealm() { 57 | MyShiroRealm myShiroRealm = new MyShiroRealm(); 58 | myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); //设置解密规则 59 | return myShiroRealm; 60 | } 61 | 62 | //因为我们的密码是加过密的,所以,如果要Shiro验证用户身份的话,需要告诉它我们用的是md5加密的,并且是加密了两次。同时我们在自己的Realm中也通过SimpleAuthenticationInfo返回了加密时使用的盐。这样Shiro就能顺利的解密密码并验证用户名和密码是否正确了。 63 | @Bean 64 | public HashedCredentialsMatcher hashedCredentialsMatcher() { 65 | HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher(); 66 | //散列算法:这里使用MD5算法; 67 | hashedCredentialsMatcher.setHashAlgorithmName("md5"); 68 | //散列的次数,比如散列两次,相当于 md5(md5("")); 69 | hashedCredentialsMatcher.setHashIterations(2); 70 | return hashedCredentialsMatcher; 71 | } 72 | /** 73 | * 开启shiro aop注解支持. 74 | * 使用代理方式;所以需要开启代码支持; 75 | * @param securityManager 76 | * @return 77 | */ 78 | @Bean 79 | public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ 80 | AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); 81 | authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); 82 | return authorizationAttributeSourceAdvisor; 83 | } 84 | @Bean 85 | public SimpleMappingExceptionResolver resolver() { 86 | SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver(); 87 | Properties properties = new Properties(); 88 | properties.setProperty("org.apache.shiro.authz.UnauthorizedException", "/403"); 89 | resolver.setExceptionMappings(properties); 90 | return resolver; 91 | } 92 | @Bean 93 | public EhCacheManager ehCacheManager() { 94 | EhCacheManager ehCacheManager = new EhCacheManager(); 95 | ehCacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml"); 96 | return ehCacheManager; 97 | } 98 | 99 | /** 100 | * cookie对象; 101 | */ 102 | @Bean 103 | public SimpleCookie rememberMeCookie() { 104 | //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe 105 | SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); 106 | // 107 | simpleCookie.setMaxAge(259200); 108 | return simpleCookie; 109 | } 110 | 111 | /** 112 | * cookie管理对象; 113 | */ 114 | @Bean 115 | public CookieRememberMeManager cookieRememberMeManager() { 116 | CookieRememberMeManager manager = new CookieRememberMeManager(); 117 | manager.setCookie(rememberMeCookie()); 118 | return manager; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/controller/HomeController.java: -------------------------------------------------------------------------------- 1 | package com.pjb.controller; 2 | 3 | import org.apache.shiro.authc.IncorrectCredentialsException; 4 | import org.apache.shiro.authc.UnknownAccountException; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author jinbin 13 | * @date 2017-12-01 21:35 14 | */ 15 | @Controller 16 | public class HomeController { 17 | @RequestMapping({"/","/index"}) 18 | public String index(){ 19 | return"/index"; 20 | } 21 | 22 | // 这里如果不写method参数的话,默认支持所有请求,如果想缩小请求范围,还是要添加method来支持get, post等等某个请求。 23 | @RequestMapping("/login") 24 | public String login(HttpServletRequest request, Map map) { 25 | // 登录失败从request中获取shiro处理的异常信息。 26 | // shiroLoginFailure:就是shiro异常类的全类名. 27 | Object exception = request.getAttribute("shiroLoginFailure"); 28 | String msg = ""; 29 | if (exception != null) { 30 | if (exception instanceof UnknownAccountException) { 31 | msg = "账户不存在或密码不正确"; 32 | } else if (exception instanceof IncorrectCredentialsException) { 33 | msg = "账户不存在或密码不正确"; 34 | } else { 35 | msg = "其他异常"; 36 | } 37 | } 38 | 39 | map.put("msg", msg); 40 | // 此方法不处理登录成功,由shiro进行处理. 41 | return "login"; 42 | } 43 | 44 | @RequestMapping("/403") 45 | public String unauthorizedRole(){ 46 | return "403"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/controller/UserInfoController.java: -------------------------------------------------------------------------------- 1 | package com.pjb.controller; 2 | 3 | import org.apache.shiro.authz.annotation.RequiresPermissions; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | 7 | /** 8 | * @author jinbin 9 | * @date 2017-12-01 21:36 10 | */ 11 | @Controller 12 | @RequestMapping("/userInfo") 13 | public class UserInfoController { 14 | /** 15 | * 用户查询. 16 | */ 17 | @RequestMapping("/userList") 18 | @RequiresPermissions("userInfo:view") 19 | public String userInfo(){ 20 | return "userInfo"; 21 | } 22 | 23 | /** 24 | * 用户添加; 25 | */ 26 | @RequestMapping("/userAdd") 27 | @RequiresPermissions("userInfo:add") 28 | public String userInfoAdd(){ 29 | return "userInfoAdd"; 30 | } 31 | 32 | /** 33 | * 用户删除; 34 | * @return 35 | */ 36 | @RequestMapping("/userDel") 37 | @RequiresPermissions("userInfo:del") 38 | public String userDel(){ 39 | return "userInfoDel"; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/entity/SysPermission.java: -------------------------------------------------------------------------------- 1 | package com.pjb.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | /** 8 | * @author jinbin 9 | * @date 2017-12-01 20:55 10 | */ 11 | @Data 12 | @AllArgsConstructor 13 | @NoArgsConstructor 14 | public class SysPermission { 15 | Integer id;//主键. 16 | String name;//名称. 17 | String url;//资源路径. 18 | String permission; //权限字符串 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/entity/SysRole.java: -------------------------------------------------------------------------------- 1 | package com.pjb.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author jinbin 11 | * @date 2017-12-01 20:54 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class SysRole { 17 | Integer id; 18 | String role;//角色标识程序中判断使用,如"admin",这个是唯一的: 19 | String description; // 角色描述,UI界面显示使用 20 | private Boolean available = Boolean.FALSE; // 是否可用,如果不可用将不会添加给用户 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/entity/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.pjb.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author jinbin 11 | * @date 2017-12-01 20:52 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | @NoArgsConstructor 16 | public class UserInfo { 17 | Integer uid;//用户id 18 | String username;//帐号 19 | String name; 20 | String password; 21 | String salt; 22 | byte state; 23 | /** 24 | * 密码盐. 25 | * @return 26 | */ 27 | public String getCredentialsSalt(){ 28 | 29 | return this.username+this.salt; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/mapper/SysPermissionMapper.java: -------------------------------------------------------------------------------- 1 | package com.pjb.mapper; 2 | 3 | import com.pjb.entity.SysPermission; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author jinbin 11 | * @date 2017-12-01 21:12 12 | */ 13 | @Component 14 | public interface SysPermissionMapper { 15 | //根据角色ID查询角色对应的权限信息 16 | List findPermissionByRoleId(@Param("roleId") Integer roleId); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/mapper/SysRoleMapper.java: -------------------------------------------------------------------------------- 1 | package com.pjb.mapper; 2 | 3 | import com.pjb.entity.SysRole; 4 | import org.apache.ibatis.annotations.Param; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * @author jinbin 11 | * @date 2017-12-01 21:02 12 | */ 13 | @Component 14 | public interface SysRoleMapper { 15 | //通过username查找用户角色信息 16 | List findRoleByUsername(@Param("username") String username); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/mapper/UserInfoMapper.java: -------------------------------------------------------------------------------- 1 | package com.pjb.mapper; 2 | 3 | import com.pjb.entity.UserInfo; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * @author jinbin 12 | * @date 2017-12-01 20:58 13 | */ 14 | @Component 15 | public interface UserInfoMapper { 16 | //通过username查找用户信息 17 | UserInfo findByUsername(@Param("username") String username); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/service/UserInfoService.java: -------------------------------------------------------------------------------- 1 | package com.pjb.service; 2 | 3 | import com.pjb.entity.UserInfo; 4 | 5 | /** 6 | * @author jinbin 7 | * @date 2017-12-01 21:22 8 | */ 9 | public interface UserInfoService { 10 | /**通过username查找用户信息;*/ 11 | UserInfo findByUsername(String username); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/pjb/service/impl/UserInfoServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.pjb.service.impl; 2 | 3 | import com.pjb.entity.UserInfo; 4 | import com.pjb.mapper.UserInfoMapper; 5 | import com.pjb.service.UserInfoService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * @author jinbin 11 | * @date 2017-12-01 21:22 12 | */ 13 | @Service("UserInfoService") 14 | public class UserInfoServiceImpl implements UserInfoService { 15 | @Autowired 16 | UserInfoMapper userInfoMapper; 17 | @Override 18 | public UserInfo findByUsername(String username) { 19 | return userInfoMapper.findByUsername(username); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | url: jdbc:mysql://localhost:3306/test1?useSSL=false&serverTimezone=UTC 4 | username: root 5 | password: 1997 6 | driver-class-name: com.mysql.cj.jdbc.Driver 7 | thymeleaf: 8 | cache: false 9 | mode: LEGACYHTML5 10 | mybatis: 11 | type-aliases-package: com.pjb.entity 12 | mapper-locations: classpath*:com.pjb.mapper/*.xml -------------------------------------------------------------------------------- /src/main/resources/com/pjb/mapper/SysPermissionMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | -------------------------------------------------------------------------------- /src/main/resources/com/pjb/mapper/SysRoleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 23 | -------------------------------------------------------------------------------- /src/main/resources/com/pjb/mapper/UserInfoMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | -------------------------------------------------------------------------------- /src/main/resources/ehcache-shiro.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 25 | 34 | 35 | 36 | 37 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/main/resources/templates/403.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

403没有权限

9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

index

9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 错误信息:

9 |
10 |

账号:

11 |

密码:

12 |

13 |

记住我

14 |
15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/templates/userInfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

用户查询界面

9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/templates/userInfoAdd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

用户添加界面

9 | 10 | -------------------------------------------------------------------------------- /src/main/resources/templates/userInfoDel.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

用户删除界面

9 | 10 | -------------------------------------------------------------------------------- /src/test/java/com/pjb/SpringbootMybatisShiroApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.pjb; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class SpringbootMybatisShiroApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | --------------------------------------------------------------------------------