测试项目已上传到GitHub:https://github.com/xiaostudy/springboot_shiro_test1
1、创建springboot项目






1 1 <!-- 数据库连接池 --> 2 2 <dependency> 3 3 <groupId>com.alibaba</groupId> 4 4 <artifactId>druid</artifactId> 5 5 <version>1.1.10</version> 6 6 </dependency> 7 7 <!-- Shiro --> 8 8 <dependency> 9 9 <groupId>org.apache.shiro</groupId> 1010 <artifactId>shiro-spring</artifactId> 1111 <version>1.3.2</version> 1212 </dependency> 1313 <!-- log4j --> 1414 <dependency> 1515 <groupId>log4j</groupId> 1616 <artifactId>log4j</artifactId> 1717 <version>1.2.17</version> 1818 </dependency>





src\main\webapp\


2、创建实体类

PermissionEntity.java
1 1 package com.xiaostudy.shiro_test1.entity; 2 2 3 3 import java.io.Serializable; 4 4 5 5 /** 6 6 * 权限实体类 7 7 * Created with IntelliJ IDEA. 8 8 * User: Administrator 9 9 * Date: 2019/6/8 1010 * Time: 14:21 1111 * Description: No Description 1212 */ 1313 public class PermissionEntity implements Serializable { 1414 private String id; 1515 private String name; 1616 private String url; 1717 1818 public String getId() { 1919 return id; 2020 } 2121 2222 public void setId(String id) { 2323 this.id = id; 2424 } 2525 2626 public String getName() { 2727 return name; 2828 } 2929 3030 public void setName(String name) { 3131 this.name = name; 3232 } 3333 3434 public String getUrl() { 3535 return url; 3636 } 3737 3838 public void setUrl(String url) { 3939 this.url = url; 4040 } 4141 }

1 1 package com.xiaostudy.shiro_test1.entity; 2 2 3 3 import java.io.Serializable; 4 4 import java.util.HashSet; 5 5 import java.util.Set; 6 6 7 7 /** 8 8 * 角色实体类 9 9 * Created with IntelliJ IDEA. 1010 * User: Administrator 1111 * Date: 2019/6/8 1212 * Time: 14:24 1313 * Description: No Description 1414 */ 1515 public class RoleEntity implements Serializable { 1616 private String id; 1717 private String name; 1818 private Set<PermissionEntity> permissions = new HashSet<>(); 1919 2020 public String getId() { 2121 return id; 2222 } 2323 2424 public void setId(String id) { 2525 this.id = id; 2626 } 2727 2828 public String getName() { 2929 return name; 3030 } 3131 3232 public void setName(String name) { 3333 this.name = name; 3434 } 3535 3636 public Set<PermissionEntity> getPermissions() { 3737 return permissions; 3838 } 3939 4040 public void setPermissions(Set<PermissionEntity> permissions) { 4141 this.permissions = permissions; 4242 } 4343 }

1 1 package com.xiaostudy.shiro_test1.entity; 2 2 3 3 import java.io.Serializable; 4 4 import java.util.HashSet; 5 5 import java.util.Set; 6 6 7 7 /** 8 8 * 用户实体类 9 9 * Created with IntelliJ IDEA. 1010 * User: Administrator 1111 * Date: 2019/6/8 1212 * Time: 14:26 1313 * Description: No Description 1414 */ 1515 public class UserEntity implements Serializable { 1616 private String id; 1717 private String name; 1818 private String password; 1919 private Set<RoleEntity> roles = new HashSet<>(); 2020 2121 public String getId() { 2222 return id; 2323 } 2424 2525 public void setId(String id) { 2626 this.id = id; 2727 } 2828 2929 public String getName() { 3030 return name; 3131 } 3232 3333 public void setName(String name) { 3434 this.name = name; 3535 } 3636 3737 public String getPassword() { 3838 return password; 3939 } 4040 4141 public void setPassword(String password) { 4242 this.password = password; 4343 } 4444 4545 public Set<RoleEntity> getRoles() { 4646 return roles; 4747 } 4848 4949 public void setRoles(Set<RoleEntity> roles) { 5050 this.roles = roles; 5151 } 5252 }
实体类entity,也可以叫bean、domain,具体叫什可以根据自己的喜欢选取
3、数据库创建表和添加数据


1 1 DROP TABLE IF EXISTS `role_permission`; 2 2 DROP TABLE IF EXISTS `permission`; 3 3 DROP TABLE IF EXISTS `user_role`; 4 4 DROP TABLE IF EXISTS `role`; 5 5 DROP TABLE IF EXISTS `user`; 6 6 7 7 CREATE TABLE `user` ( 8 8 `id` VARCHAR(255) PRIMARY KEY, 9 9 `name` VARCHAR(255), 1010 `password` VARCHAR(255) 1111 ) engine = InnoDB default charset = utf8 comment = '用户表'; 1212 1313 CREATE TABLE `role` ( 1414 `id` VARCHAR(255) PRIMARY KEY, 1515 `name` VARCHAR(255) 1616 ) engine = InnoDB default charset = utf8 comment = '角色表'; 1717 1818 CREATE TABLE `user_role` ( 1919 `id` VARCHAR(255) PRIMARY KEY, 2020 `user_id` VARCHAR(255), 2121 `role_id` VARCHAR(255), 2222 FOREIGN KEY (`user_id`) REFERENCES `user`(id), 2323 FOREIGN KEY (`role_id`) REFERENCES `role`(id) 2424 ) engine = InnoDB default charset = utf8 comment = '用户与角色多对多表'; 2525 2626 CREATE TABLE `permission` ( 2727 `id` VARCHAR(255) PRIMARY KEY, 2828 `name` VARCHAR(255), 2929 `url` VARCHAR(255) 3030 ) engine = InnoDB default charset = utf8 comment = '权限表'; 3131 3232 CREATE TABLE `role_permission` ( 3333 `id` VARCHAR(255) PRIMARY KEY, 3434 `role_id` VARCHAR(255), 3535 `permission_id` VARCHAR(255), 3636 FOREIGN KEY (`role_id`) REFERENCES `role`(id), 3737 FOREIGN KEY (`permission_id`) REFERENCES `permission`(id) 3838 ) engine = InnoDB default charset = utf8 comment = '角色与权限多对多表'; 3939 4040 insert into `user` (`id`, `name`, `password`) values('1','admin','123456'); 4141 insert into `user` (`id`, `name`, `password`) values('2','vip','123456'); 4242 insert into `user` (`id`, `name`, `password`) values('3','svip','1234'); 4343 4444 insert into `role` (`id`, `name`) values('1','user'); 4545 insert into `role` (`id`, `name`) values('2','vip'); 4646 insert into `role` (`id`, `name`) values('3','svip'); 4747 4848 insert into `permission` (`id`, `name`, `url`) values('1','user','user'); 4949 insert into `permission` (`id`, `name`, `url`) values('2','vip','vip'); 5050 insert into `permission` (`id`, `name`, `url`) values('3','svip','svip'); 5151 5252 insert into `user_role` (`id`, `user_id`, `role_id`) values('1','1','1'); 5353 insert into `user_role` (`id`, `user_id`, `role_id`) values('2','2','1'); 5454 insert into `user_role` (`id`, `user_id`, `role_id`) values('3','2','2'); 5555 insert into `user_role` (`id`, `user_id`, `role_id`) values('4','3','1'); 5656 insert into `user_role` (`id`, `user_id`, `role_id`) values('5','3','2'); 5757 insert into `user_role` (`id`, `user_id`, `role_id`) values('6','3','3'); 5858 5959 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('1','1','1'); 6060 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('2','2','1'); 6161 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('3','2','2'); 6262 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('4','3','1'); 6363 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('5','3','2'); 6464 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('6','3','3');
4、接下来写mapper,也叫dao

1 1 package com.xiaostudy.shiro_test1.mapper; 2 2 3 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 4 import org.apache.ibatis.annotations.Mapper; 5 5 6 6 /** 7 7 * Created with IntelliJ IDEA. 8 8 * User: Administrator 9 9 * Date: 2019/6/8 1010 * Time: 14:45 1111 * Description: No Description 1212 */ 1313 @Mapper 1414 public interface UserMapper { 1515 1616 // 根据用户名称,查询用户信息 1717 public UserEntity findByName(String name); 1818 1919 // 根据用户id,查询用户信息、角色、权限 2020 public UserEntity findById(String id); 2121 }
@Mapper后面再讲,这里也可以不用@Mapper


1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 3 <mapper namespace="com.xiaostudy.shiro_test1.mapper.UserMapper"> 4 4 5 5 <resultMap id="userMap" type="com.xiaostudy.shiro_test1.entity.UserEntity"> 6 6 <id property="id" column="id"/> 7 7 <result property="name" column="name"/> 8 8 <result property="password" column="password"/> 9 9 <collection property="roles" ofType="com.xiaostudy.shiro_test1.entity.RoleEntity"> 1010 <id property="id" column="roleId"/> 1111 <result property="name" column="roleName"/> 1212 <collection property="permissions" ofType="com.xiaostudy.shiro_test1.entity.PermissionEntity"> 1313 <id property="id" column="permissionId"/> 1414 <result property="name" column="permissionName"/> 1515 <result property="url" column="permissionUrl"/> 1616 </collection> 1717 </collection> 1818 </resultMap> 1919 2020 <select id="findByName" parameterType="java.lang.String" resultType="com.xiaostudy.shiro_test1.entity.UserEntity"> 2121 SELECT id, name, password 2222 FROM user 2323 WHERE name = #{name} 2424 </select> 2525 2626 <select id="findById" parameterType="java.lang.String" resultMap="userMap"> 2727 SELECT user.id, user.name, user.password, 2828 role.id as roleId, role.name as roleName, 2929 permission.id as permissionId, 3030 permission.name as permissionName, 3131 permission.url as permissionUrl 3232 FROM user, user_role, role, role_permission, permission 3333 WHERE user.id = #{id} 3434 AND user.id = user_role.user_id 3535 AND user_role.role_id = role.id 3636 AND role.id = role_permission.role_id 3737 AND role_permission.permission_id = permission.id 3838 </select> 3939 4040 </mapper>
5、下面写service

1 1 package com.xiaostudy.shiro_test1.service; 2 2 3 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 4 5 5 /** 6 6 * Created with IntelliJ IDEA. 7 7 * User: Administrator 8 8 * Date: 2019/6/8 9 9 * Time: 14:55 1010 * Description: No Description 1111 */ 1212 public interface UserService { 1313 1414 UserEntity findByName(String name); 1515 1616 UserEntity findById(String id); 1717 }

1 1 package com.xiaostudy.shiro_test1.service.impl; 2 2 3 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 4 import com.xiaostudy.shiro_test1.mapper.UserMapper; 5 5 import com.xiaostudy.shiro_test1.service.UserService; 6 6 import org.springframework.beans.factory.annotation.Autowired; 7 7 import org.springframework.stereotype.Service; 8 8 9 9 /** 1010 * Created with IntelliJ IDEA. 1111 * User: Administrator 1212 * Date: 2019/6/8 1313 * Time: 14:56 1414 * Description: No Description 1515 */ 1616 @Service 1717 public class UserServiceImpl implements UserService { 1818 1919 @Autowired 2020 private UserMapper userMapper; 2121 2222 @Override 2323 public UserEntity findByName(String name) { 2424 return userMapper.findByName(name); 2525 } 2626 2727 @Override 2828 public UserEntity findById(String id) { 2929 return userMapper.findById(id); 3030 } 3131 }
6、下面写自定义Realm的UserRealm.java

1 1 package com.xiaostudy.shiro_test1.realm; 2 2 3 3 import com.xiaostudy.shiro_test1.entity.PermissionEntity; 4 4 import com.xiaostudy.shiro_test1.entity.RoleEntity; 5 5 import com.xiaostudy.shiro_test1.entity.UserEntity; 6 6 import com.xiaostudy.shiro_test1.service.UserService; 7 7 import org.apache.shiro.SecurityUtils; 8 8 import org.apache.shiro.authc.*; 9 9 import org.apache.shiro.authz.AuthorizationInfo; 1010 import org.apache.shiro.authz.SimpleAuthorizationInfo; 1111 import org.apache.shiro.realm.AuthorizingRealm; 1212 import org.apache.shiro.subject.PrincipalCollection; 1313 import org.apache.shiro.subject.Subject; 1414 import org.apache.shiro.util.ByteSource; 1515 import org.springframework.beans.factory.annotation.Autowired; 1616 1717 import java.util.Collection; 1818 import java.util.HashSet; 1919 import java.util.Set; 2020 2121 /** 2222 * 自定义Realm,实现授权与认证 2323 * Created with IntelliJ IDEA. 2424 * User: Administrator 2525 * Date: 2019/6/8 2626 * Time: 15:01 2727 * Description: No Description 2828 */ 2929 public class UserRealm extends AuthorizingRealm { 3030 3131 @Autowired 3232 private UserService userService; 3333 3434 /** 3535 * 用户授权 3636 **/ 3737 @Override 3838 protected AuthorizationInfo doGetAuthorizationInfo( 3939 PrincipalCollection principalCollection) { 4040 4141 System.out.println("===执行授权==="); 4242 4343 Subject subject = SecurityUtils.getSubject(); 4444 UserEntity user = (UserEntity)subject.getPrincipal(); 4545 if(user != null){ 4646 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 4747 // 角色字符串集合 4848 Collection<String> rolesCollection = new HashSet<>(); 4949 // 权限字符串集合 5050 Collection<String> premissionCollection = new HashSet<>(); 5151 // 读取并赋值用户角色与权限 5252 Set<RoleEntity> roles = user.getRoles(); 5353 for(RoleEntity role : roles){ 5454 rolesCollection.add(role.getName()); 5555 Set<PermissionEntity> permissions = role.getPermissions(); 5656 for (PermissionEntity permission : permissions){ 5757 // 权限名称为PermissionEntity为字段url 5858 premissionCollection.add(permission.getUrl()); 5959 } 6060 info.addStringPermissions(premissionCollection); 6161 } 6262 info.addRoles(rolesCollection); 6363 return info; 6464 } 6565 return null; 6666 } 6767 6868 /** 6969 * 用户认证 7070 **/ 7171 @Override 7272 protected AuthenticationInfo doGetAuthenticationInfo( 7373 AuthenticationToken authenticationToken) throws AuthenticationException { 7474 7575 System.out.println("===执行认证==="); 7676 7777 UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; 7878 UserEntity bean = userService.findByName(token.getUsername()); 7979 8080 if(bean == null){ 8181 // 用户不存在 8282 throw new UnknownAccountException(); 8383 } else { 8484 bean = userService.findById(bean.getId()); 8585 if(null == bean) { 8686 // 认证失败 8787 throw new AuthenticationException(); 8888 } 8989 } 9090 9191 ByteSource credentialsSalt = ByteSource.Util.bytes(bean.getName()); 9292 9393 return new SimpleAuthenticationInfo(bean, bean.getPassword(), 9494 credentialsSalt, getName()); 9595 } 9696 }
7、下面写shiro配置类

1 1 package com.xiaostudy.shiro_test1.config; 2 2 3 3 import com.xiaostudy.shiro_test1.realm.UserRealm; 4 4 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 5 5 import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 6 6 import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 7 7 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 8 8 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 9 9 import org.springframework.context.annotation.Bean; 1010 import org.springframework.context.annotation.Configuration; 1111 1212 import java.util.HashMap; 1313 import java.util.Map; 1414 1515 /** 1616 * Shiro配置类 1717 * Created with IntelliJ IDEA. 1818 * User: Administrator 1919 * Date: 2019/6/8 2020 * Time: 15:06 2121 * Description: No Description 2222 */ 2323 @Configuration 2424 public class ShiroConfig { 2525 2626 // 创建自定义 realm 2727 @Bean 2828 public UserRealm userRealm() { 2929 UserRealm userRealm = new UserRealm(); 3030 return userRealm; 3131 } 3232 3333 // 创建 SecurityManager 对象 3434 @Bean 3535 public DefaultWebSecurityManager securityManager() { 3636 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 3737 securityManager.setRealm(userRealm()); 3838 return securityManager; 3939 } 4040 4141 // Filter工厂,设置对应的过滤条件和跳转条件 4242 @Bean 4343 public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { 4444 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 4545 shiroFilterFactoryBean.setSecurityManager(securityManager); 4646 /** 4747 * anon:匿名用户可访问 4848 * authc:认证用户可访问 4949 * user:使用rememberMe可访问 5050 * perms:对应权限可访问 5151 * role:对应角色权限可访问 5252 */ 5353 Map<String, String> map = new HashMap<>(); 5454 // 开放登录接口 5555 map.put("/login", "anon"); 5656 // map.put("/login", "authc"); 5757 // 对登录跳转接口进行释放 5858 map.put("/error", "anon"); 5959 // 对所有用户认证 6060 map.put("/**", "authc"); 6161 // 登出 6262 map.put("/logout", "logout"); 6363 // 登录 6464 // 注意:这里配置的 /login 是指到 @RequestMapping(value="/login")中的 /login 6565 shiroFilterFactoryBean.setLoginUrl("/login"); 6666 // 首页 6767 shiroFilterFactoryBean.setSuccessUrl("/index"); 6868 // 错误页面,认证不通过跳转 6969 shiroFilterFactoryBean.setUnauthorizedUrl("/error/unAuth"); 7070 shiroFilterFactoryBean.setFilterChainDefinitionMap(map); 7171 return shiroFilterFactoryBean; 7272 } 7373 7474 // 加入注解的使用,不加这个,注解不生效 7575 @Bean 7676 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { 7777 AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); 7878 authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); 7979 return authorizationAttributeSourceAdvisor; 8080 } 8181 8282 // 跟上面的注解配置搭配使用,有时候加了上面的配置后注解不生效,需要加入下面的配置 8383 @Bean 8484 @ConditionalOnMissingBean 8585 public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { 8686 DefaultAdvisorAutoProxyCreator app = new DefaultAdvisorAutoProxyCreator(); 8787 app.setProxyTargetClass(true); 8888 return app; 8989 } 9090 }
8、下面写没有权限异常处理类

1 1 package com.xiaostudy.shiro_test1.exception; 2 2 3 3 import org.apache.shiro.authz.AuthorizationException; 4 4 import org.apache.shiro.authz.UnauthorizedException; 5 5 import org.springframework.stereotype.Component; 6 6 import org.springframework.web.bind.annotation.ControllerAdvice; 7 7 import org.springframework.web.bind.annotation.ExceptionHandler; 8 8 import org.springframework.web.bind.annotation.ResponseBody; 9 9 1010 /** 1111 * Created with IntelliJ IDEA. 1212 * User: Administrator 1313 * Date: 2019/6/8 1414 * Time: 15:13 1515 * Description: No Description 1616 */ 1717 @ControllerAdvice 1818 public class NoPermissionException { 1919 // 授权失败,就是说没有该权限 2020 @ExceptionHandler(UnauthorizedException.class) 2121 public String handleShiroException(Exception ex) { 2222 return "/error/unAuth"; 2323 } 2424 2525 @ResponseBody 2626 @ExceptionHandler(AuthorizationException.class) 2727 public String AuthorizationException(Exception ex) { 2828 return "权限认证失败"; 2929 } 3030 }
9、下面写controller

1 1 package com.xiaostudy.shiro_test1.web.controller; 2 2 3 3 import org.apache.shiro.SecurityUtils; 4 4 import org.apache.shiro.authc.AuthenticationException; 5 5 import org.apache.shiro.authc.IncorrectCredentialsException; 6 6 import org.apache.shiro.authc.UnknownAccountException; 7 7 import org.apache.shiro.authc.UsernamePasswordToken; 8 8 import org.apache.shiro.subject.Subject; 9 9 import org.springframework.stereotype.Controller; 1010 import org.springframework.web.bind.annotation.RequestMapping; 1111 1212 import javax.servlet.http.HttpServletRequest; 1313 import javax.servlet.http.HttpServletResponse; 1414 1515 /** 1616 * 用户登录、登出、错误页面跳转控制器 1717 * Created with IntelliJ IDEA. 1818 * User: Administrator 1919 * Date: 2019/6/8 2020 * Time: 15:15 2121 * Description: No Description 2222 */ 2323 @Controller 2424 public class MainController { 2525 2626 @RequestMapping("/index") 2727 public String index(HttpServletRequest request, HttpServletResponse response){ 2828 response.setHeader("root", request.getContextPath()); 2929 return "index"; 3030 } 3131 3232 @RequestMapping("/login") 3333 public String login(HttpServletRequest request, HttpServletResponse response){ 3434 response.setHeader("root", request.getContextPath()); 3535 String userName = request.getParameter("username"); 3636 String password = request.getParameter("password"); 3737 3838 // 等于null说明用户没有登录,只是拦截所有请求到这里,那就直接让用户去登录页面,就不认证了。 3939 // 如果这里不处理,那个会返回用户名不存在,逻辑上不合理,用户还没登录怎么就用户名不存在? 4040 if(null == userName) { 4141 return "login"; 4242 } 4343 4444 // 1.获取Subject 4545 Subject subject = SecurityUtils.getSubject(); 4646 // 2.封装用户数据 4747 UsernamePasswordToken token = new UsernamePasswordToken(userName, password); 4848 // 3.执行登录方法 4949 try{ 5050 subject.login(token); 5151 return "redirect:/index"; 5252 } catch (UnknownAccountException e){ 5353 // 这里是捕获自定义Realm的用户名不存在异常 5454 request.setAttribute("msg","用户名不存在!"); 5555 } catch (IncorrectCredentialsException e){ 5656 request.setAttribute("userName",userName); 5757 request.setAttribute("msg","密码错误!"); 5858 } catch (AuthenticationException e) { 5959 // 这里是捕获自定义Realm的认证失败异常 6060 request.setAttribute("msg","认证失败!"); 6161 } 6262 6363 return "login"; 6464 } 6565 6666 @RequestMapping("/logout") 6767 public String logout(){ 6868 Subject subject = SecurityUtils.getSubject(); 6969 if (subject != null) { 7070 subject.logout(); 7171 } 7272 // return "redirect:/main"; 7373 return "login"; 7474 } 7575 7676 @RequestMapping("/error/unAuth") 7777 public String unAuth(){ 7878 return "/error/unAuth"; 7979 } 8080 8181 @RequestMapping("/err") 8282 public String err(){ 8383 return "/error/unAuth"; 8484 } 8585 }

1 1 package com.xiaostudy.shiro_test1.web.controller; 2 2 3 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 4 import org.apache.shiro.SecurityUtils; 5 5 import org.apache.shiro.authz.annotation.RequiresPermissions; 6 6 import org.springframework.stereotype.Controller; 7 7 import org.springframework.web.bind.annotation.RequestMapping; 8 8 9 9 import javax.servlet.http.HttpServletRequest; 1010 1111 /** 1212 * 用户页面跳转 1313 * Created with IntelliJ IDEA. 1414 * User: Administrator 1515 * Date: 2019/6/8 1616 * Time: 15:21 1717 * Description: No Description 1818 */ 1919 @Controller 2020 public class UserController { 2121 2222 /** 2323 * 个人中心,需认证可访问 2424 */ 2525 @RequestMapping("/user/index") 2626 @RequiresPermissions(value = "user")// 这里的user,就是对应权限实体类PermissionEntity的字段url,自定义Realm类UserRealm里是用这个字段 2727 public String add(HttpServletRequest request){ 2828 UserEntity bean = (UserEntity) SecurityUtils.getSubject().getPrincipal(); 2929 request.setAttribute("userName", bean.getName()); 3030 return "/user/index"; 3131 } 3232 3333 /** 3434 * 会员中心,需认证且角色为vip可访问 3535 */ 3636 @RequestMapping("/vip/index") 3737 @RequiresPermissions(value = "vip") 3838 public String update(){ 3939 return "/vip/index"; 4040 } 4141 }
10、下面写spring-mvc.xml

1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 3 xmlns:mvc="http://www.springframework.org/schema/mvc" 4 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 6 xmlns:context="http://www.springframework.org/schema/context" 7 7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 8 8 xsi:schemaLocation="http://www.springframework.org/schema/beans 9 9 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 1010 http://www.springframework.org/schema/mvc 1111 http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 1212 http://www.springframework.org/schema/context 1313 http://www.springframework.org/schema/context/spring-context-3.2.xsd 1414 http://www.springframework.org/schema/aop 1515 http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 1616 http://www.springframework.org/schema/tx 1717 http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> 1818 1919 <!-- 把Controller交给spring管理 --> 2020 <context:component-scan base-package="com.xiaostudy"/> 2121 2222 <!-- 配置注解处理器映射器 功能:寻找执行类Controller --> 2323 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> 2424 2525 <!-- 配置注解处理器适配器 功能:调用controller方法,执行controller --> 2626 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> 2727 2828 <!-- 配置sprigmvc视图解析器:解析逻辑试图 2929 后台返回逻辑试图:index 3030 视图解析器解析出真正物理视图:前缀+逻辑试图+后缀====/WEB-INF/index.jsp --> 3131 <!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 3232 <property name="prefix" value="/WEB-INF/"/> 3333 <property name="suffix" value=".jsp"/> 3434 </bean>--> 3535 </beans>
11、下面写web.xml
1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 5 version="4.0"> 6 6 <display-name>Archetype Created Web Application</display-name> 7 7 8 8 <!--请求编码设置--> 9 9 <filter> 1010 <filter-name>encodingFilter</filter-name> 1111 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 1212 <init-param> 1313 <param-name>encoding</param-name> 1414 <param-value>UTF-8</param-value> 1515 </init-param> 1616 <init-param> 1717 <param-name>forceEncoding</param-name> 1818 <param-value>true</param-value> 1919 </init-param> 2020 </filter> 2121 <filter-mapping> 2222 <filter-name>encodingFilter</filter-name> 2323 <url-pattern>/*</url-pattern> 2424 </filter-mapping> 2525 2626 <listener> 2727 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 2828 </listener> 2929 <listener> 3030 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> 3131 </listener> 3232 <servlet> 3333 <servlet-name>SpringMVC</servlet-name> 3434 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 3535 <init-param> 3636 <param-name>contextConfigLocation</param-name> 3737 <param-value>classpath:spring-mvc.xml</param-value> 3838 </init-param> 3939 <load-on-startup>1</load-on-startup> 4040 <async-supported>true</async-supported> 4141 </servlet> 4242 <servlet-mapping> 4343 <servlet-name>SpringMVC</servlet-name> 4444 <url-pattern>/</url-pattern> 4545 </servlet-mapping> 4646 <welcome-file-list> 4747 <welcome-file>/index</welcome-file> 4848 </welcome-file-list> 4949 </web-app>
12、下面写application.yml

1 1 spring: 2 2 datasource: 3 3 url: jdbc:mysql://localhost:3306/shiro_test?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC 4 4 username: root 5 5 password: root 6 6 driver-class-name: com.mysql.cj.jdbc.Driver 7 7 type: com.alibaba.druid.pool.DruidDataSource 8 8 # 初始化时建立物理连接连接的个数 9 9 initialSize: 5 1010 # 最小连接池数量 1111 minIdle: 5 1212 # 最大连接池数量 1313 maxActive: 20 1414 # 获取连接时最大等待时间(ms),即60s 1515 maxWait: 60000 1616 # 1.Destroy线程会检测连接的间隔时间;2.testWhileIdle的判断依据 1717 timeBetweenEvictionRunsMillis: 60000 1818 # 最小生存时间ms 1919 minEvictableIdleTimeMillis: 600000 2020 maxEvictableIdleTimeMillis: 900000 2121 # 用来检测连接是否有效的sql 2222 validationQuery: SELECT 1 FROM DUAL 2323 # 申请连接时执行validationQuery检测连接是否有效,启用会降低性能 2424 testOnBorrow: false 2525 # 归还连接时执行validationQuery检测连接是否有效,启用会降低性能 2626 testOnReturn: false 2727 # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis, 2828 # 执行validationQuery检测连接是否有效,不会降低性能 2929 testWhileIdle: true 3030 # 是否缓存preparedStatement,mysql建议关闭 3131 poolPreparedStatements: false 3232 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 3333 filters: stat,wall,log4j 3434 thymeleaf: 3535 suffix: .html 3636 charset: utf-8 3737 mvc: 3838 # 配置静态资源映射路径,/public、/resources路径失效 3939 static-path-pattern: templates/** 4040 mybatis: 4141 mapper-locations: classpath:mapper/*.xml 4242 # mapperLocations: classpath:mapper/*.xml 4343 # 虽然可以配置这项来进行pojo包扫描,但其实我更倾向于在mapper.xml写全类名 4444 # type-aliases-package: com.xiaostudy.shiro_test1.entity


13、下面写html

1 1 <!DOCTYPE html> 2 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 3 <head> 4 4 <meta charset="UTF-8"> 5 5 <title>登录</title> 6 6 </head> 7 7 <body> 8 8 <h1>用户登录</h1> 9 9 <hr> 1010 <form id="from" action="/login" method="post"> 1111 <table> 1212 <tr> 1313 <td>用户名</td> 1414 <td> 1515 <input type="text" name="username" placeholder="请输入账户名" value="" th:value="${userName }"/> 1616 </td> 1717 </tr> 1818 <tr> 1919 <td>密码</td> 2020 <td> 2121 <input type="password" name="password" placeholder="请输入密码"/> 2222 </td> 2323 </tr> 2424 <tr> 2525 <td colspan="2"> 2626 <span style="color: red;">[[${msg }]]</span> 2727 </td> 2828 </tr> 2929 <tr> 3030 <td colspan="2"> 3131 <input type="submit" value="登录"/> 3232 <input type="reset" value="重置"/> 3333 </td> 3434 </tr> 3535 </table> 3636 </form> 3737 </body> 3838 </html>

1 1 <!DOCTYPE html> 2 2 <html lang="en"> 3 3 4 4 <head> 5 5 <title>首页</title> 6 6 </head> 7 7 <body> 8 8 <h1>首页</h1> 9 9 <hr> 1010 <ul> 1111 <li><a href="user/index">个人中心</a></li> 1212 <li><a href="vip/index">会员中心</a></li> 1313 <li><a href="logout">退出登录</a></li> 1414 </ul> 1515 </body> 1616 </html>


1 1 <!DOCTYPE html> 2 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 3 <head> 4 4 <title>用户中心</title> 5 5 </head> 6 6 <body> 7 7 <h1>用户中心</h1> 8 8 <hr> 9 9 <h1>欢迎[[${userName }]],这里是用户中心</h1> 1010 </body> 1111 </html>

1 1 <!DOCTYPE html> 2 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 3 <head> 4 4 <title>会员中心</title> 5 5 </head> 6 6 <body> 7 7 <h1>会员中心</h1> 8 8 <hr> 9 9 <h1>欢迎来到<span style="color: red;">会员中心</span></h1> 1010 </body> 1111 </html>

11 <!DOCTYPE html> 22 <html lang="en"> 33 <head> 44 <title>未授权提示</title> 55 </head> 66 <body> 77 <h1>您还不是<span style="color: red;">会员</span> ,没有权限访问这个页面!</h1> 88 </body> 99 </html>
下面讲一下@Mapper与@MapperScan这个注解
@Mapper是放在具体的*Mapper.java类上面的,告诉springboot,这是mapper类

而@MapperScan是让springboot去扫描指定包下的mapper类,就不用每个mapper自己添加一个@Mapper注解了,这种方式比较好,因为这里测试只有一个mapper类,就直接用@Mapper了,两个一起用会不会冲突,这里没有测试。

整体目录



先看一下数据库表






下面是启动测试
















参考文章:https://blog.csdn.net/qq_34802416/article/details/84959457
thymeleaf