springboot与shiro和mybatis和mysql
测试项目已上传到GitHub:https://github.com/xiaostudy/springboot_shiro_test1
1、创建springboot项目
1 <!-- 数据库连接池 --> 2 <dependency> 3 <groupId>com.alibaba</groupId> 4 <artifactId>druid</artifactId> 5 <version>1.1.10</version> 6 </dependency> 7 <!-- Shiro --> 8 <dependency> 9 <groupId>org.apache.shiro</groupId> 10 <artifactId>shiro-spring</artifactId> 11 <version>1.3.2</version> 12 </dependency> 13 <!-- log4j --> 14 <dependency> 15 <groupId>log4j</groupId> 16 <artifactId>log4j</artifactId> 17 <version>1.2.17</version> 18 </dependency>
src\main\webapp\
2、创建实体类
PermissionEntity.java
1 package com.xiaostudy.shiro_test1.entity; 2 3 import java.io.Serializable; 4 5 /** 6 * 权限实体类 7 * Created with IntelliJ IDEA. 8 * User: Administrator 9 * Date: 2019/6/8 10 * Time: 14:21 11 * Description: No Description 12 */ 13 public class PermissionEntity implements Serializable { 14 private String id; 15 private String name; 16 private String url; 17 18 public String getId() { 19 return id; 20 } 21 22 public void setId(String id) { 23 this.id = id; 24 } 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public String getUrl() { 35 return url; 36 } 37 38 public void setUrl(String url) { 39 this.url = url; 40 } 41 }
1 package com.xiaostudy.shiro_test1.entity; 2 3 import java.io.Serializable; 4 import java.util.HashSet; 5 import java.util.Set; 6 7 /** 8 * 角色实体类 9 * Created with IntelliJ IDEA. 10 * User: Administrator 11 * Date: 2019/6/8 12 * Time: 14:24 13 * Description: No Description 14 */ 15 public class RoleEntity implements Serializable { 16 private String id; 17 private String name; 18 private Set<PermissionEntity> permissions = new HashSet<>(); 19 20 public String getId() { 21 return id; 22 } 23 24 public void setId(String id) { 25 this.id = id; 26 } 27 28 public String getName() { 29 return name; 30 } 31 32 public void setName(String name) { 33 this.name = name; 34 } 35 36 public Set<PermissionEntity> getPermissions() { 37 return permissions; 38 } 39 40 public void setPermissions(Set<PermissionEntity> permissions) { 41 this.permissions = permissions; 42 } 43 }
1 package com.xiaostudy.shiro_test1.entity; 2 3 import java.io.Serializable; 4 import java.util.HashSet; 5 import java.util.Set; 6 7 /** 8 * 用户实体类 9 * Created with IntelliJ IDEA. 10 * User: Administrator 11 * Date: 2019/6/8 12 * Time: 14:26 13 * Description: No Description 14 */ 15 public class UserEntity implements Serializable { 16 private String id; 17 private String name; 18 private String password; 19 private Set<RoleEntity> roles = new HashSet<>(); 20 21 public String getId() { 22 return id; 23 } 24 25 public void setId(String id) { 26 this.id = id; 27 } 28 29 public String getName() { 30 return name; 31 } 32 33 public void setName(String name) { 34 this.name = name; 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 Set<RoleEntity> getRoles() { 46 return roles; 47 } 48 49 public void setRoles(Set<RoleEntity> roles) { 50 this.roles = roles; 51 } 52 }
实体类entity,也可以叫bean、domain,具体叫什可以根据自己的喜欢选取
3、数据库创建表和添加数据
1 DROP TABLE IF EXISTS `role_permission`; 2 DROP TABLE IF EXISTS `permission`; 3 DROP TABLE IF EXISTS `user_role`; 4 DROP TABLE IF EXISTS `role`; 5 DROP TABLE IF EXISTS `user`; 6 7 CREATE TABLE `user` ( 8 `id` VARCHAR(255) PRIMARY KEY, 9 `name` VARCHAR(255), 10 `password` VARCHAR(255) 11 ) engine = InnoDB default charset = utf8 comment = '用户表'; 12 13 CREATE TABLE `role` ( 14 `id` VARCHAR(255) PRIMARY KEY, 15 `name` VARCHAR(255) 16 ) engine = InnoDB default charset = utf8 comment = '角色表'; 17 18 CREATE TABLE `user_role` ( 19 `id` VARCHAR(255) PRIMARY KEY, 20 `user_id` VARCHAR(255), 21 `role_id` VARCHAR(255), 22 FOREIGN KEY (`user_id`) REFERENCES `user`(id), 23 FOREIGN KEY (`role_id`) REFERENCES `role`(id) 24 ) engine = InnoDB default charset = utf8 comment = '用户与角色多对多表'; 25 26 CREATE TABLE `permission` ( 27 `id` VARCHAR(255) PRIMARY KEY, 28 `name` VARCHAR(255), 29 `url` VARCHAR(255) 30 ) engine = InnoDB default charset = utf8 comment = '权限表'; 31 32 CREATE TABLE `role_permission` ( 33 `id` VARCHAR(255) PRIMARY KEY, 34 `role_id` VARCHAR(255), 35 `permission_id` VARCHAR(255), 36 FOREIGN KEY (`role_id`) REFERENCES `role`(id), 37 FOREIGN KEY (`permission_id`) REFERENCES `permission`(id) 38 ) engine = InnoDB default charset = utf8 comment = '角色与权限多对多表'; 39 40 insert into `user` (`id`, `name`, `password`) values('1','admin','123456'); 41 insert into `user` (`id`, `name`, `password`) values('2','vip','123456'); 42 insert into `user` (`id`, `name`, `password`) values('3','svip','1234'); 43 44 insert into `role` (`id`, `name`) values('1','user'); 45 insert into `role` (`id`, `name`) values('2','vip'); 46 insert into `role` (`id`, `name`) values('3','svip'); 47 48 insert into `permission` (`id`, `name`, `url`) values('1','user','user'); 49 insert into `permission` (`id`, `name`, `url`) values('2','vip','vip'); 50 insert into `permission` (`id`, `name`, `url`) values('3','svip','svip'); 51 52 insert into `user_role` (`id`, `user_id`, `role_id`) values('1','1','1'); 53 insert into `user_role` (`id`, `user_id`, `role_id`) values('2','2','1'); 54 insert into `user_role` (`id`, `user_id`, `role_id`) values('3','2','2'); 55 insert into `user_role` (`id`, `user_id`, `role_id`) values('4','3','1'); 56 insert into `user_role` (`id`, `user_id`, `role_id`) values('5','3','2'); 57 insert into `user_role` (`id`, `user_id`, `role_id`) values('6','3','3'); 58 59 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('1','1','1'); 60 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('2','2','1'); 61 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('3','2','2'); 62 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('4','3','1'); 63 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('5','3','2'); 64 insert into `role_permission` (`id`, `role_id`, `permission_id`) values('6','3','3');
4、接下来写mapper,也叫dao
1 package com.xiaostudy.shiro_test1.mapper; 2 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 import org.apache.ibatis.annotations.Mapper; 5 6 /** 7 * Created with IntelliJ IDEA. 8 * User: Administrator 9 * Date: 2019/6/8 10 * Time: 14:45 11 * Description: No Description 12 */ 13 @Mapper 14 public interface UserMapper { 15 16 // 根据用户名称,查询用户信息 17 public UserEntity findByName(String name); 18 19 // 根据用户id,查询用户信息、角色、权限 20 public UserEntity findById(String id); 21 }
@Mapper后面再讲,这里也可以不用@Mapper
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 3 <mapper namespace="com.xiaostudy.shiro_test1.mapper.UserMapper"> 4 5 <resultMap id="userMap" type="com.xiaostudy.shiro_test1.entity.UserEntity"> 6 <id property="id" column="id"/> 7 <result property="name" column="name"/> 8 <result property="password" column="password"/> 9 <collection property="roles" ofType="com.xiaostudy.shiro_test1.entity.RoleEntity"> 10 <id property="id" column="roleId"/> 11 <result property="name" column="roleName"/> 12 <collection property="permissions" ofType="com.xiaostudy.shiro_test1.entity.PermissionEntity"> 13 <id property="id" column="permissionId"/> 14 <result property="name" column="permissionName"/> 15 <result property="url" column="permissionUrl"/> 16 </collection> 17 </collection> 18 </resultMap> 19 20 <select id="findByName" parameterType="java.lang.String" resultType="com.xiaostudy.shiro_test1.entity.UserEntity"> 21 SELECT id, name, password 22 FROM user 23 WHERE name = #{name} 24 </select> 25 26 <select id="findById" parameterType="java.lang.String" resultMap="userMap"> 27 SELECT user.id, user.name, user.password, 28 role.id as roleId, role.name as roleName, 29 permission.id as permissionId, 30 permission.name as permissionName, 31 permission.url as permissionUrl 32 FROM user, user_role, role, role_permission, permission 33 WHERE user.id = #{id} 34 AND user.id = user_role.user_id 35 AND user_role.role_id = role.id 36 AND role.id = role_permission.role_id 37 AND role_permission.permission_id = permission.id 38 </select> 39 40 </mapper>
5、下面写service
1 package com.xiaostudy.shiro_test1.service; 2 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 5 /** 6 * Created with IntelliJ IDEA. 7 * User: Administrator 8 * Date: 2019/6/8 9 * Time: 14:55 10 * Description: No Description 11 */ 12 public interface UserService { 13 14 UserEntity findByName(String name); 15 16 UserEntity findById(String id); 17 }
1 package com.xiaostudy.shiro_test1.service.impl; 2 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 import com.xiaostudy.shiro_test1.mapper.UserMapper; 5 import com.xiaostudy.shiro_test1.service.UserService; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Service; 8 9 /** 10 * Created with IntelliJ IDEA. 11 * User: Administrator 12 * Date: 2019/6/8 13 * Time: 14:56 14 * Description: No Description 15 */ 16 @Service 17 public class UserServiceImpl implements UserService { 18 19 @Autowired 20 private UserMapper userMapper; 21 22 @Override 23 public UserEntity findByName(String name) { 24 return userMapper.findByName(name); 25 } 26 27 @Override 28 public UserEntity findById(String id) { 29 return userMapper.findById(id); 30 } 31 }
6、下面写自定义Realm的UserRealm.java
1 package com.xiaostudy.shiro_test1.realm; 2 3 import com.xiaostudy.shiro_test1.entity.PermissionEntity; 4 import com.xiaostudy.shiro_test1.entity.RoleEntity; 5 import com.xiaostudy.shiro_test1.entity.UserEntity; 6 import com.xiaostudy.shiro_test1.service.UserService; 7 import org.apache.shiro.SecurityUtils; 8 import org.apache.shiro.authc.*; 9 import org.apache.shiro.authz.AuthorizationInfo; 10 import org.apache.shiro.authz.SimpleAuthorizationInfo; 11 import org.apache.shiro.realm.AuthorizingRealm; 12 import org.apache.shiro.subject.PrincipalCollection; 13 import org.apache.shiro.subject.Subject; 14 import org.apache.shiro.util.ByteSource; 15 import org.springframework.beans.factory.annotation.Autowired; 16 17 import java.util.Collection; 18 import java.util.HashSet; 19 import java.util.Set; 20 21 /** 22 * 自定义Realm,实现授权与认证 23 * Created with IntelliJ IDEA. 24 * User: Administrator 25 * Date: 2019/6/8 26 * Time: 15:01 27 * Description: No Description 28 */ 29 public class UserRealm extends AuthorizingRealm { 30 31 @Autowired 32 private UserService userService; 33 34 /** 35 * 用户授权 36 **/ 37 @Override 38 protected AuthorizationInfo doGetAuthorizationInfo( 39 PrincipalCollection principalCollection) { 40 41 System.out.println("===执行授权==="); 42 43 Subject subject = SecurityUtils.getSubject(); 44 UserEntity user = (UserEntity)subject.getPrincipal(); 45 if(user != null){ 46 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 47 // 角色字符串集合 48 Collection<String> rolesCollection = new HashSet<>(); 49 // 权限字符串集合 50 Collection<String> premissionCollection = new HashSet<>(); 51 // 读取并赋值用户角色与权限 52 Set<RoleEntity> roles = user.getRoles(); 53 for(RoleEntity role : roles){ 54 rolesCollection.add(role.getName()); 55 Set<PermissionEntity> permissions = role.getPermissions(); 56 for (PermissionEntity permission : permissions){ 57 // 权限名称为PermissionEntity为字段url 58 premissionCollection.add(permission.getUrl()); 59 } 60 info.addStringPermissions(premissionCollection); 61 } 62 info.addRoles(rolesCollection); 63 return info; 64 } 65 return null; 66 } 67 68 /** 69 * 用户认证 70 **/ 71 @Override 72 protected AuthenticationInfo doGetAuthenticationInfo( 73 AuthenticationToken authenticationToken) throws AuthenticationException { 74 75 System.out.println("===执行认证==="); 76 77 UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken; 78 UserEntity bean = userService.findByName(token.getUsername()); 79 80 if(bean == null){ 81 // 用户不存在 82 throw new UnknownAccountException(); 83 } else { 84 bean = userService.findById(bean.getId()); 85 if(null == bean) { 86 // 认证失败 87 throw new AuthenticationException(); 88 } 89 } 90 91 ByteSource credentialsSalt = ByteSource.Util.bytes(bean.getName()); 92 93 return new SimpleAuthenticationInfo(bean, bean.getPassword(), 94 credentialsSalt, getName()); 95 } 96 }
7、下面写shiro配置类
1 package com.xiaostudy.shiro_test1.config; 2 3 import com.xiaostudy.shiro_test1.realm.UserRealm; 4 import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 5 import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 6 import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 7 import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 8 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 9 import org.springframework.context.annotation.Bean; 10 import org.springframework.context.annotation.Configuration; 11 12 import java.util.HashMap; 13 import java.util.Map; 14 15 /** 16 * Shiro配置类 17 * Created with IntelliJ IDEA. 18 * User: Administrator 19 * Date: 2019/6/8 20 * Time: 15:06 21 * Description: No Description 22 */ 23 @Configuration 24 public class ShiroConfig { 25 26 // 创建自定义 realm 27 @Bean 28 public UserRealm userRealm() { 29 UserRealm userRealm = new UserRealm(); 30 return userRealm; 31 } 32 33 // 创建 SecurityManager 对象 34 @Bean 35 public DefaultWebSecurityManager securityManager() { 36 DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 37 securityManager.setRealm(userRealm()); 38 return securityManager; 39 } 40 41 // Filter工厂,设置对应的过滤条件和跳转条件 42 @Bean 43 public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { 44 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 45 shiroFilterFactoryBean.setSecurityManager(securityManager); 46 /** 47 * anon:匿名用户可访问 48 * authc:认证用户可访问 49 * user:使用rememberMe可访问 50 * perms:对应权限可访问 51 * role:对应角色权限可访问 52 */ 53 Map<String, String> map = new HashMap<>(); 54 // 开放登录接口 55 map.put("/login", "anon"); 56 // map.put("/login", "authc"); 57 // 对登录跳转接口进行释放 58 map.put("/error", "anon"); 59 // 对所有用户认证 60 map.put("/**", "authc"); 61 // 登出 62 map.put("/logout", "logout"); 63 // 登录 64 // 注意:这里配置的 /login 是指到 @RequestMapping(value="/login")中的 /login 65 shiroFilterFactoryBean.setLoginUrl("/login"); 66 // 首页 67 shiroFilterFactoryBean.setSuccessUrl("/index"); 68 // 错误页面,认证不通过跳转 69 shiroFilterFactoryBean.setUnauthorizedUrl("/error/unAuth"); 70 shiroFilterFactoryBean.setFilterChainDefinitionMap(map); 71 return shiroFilterFactoryBean; 72 } 73 74 // 加入注解的使用,不加这个,注解不生效 75 @Bean 76 public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { 77 AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); 78 authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); 79 return authorizationAttributeSourceAdvisor; 80 } 81 82 // 跟上面的注解配置搭配使用,有时候加了上面的配置后注解不生效,需要加入下面的配置 83 @Bean 84 @ConditionalOnMissingBean 85 public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { 86 DefaultAdvisorAutoProxyCreator app = new DefaultAdvisorAutoProxyCreator(); 87 app.setProxyTargetClass(true); 88 return app; 89 } 90 }
8、下面写没有权限异常处理类
1 package com.xiaostudy.shiro_test1.exception; 2 3 import org.apache.shiro.authz.AuthorizationException; 4 import org.apache.shiro.authz.UnauthorizedException; 5 import org.springframework.stereotype.Component; 6 import org.springframework.web.bind.annotation.ControllerAdvice; 7 import org.springframework.web.bind.annotation.ExceptionHandler; 8 import org.springframework.web.bind.annotation.ResponseBody; 9 10 /** 11 * Created with IntelliJ IDEA. 12 * User: Administrator 13 * Date: 2019/6/8 14 * Time: 15:13 15 * Description: No Description 16 */ 17 @ControllerAdvice 18 public class NoPermissionException { 19 // 授权失败,就是说没有该权限 20 @ExceptionHandler(UnauthorizedException.class) 21 public String handleShiroException(Exception ex) { 22 return "/error/unAuth"; 23 } 24 25 @ResponseBody 26 @ExceptionHandler(AuthorizationException.class) 27 public String AuthorizationException(Exception ex) { 28 return "权限认证失败"; 29 } 30 }
9、下面写controller
1 package com.xiaostudy.shiro_test1.web.controller; 2 3 import org.apache.shiro.SecurityUtils; 4 import org.apache.shiro.authc.AuthenticationException; 5 import org.apache.shiro.authc.IncorrectCredentialsException; 6 import org.apache.shiro.authc.UnknownAccountException; 7 import org.apache.shiro.authc.UsernamePasswordToken; 8 import org.apache.shiro.subject.Subject; 9 import org.springframework.stereotype.Controller; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 /** 16 * 用户登录、登出、错误页面跳转控制器 17 * Created with IntelliJ IDEA. 18 * User: Administrator 19 * Date: 2019/6/8 20 * Time: 15:15 21 * Description: No Description 22 */ 23 @Controller 24 public class MainController { 25 26 @RequestMapping("/index") 27 public String index(HttpServletRequest request, HttpServletResponse response){ 28 response.setHeader("root", request.getContextPath()); 29 return "index"; 30 } 31 32 @RequestMapping("/login") 33 public String login(HttpServletRequest request, HttpServletResponse response){ 34 response.setHeader("root", request.getContextPath()); 35 String userName = request.getParameter("username"); 36 String password = request.getParameter("password"); 37 38 // 等于null说明用户没有登录,只是拦截所有请求到这里,那就直接让用户去登录页面,就不认证了。 39 // 如果这里不处理,那个会返回用户名不存在,逻辑上不合理,用户还没登录怎么就用户名不存在? 40 if(null == userName) { 41 return "login"; 42 } 43 44 // 1.获取Subject 45 Subject subject = SecurityUtils.getSubject(); 46 // 2.封装用户数据 47 UsernamePasswordToken token = new UsernamePasswordToken(userName, password); 48 // 3.执行登录方法 49 try{ 50 subject.login(token); 51 return "redirect:/index"; 52 } catch (UnknownAccountException e){ 53 // 这里是捕获自定义Realm的用户名不存在异常 54 request.setAttribute("msg","用户名不存在!"); 55 } catch (IncorrectCredentialsException e){ 56 request.setAttribute("userName",userName); 57 request.setAttribute("msg","密码错误!"); 58 } catch (AuthenticationException e) { 59 // 这里是捕获自定义Realm的认证失败异常 60 request.setAttribute("msg","认证失败!"); 61 } 62 63 return "login"; 64 } 65 66 @RequestMapping("/logout") 67 public String logout(){ 68 Subject subject = SecurityUtils.getSubject(); 69 if (subject != null) { 70 subject.logout(); 71 } 72 // return "redirect:/main"; 73 return "login"; 74 } 75 76 @RequestMapping("/error/unAuth") 77 public String unAuth(){ 78 return "/error/unAuth"; 79 } 80 81 @RequestMapping("/err") 82 public String err(){ 83 return "/error/unAuth"; 84 } 85 }
1 package com.xiaostudy.shiro_test1.web.controller; 2 3 import com.xiaostudy.shiro_test1.entity.UserEntity; 4 import org.apache.shiro.SecurityUtils; 5 import org.apache.shiro.authz.annotation.RequiresPermissions; 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 9 import javax.servlet.http.HttpServletRequest; 10 11 /** 12 * 用户页面跳转 13 * Created with IntelliJ IDEA. 14 * User: Administrator 15 * Date: 2019/6/8 16 * Time: 15:21 17 * Description: No Description 18 */ 19 @Controller 20 public class UserController { 21 22 /** 23 * 个人中心,需认证可访问 24 */ 25 @RequestMapping("/user/index") 26 @RequiresPermissions(value = "user")// 这里的user,就是对应权限实体类PermissionEntity的字段url,自定义Realm类UserRealm里是用这个字段 27 public String add(HttpServletRequest request){ 28 UserEntity bean = (UserEntity) SecurityUtils.getSubject().getPrincipal(); 29 request.setAttribute("userName", bean.getName()); 30 return "/user/index"; 31 } 32 33 /** 34 * 会员中心,需认证且角色为vip可访问 35 */ 36 @RequestMapping("/vip/index") 37 @RequiresPermissions(value = "vip") 38 public String update(){ 39 return "/vip/index"; 40 } 41 }
10、下面写spring-mvc.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:mvc="http://www.springframework.org/schema/mvc" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans 9 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 10 http://www.springframework.org/schema/mvc 11 http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 12 http://www.springframework.org/schema/context 13 http://www.springframework.org/schema/context/spring-context-3.2.xsd 14 http://www.springframework.org/schema/aop 15 http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 16 http://www.springframework.org/schema/tx 17 http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> 18 19 <!-- 把Controller交给spring管理 --> 20 <context:component-scan base-package="com.xiaostudy"/> 21 22 <!-- 配置注解处理器映射器 功能:寻找执行类Controller --> 23 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> 24 25 <!-- 配置注解处理器适配器 功能:调用controller方法,执行controller --> 26 <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> 27 28 <!-- 配置sprigmvc视图解析器:解析逻辑试图 29 后台返回逻辑试图:index 30 视图解析器解析出真正物理视图:前缀+逻辑试图+后缀====/WEB-INF/index.jsp --> 31 <!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 32 <property name="prefix" value="/WEB-INF/"/> 33 <property name="suffix" value=".jsp"/> 34 </bean>--> 35 </beans>
11、下面写web.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" 5 version="4.0"> 6 <display-name>Archetype Created Web Application</display-name> 7 8 <!--请求编码设置--> 9 <filter> 10 <filter-name>encodingFilter</filter-name> 11 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 12 <init-param> 13 <param-name>encoding</param-name> 14 <param-value>UTF-8</param-value> 15 </init-param> 16 <init-param> 17 <param-name>forceEncoding</param-name> 18 <param-value>true</param-value> 19 </init-param> 20 </filter> 21 <filter-mapping> 22 <filter-name>encodingFilter</filter-name> 23 <url-pattern>/*</url-pattern> 24 </filter-mapping> 25 26 <listener> 27 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 28 </listener> 29 <listener> 30 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> 31 </listener> 32 <servlet> 33 <servlet-name>SpringMVC</servlet-name> 34 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 35 <init-param> 36 <param-name>contextConfigLocation</param-name> 37 <param-value>classpath:spring-mvc.xml</param-value> 38 </init-param> 39 <load-on-startup>1</load-on-startup> 40 <async-supported>true</async-supported> 41 </servlet> 42 <servlet-mapping> 43 <servlet-name>SpringMVC</servlet-name> 44 <url-pattern>/</url-pattern> 45 </servlet-mapping> 46 <welcome-file-list> 47 <welcome-file>/index</welcome-file> 48 </welcome-file-list> 49 </web-app>
12、下面写application.yml
1 spring: 2 datasource: 3 url: jdbc:mysql://localhost:3306/shiro_test?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC 4 username: root 5 password: root 6 driver-class-name: com.mysql.cj.jdbc.Driver 7 type: com.alibaba.druid.pool.DruidDataSource 8 # 初始化时建立物理连接连接的个数 9 initialSize: 5 10 # 最小连接池数量 11 minIdle: 5 12 # 最大连接池数量 13 maxActive: 20 14 # 获取连接时最大等待时间(ms),即60s 15 maxWait: 60000 16 # 1.Destroy线程会检测连接的间隔时间;2.testWhileIdle的判断依据 17 timeBetweenEvictionRunsMillis: 60000 18 # 最小生存时间ms 19 minEvictableIdleTimeMillis: 600000 20 maxEvictableIdleTimeMillis: 900000 21 # 用来检测连接是否有效的sql 22 validationQuery: SELECT 1 FROM DUAL 23 # 申请连接时执行validationQuery检测连接是否有效,启用会降低性能 24 testOnBorrow: false 25 # 归还连接时执行validationQuery检测连接是否有效,启用会降低性能 26 testOnReturn: false 27 # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis, 28 # 执行validationQuery检测连接是否有效,不会降低性能 29 testWhileIdle: true 30 # 是否缓存preparedStatement,mysql建议关闭 31 poolPreparedStatements: false 32 # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 33 filters: stat,wall,log4j 34 thymeleaf: 35 suffix: .html 36 charset: utf-8 37 mvc: 38 # 配置静态资源映射路径,/public、/resources路径失效 39 static-path-pattern: templates/** 40 mybatis: 41 mapper-locations: classpath:mapper/*.xml 42 # mapperLocations: classpath:mapper/*.xml 43 # 虽然可以配置这项来进行pojo包扫描,但其实我更倾向于在mapper.xml写全类名 44 # type-aliases-package: com.xiaostudy.shiro_test1.entity
13、下面写html
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>登录</title> 6 </head> 7 <body> 8 <h1>用户登录</h1> 9 <hr> 10 <form id="from" action="/login" method="post"> 11 <table> 12 <tr> 13 <td>用户名</td> 14 <td> 15 <input type="text" name="username" placeholder="请输入账户名" value="" th:value="${userName }"/> 16 </td> 17 </tr> 18 <tr> 19 <td>密码</td> 20 <td> 21 <input type="password" name="password" placeholder="请输入密码"/> 22 </td> 23 </tr> 24 <tr> 25 <td colspan="2"> 26 <span style="color: red;">[[${msg }]]</span> 27 </td> 28 </tr> 29 <tr> 30 <td colspan="2"> 31 <input type="submit" value="登录"/> 32 <input type="reset" value="重置"/> 33 </td> 34 </tr> 35 </table> 36 </form> 37 </body> 38 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <title>首页</title> 6 </head> 7 <body> 8 <h1>首页</h1> 9 <hr> 10 <ul> 11 <li><a href="user/index">个人中心</a></li> 12 <li><a href="vip/index">会员中心</a></li> 13 <li><a href="logout">退出登录</a></li> 14 </ul> 15 </body> 16 </html>
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <title>用户中心</title> 5 </head> 6 <body> 7 <h1>用户中心</h1> 8 <hr> 9 <h1>欢迎[[${userName }]],这里是用户中心</h1> 10 </body> 11 </html>
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <title>会员中心</title> 5 </head> 6 <body> 7 <h1>会员中心</h1> 8 <hr> 9 <h1>欢迎来到<span style="color: red;">会员中心</span></h1> 10 </body> 11 </html>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <title>未授权提示</title> 5 </head> 6 <body> 7 <h1>您还不是<span style="color: red;">会员</span> ,没有权限访问这个页面!</h1> 8 </body> 9 </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