目录
1.搭建SSM框架
1.1.引入相关的依赖
1.2. spring配置文件
1.3. web.xml配置文件
1.4.配置Tomcat并启动
2.ssm整合shiro---认证功能
(1).引入依赖
(2).修改spring配置文件
(3).修改web.xml文件
(4).新建login.jsp(登录页面)
(5).新建success.jsp(登录成功后跳转到此)
(6).创建User实体类
(7).创建LoginVo
(8).controller层
(9).创建MyRealm
(10).创建UserService接口
(11).创建UserServiceImpl实现类
(12).创建dao方法
(13).创建dao方法的映射代码UserMapper.xml
(14).启动Tomcat测试
3.ssm整合shiro---授权
(1).创建Permission实体类
(2).修改myRealm
(3).UserService添加
(4).UserServiceImpl
(5).userDao
(6).UserMapper.xml
(7).success.jsp
(8).新建UserController
(9).测试
(10).shiro注解
(11).处理权限不足的异常
1.创建一个异常处理类
2.创建一个403.jsp
3.测试
3.ssm整合shiro前后端分离
以下后台返回结果改为json格式数据:
3.1.根据账号和密码登录后---返回json数据
(1).定义一个统一的json类
(2) 修改controller代码
3.2.权限不足时---返回json数据
(1).修改权限不足的异常处理类
3.3.未登录时---返回json数据
(1).第一种: 未登录跳转到一个接口路径
(2).第二种: 定义过滤器
测试
4.shiro权限对象缓存到redis中
(1).依赖
(2).修改spring配置文件
1.搭建SSM框架
1.1.引入相关的依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>shiro-ssm</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>shiro-ssm Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.31</version> </dependency> <!--spring的相关依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.15.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.15.RELEASE</version> </dependency> <!--mybatis的依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> </dependency> <!--jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency> <!--jsp servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!--druid依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency> </dependencies> <build> <finalName>shiro-ssm</finalName> </build> </project>
1.2. spring配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--包扫描--> <context:component-scan base-package="com.wqg"/> <!--2.注解驱动--> <mvc:annotation-driven/> <!--3.静态资源放行--> <mvc:default-servlet-handler/> <!--4.视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!--数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="username" value="root"/> <property name="password" value="root"/> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/shiro?serverTimezone=Asia/Shanghai"/> </bean> <!--SqlSessionFactory 加载mybatis的配置--> <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!--映射文件所在的路径--> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!--7.设置dao接口的代理实现类--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sessionFactory"/> <!--dao接口所在的包--> <property name="basePackage" value="com.wqg.dao"/> </bean> <!--事务管理--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--开启事务的注解驱动--> <tx:annotation-driven/> </beans>
1.3. web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置前端控制器--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring.xml</param-value> </init-param> <!--tomcat启动时加载该类--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
1.4.配置Tomcat并启动
2.ssm整合shiro---认证功能
数据库结构
/* Navicat Premium Data Transfer Source Server : 实训 Source Server Type : MySQL Source Server Version : 80032 Source Host : localhost:3306 Source Schema : shiro Target Server Type : MySQL Target Server Version : 80032 File Encoding : 65001 Date: 06/07/2023 11:16:35 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for permission -- ---------------------------- DROP TABLE IF EXISTS `permission`; CREATE TABLE `permission` ( `perid` int(0) NOT NULL AUTO_INCREMENT, `pername` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `percode` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, PRIMARY KEY (`perid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of permission -- ---------------------------- INSERT INTO `permission` VALUES (1, '查询用户信息', 'user:query'); INSERT INTO `permission` VALUES (2, '修改用户', 'user:update'); INSERT INTO `permission` VALUES (3, '删除用户', 'user:delete'); INSERT INTO `permission` VALUES (4, '添加用户', 'user:insert'); INSERT INTO `permission` VALUES (5, '导出用户', 'user:export'); -- ---------------------------- -- Table structure for role -- ---------------------------- DROP TABLE IF EXISTS `role`; CREATE TABLE `role` ( `roleid` int(0) NOT NULL AUTO_INCREMENT, `rolename` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, PRIMARY KEY (`roleid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of role -- ---------------------------- INSERT INTO `role` VALUES (1, '仓管管理员'); INSERT INTO `role` VALUES (2, 'CEO'); INSERT INTO `role` VALUES (3, '保安'); -- ---------------------------- -- Table structure for role_permission -- ---------------------------- DROP TABLE IF EXISTS `role_permission`; CREATE TABLE `role_permission` ( `perid` int(0) NOT NULL, `roleid` int(0) NOT NULL, PRIMARY KEY (`perid`, `roleid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of role_permission -- ---------------------------- INSERT INTO `role_permission` VALUES (1, 1); INSERT INTO `role_permission` VALUES (1, 2); INSERT INTO `role_permission` VALUES (1, 3); INSERT INTO `role_permission` VALUES (2, 1); INSERT INTO `role_permission` VALUES (2, 2); INSERT INTO `role_permission` VALUES (3, 1); INSERT INTO `role_permission` VALUES (3, 2); INSERT INTO `role_permission` VALUES (4, 1); INSERT INTO `role_permission` VALUES (5, 3); -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `userid` int(0) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `userpwd` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `sex` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, `salt` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL, PRIMARY KEY (`userid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'zhangsan', '4b05a8716a430f71c6911d2e9149092f', '男', '武汉', '07f63bbf285e4719bfee1cc2bb81db33'); INSERT INTO `user` VALUES (2, 'lisi', '99cc11855b41ff3e5f7c0af3c5090a8c', '女', '北京', '2d7e37f019144764ac02aa7220929f93'); INSERT INTO `user` VALUES (3, 'wangwu', '6d70c027801af4dc892ab340d4bf73b6', '女', '成都', '99f6bf1b540145699e6e5c90480105b0'); -- ---------------------------- -- Table structure for user_role -- ---------------------------- DROP TABLE IF EXISTS `user_role`; CREATE TABLE `user_role` ( `userid` int(0) NOT NULL, `roleid` int(0) NOT NULL, PRIMARY KEY (`userid`, `roleid`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user_role -- ---------------------------- INSERT INTO `user_role` VALUES (1, 1); INSERT INTO `user_role` VALUES (2, 2); INSERT INTO `user_role` VALUES (3, 3); SET FOREIGN_KEY_CHECKS = 1;
(1).引入依赖
<!--shiro-spring整合的依赖--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.0</version> </dependency>
(2).修改spring配置文件
加入:
<!--shiro和spring整合的配置--> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="myRealm"/> </bean> <bean id="myRealm" class="com.wqg.realm.MyRealm"> <property name="credentialsMatcher" ref="credentialsMatcher"/> </bean> <!--加密器--> <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> <property name="hashAlgorithmName" value="MD5"/> <property name="hashIterations" value="1024"/> </bean> <!--shiro过滤器 id:必须和web.xml里面的过滤器配置的名称对应--> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> <!--未登录时跳转的路径--> <property name="loginUrl" value="/login.jsp"/> <!--过滤规则--> <property name="filterChainDefinitions"> <value> /login=anon /**=authc </value> </property> </bean>
(3).修改web.xml文件
加入:
<!--shiro的过滤器:必须和ShiroFilterFactoryBean的id一致--> <filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
(4).新建login.jsp(登录页面)
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/6 Time: 16:03 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="/login" method="post"> 账号:<input type="text" name="username"/><br><br> 密码:<input type="text" name="password"/><br><br> <input type="submit" value="登录"/> </form> </body> </html>
(5).新建success.jsp(登录成功后跳转到此)
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/6 Time: 16:09 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Welcome to Henan</h1> </body> </html>
(6).创建User实体类
@Data public class User { private Integer userid; private String username; private String userpwd; private String sex; private String address; private String salt; }
(7).创建LoginVo
@Data public class LoginVo { private String Password; private String Username; }
(8).controller层
@Controller public class LoginController { @PostMapping("/login") public String login(LoginVo loginVo){//@RequestBody接受的json对象参数。 不加:表单数据以及地址栏传递的数据 //传递的数据校验 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(loginVo.getUsername(),loginVo.getPassword()); try { subject.login(token); return "success"; //经过视图解析器 /WEB-INF/views/success.jsp }catch (Exception e){ e.printStackTrace(); return "redirect:/login.jsp"; } } }
(9).创建MyRealm
package com.wqg.realm; import com.wqg.entity.User; import com.wqg.service.UserService; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.util.ByteSource; import org.springframework.beans.factory.annotation.Autowired; /** * @ fileName:MyRealm * @ description: * @ author:wqg * @ createTime:2023/7/6 15:46 */ public class MyRealm extends AuthorizingRealm { @Autowired private UserService userService; protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { return null; } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { //1.获取登录账号 String username = token.getPrincipal().toString(); //2.根据账号获取用户信息 User user = userService.selectByUsername(username); if (user != null) { ByteSource salt = ByteSource.Util.bytes(user.getSalt()); SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getUserpwd(), salt, this.getName()); return info; } return null; } }
(10).创建UserService接口
public interface UserService { User selectByUsername(String username); }
(11).创建UserServiceImpl实现类
@Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; public User selectByUsername(String username) { User user = userDao.findByUsername(username); return user; } }
(12).创建dao方法
public interface UserDao { User findByUsername(String username); }
(13).创建dao方法的映射代码UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namesapce的内容必须和对应的接口路径映射--> <mapper namespace="com.wqg.dao.UserDao"> <select id="findByUsername" resultType="com.wqg.entity.User"> select * from user where username=#{username} </select> </mapper>
(14).启动Tomcat测试
3.ssm整合shiro---授权
(1).创建Permission实体类
@Data public class Permission { private Integer perid; private String pername; private String percode; }
(2).修改myRealm
//授权 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { //获取当前登录者的账号 User user = (User) principals.getPrimaryPrincipal(); //调用userSerice中的方法--根据id List<String> permissions = userService.selectPermissionByUserid(user.getUserid()); if (permissions.size() != 0) { SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermissions(permissions); return info; } return null; }
(3).UserService添加
List<String> selectPermissionByUserid(Integer userid);
(4).UserServiceImpl
@Override public List<String> selectPermissionByUserid(Integer userid) { List<Permission> permissionList= userDao.findPermissionByUserid(userid); List<String> collect = permissionList.stream().map(item -> item.getPercode()).collect(Collectors.toList()); return collect; }
(5).userDao
List<Permission> findPermissionByUserid(Integer userid);
(6).UserMapper.xml
<select id="findPermissionByUserid" resultType="com.wqg.entity.Permission"> select p.* from user_role ur join role_permission rp on ur.roleId=rp.roleid join permission p on rp.perid=p.perid where ur.userid=#{userId} </select>
(7).success.jsp
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/6 Time: 16:09 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <html> <head> <title>Title</title> </head> <body> <%--拥有不同权限的人登录所看到的权限不同--%> <shiro:hasPermission name="user:query"><a href="/user/query">查询用户</a></shiro:hasPermission> <shiro:hasPermission name="user:update"><a href="/user/update">修改用户</a></shiro:hasPermission> <shiro:hasPermission name="user:delete"><a href="/user/delete">删除用户</a></shiro:hasPermission> <shiro:hasPermission name="user:insert"><a href="/user/insert">添加用户</a></shiro:hasPermission> <shiro:hasPermission name="user:export"><a href="/user/export">导出用户</a></shiro:hasPermission> </body> </html>
(8).新建UserController
package com.wqg.controller; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ fileName:UserController * @ description: * @ author:wqg * @ createTime:2023/7/6 16:42 */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/query") public String query(){ return "user:query------------------------"; } @GetMapping("/update") public String update(){ return "user:update------------------------"; } @GetMapping("/delete") public String delete(){ return "user:delete------------------------"; } @GetMapping("/insert") public String insert(){ return "user:insert------------------------"; } @GetMapping("/export") public String export(){ return "user:export------------------------"; } }
(9).测试
现在虽然可以在浏览器看到相应的权限---可是可以同别的方式访问后台对应的资源。
shiro提供了注解。---判断当前是否具有该注解的权限---才会执行对应的资源方法
(10).shiro注解
package com.wqg.controller; import org.apache.shiro.authz.annotation.Logical; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @ fileName:UserController * @ description: * @ author:wqg * @ createTime:2023/7/6 16:42 */ @RestController @RequestMapping("/user") public class UserController { @GetMapping("/query") @RequiresPermissions(value = {"user:query","user:delete"},logical = Logical.OR) //可以通过多个路径访问内部资源 //@RequiresPermissions(value = "user:query") public String query(){ return "user:query------------------------"; } @GetMapping("/update") @RequiresPermissions(value = "user:update") public String update(){ return "user:update------------------------"; } @GetMapping("/delete") @RequiresPermissions(value = "user:delete") public String delete(){ return "user:delete------------------------"; } @GetMapping("/insert") @RequiresPermissions(value = "user:insert") public String insert(){ return "user:insert------------------------"; } @GetMapping("/export") @RequiresPermissions(value = "user:export") //该注解不能被识别 public String export(){ return "user:export------------------------"; } }
发现上面注解不生效-----spring没有开启该注解的驱动---spring配置文件加入如下内容
<!-- 启动Shrio的注解 shiro加在controller应该属于springmvc的配置 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" /> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean>
测试:
在查询用户 中输入当前用户没有的权限的地址会跳转失败,证明测试成功
(11).处理权限不足的异常
处理上方权限不足导致的500报错
1.创建一个异常处理类
把上面抛出的异常放入ExceptionHandler注解中
@ControllerAdvice public class MyHandler { //捕获异常 @ExceptionHandler(value = UnauthorizedException.class) public String unauthorizedException(UnauthorizedException e){ e.printStackTrace(); return "403"; } }
2.创建一个403.jsp
<%-- Created by IntelliJ IDEA. User: Administrator Date: 2023/7/7 Time: 13:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> 权限不足~~~~~ </body> </html>
3.测试
4.ssm整合shiro前后端分离
前后分离------后台返回的都是json数据
以下后台返回结果改为json格式数据:
根据账号和密码登录后
权限不足时
未登录
4.1.根据账号和密码登录后---返回json数据
(1).定义一个统一的json类
@Data @NoArgsConstructor @AllArgsConstructor public class Result { private Integer code; private String msg; private Object data; }
(2) 修改controller代码
@PostMapping("/login") @ResponseBody public Result login(LoginVo loginVo){//@RequestBody接受的json对象参数。 不加:表单数据以及地址栏传递的数据 //传递的数据校验 Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token=new UsernamePasswordToken(loginVo.getUsername(),loginVo.getPassword()); try { subject.login(token); return new Result(200,"登录成功",null); }catch (Exception e){ e.printStackTrace(); return new Result(500,"登录失败",null); } }
4.2.权限不足时---返回json数据
(1).修改权限不足的异常处理类
//@ControllerAdvice:处理controller中出现的异常,该类注解必须能被spring扫描到 @ControllerAdvice public class MyHandler { //捕获异常 @ExceptionHandler(value = UnauthorizedException.class) @ResponseBody public Result unauthorizedException(UnauthorizedException e) { e.printStackTrace(); return new Result(403, "权限不足", null); } }
4.3.未登录时---返回json数据
(1).第一种: 未登录跳转到一个接口路径
(2).第二种: 定义过滤器
加入依赖
public class LoginFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { // 设置响应的内容类型为JSON,并使用UTF-8编码 response.setContentType("application/json;charset=utf-8"); // 获取用于写入响应的PrintWriter对象 PrintWriter writer = response.getWriter(); // 创建一个Result对象,包含401状态码和提示信息 Result result = new Result(401, "请先登录---", null); // 将Result对象转换为JSON字符串 String jsonString = JSON.toJSONString(result); // 将JSON字符串写入响应 writer.println(jsonString); // 刷新并关闭PrintWriter对象 writer.flush(); writer.close(); // 返回false,表示请求应在此处停止 return false; } }
修改spring配置文件
测试
5.shiro权限对象缓存到redis中
目的:避免频繁的查询数据库
(1).依赖
<!--shiro和redis整合的依赖--> <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>2.4.6</version> </dependency>
(2).修改spring配置文件