测试项目已上传到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