1
0
mirror of https://gitee.com/dromara/sa-token.git synced 2025-04-05 17:37:53 +08:00

SSM 架构整合 Sa-Token 简单示例

This commit is contained in:
click33 2024-04-15 20:55:02 +08:00
parent 18bce0877e
commit ccb79f6494
22 changed files with 935 additions and 0 deletions

View File

@ -0,0 +1,10 @@
## SSM 架构集成 Sa-Token 示例
说是SSM其实没有M仅仅是给使用 SpringMVC 非 SpringBoot 的项目提供一个简单的 Sa-Token 集成示例。
直接运行项目即可,里面注释挺全的,也不必做过多说明了
(其实就是我懒,光搭建起来这个架子就累瘫了,各种版本兼容问题报起错来大汗淋漓,推荐新项目能上 SpringBoot 就赶紧上吧千万别在SSM上浪费生命
推荐 jdk8 + tomcat8。

View File

@ -0,0 +1,133 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-demo-ssm</artifactId>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<version>0.0.1-SNAPSHOT</version>
<!-- 定义 Sa-Token 版本号 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--<spring.version>4.2.5.RELEASE</spring.version>-->
<spring.version>5.3.7</spring.version>
<jackson.version>2.16.1</jackson.version>
<sa-token.version>1.37.0</sa-token.version>
</properties>
<dependencies>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- Spring 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Jackson 依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Sa-Token 权限认证在线文档https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>${sa-token.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.2</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,74 @@
package com.pj.controller;
import cn.dev33.satoken.annotation.*;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 注解鉴权测试
* @author click33
*
*/
@RestController
@RequestMapping("/at/")
public class AtController {
// 登录认证登录之后才可以进入方法 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkLogin
@SaCheckLogin
@RequestMapping("checkLogin")
public SaResult checkLogin() {
return SaResult.ok();
}
// 权限认证具备user-add权限才可以进入方法 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkPermission
@SaCheckPermission("user-add")
@RequestMapping("checkPermission")
public SaResult checkPermission() {
return SaResult.ok();
}
// 权限认证同时具备所有权限才可以进入 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkPermissionAnd
@SaCheckPermission({"user-add", "user-delete", "user-update"})
@RequestMapping("checkPermissionAnd")
public SaResult checkPermissionAnd() {
return SaResult.ok();
}
// 权限认证只要具备其中一个就可以进入 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkPermissionOr
@SaCheckPermission(value = {"user-add", "user-delete", "user-update"}, mode = SaMode.OR)
@RequestMapping("checkPermissionOr")
public SaResult checkPermissionOr() {
return SaResult.ok();
}
// 角色认证只有具备admin角色才可以进入 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkRole
@SaCheckRole("admin")
@RequestMapping("checkRole")
public SaResult checkRole() {
return SaResult.ok();
}
// 完成二级认证 ---- http://localhost:8080/sa_token_demo_ssm_war/at/openSafe
@RequestMapping("openSafe")
public SaResult openSafe() {
StpUtil.openSafe(200); // 打开二级认证有效期为200秒
return SaResult.ok();
}
// 通过二级认证后才可以进入 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkSafe
@SaCheckSafe
@RequestMapping("checkSafe")
public SaResult checkSafe() {
return SaResult.ok();
}
// 通过Basic认证后才可以进入 ---- http://localhost:8080/sa_token_demo_ssm_war/at/checkBasic
@SaCheckBasic(account = "sa:123456")
@RequestMapping("checkBasic")
public SaResult checkBasic() {
return SaResult.ok();
}
}

View File

@ -0,0 +1,55 @@
package com.pj.controller;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 登录测试
* @author click33
*
*/
@RestController
@RequestMapping("/acc/")
public class LoginController {
// 测试登录 ---- http://localhost:8080/sa_token_demo_ssm_war/acc/doLogin?name=zhang&pwd=123456
@RequestMapping("doLogin")
public SaResult doLogin(String name, String pwd) {
System.out.println("-------- 12344");
// 此处仅作模拟示例真实项目需要从数据库中查询数据进行比对
if("zhang".equals(name) && "123456".equals(pwd)) {
StpUtil.login(10001);
return SaResult.ok("登录成功");
}
return SaResult.error("登录失败");
}
// 查询登录状态 ---- http://localhost:8080/sa_token_demo_ssm_war/acc/isLogin
@RequestMapping("isLogin")
public SaResult isLogin() {
return SaResult.ok("是否登录:" + StpUtil.isLogin());
}
// 校验登录 ---- http://localhost:8080/sa_token_demo_ssm_war/acc/checkLogin
@RequestMapping("checkLogin")
public SaResult checkLogin() {
StpUtil.checkLogin();
return SaResult.ok();
}
// 查询 Token 信息 ---- http://localhost:8080/sa_token_demo_ssm_war/acc/tokenInfo
@RequestMapping("tokenInfo")
public SaResult tokenInfo() {
return SaResult.data(StpUtil.getTokenInfo());
}
// 测试注销 ---- http://localhost:8080/sa_token_demo_ssm_war/acc/logout
@RequestMapping("logout")
public SaResult logout() {
StpUtil.logout();
return SaResult.ok();
}
}

View File

@ -0,0 +1,38 @@
package com.pj.controller;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 页面访问测试
* @author click33
* @since 2024/4/14
*/
@Controller
public class PageController {
// http://localhost:8080/sa_token_demo_ssm_war/home
@RequestMapping("/home")
public String index() {
System.out.println("------- home页所有游客可访问");
return "home";
}
// http://localhost:8080/sa_token_demo_ssm_war/user
@RequestMapping("/user")
public String user() {
System.out.println("------- user页登录后才能访问");
StpUtil.checkLogin();
return "user";
}
// http://localhost:8080/sa_token_demo_ssm_war/admin
@RequestMapping("/admin")
public String admin() {
System.out.println("------- admin页具有admin角色才能访问");
StpUtil.checkRole("admin");
return "admin";
}
}

View File

@ -0,0 +1,54 @@
package com.pj.controller;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
* 测试专用Controller
* @author click33
*
*/
@RestController
@RequestMapping("/test/")
public class TestController {
// 测试登录 ---- http://localhost:8080/sa_token_demo_ssm_war/test/login
@RequestMapping("login")
public SaResult login(@RequestParam(defaultValue = "10001") long id) {
StpUtil.login(id, SaLoginConfig.setActiveTimeout(-1));
return SaResult.ok("登录成功");
}
// 测试 浏览器访问 http://localhost:8080/sa_token_demo_ssm_war/test/test
@RequestMapping("test")
public SaResult test() {
System.out.println("------------进来了 " + SaFoxUtil.formatDate(new Date()));
// StpUtil.getLoginId();
// 返回
return SaResult.data(null);
}
// 测试 浏览器访问 http://localhost:8080/sa_token_demo_ssm_war/test/test2
@RequestMapping("test2")
public SaResult test2() {
return SaResult.ok();
}
// 测试 浏览器访问 http://localhost:8080/sa_token_demo_ssm_war/getRequestPath
@RequestMapping("getRequestPath")
public SaResult getRequestPath() {
System.out.println("------------ 测试访问路径获取 ");
// System.out.println("SpringMVCUtil.getRequest().getRequestURI() " + SpringMVCUtil.getRequest().getRequestURI());
System.out.println("SaHolder.getRequest().getRequestPath() " + SaHolder.getRequest().getRequestPath());
return SaResult.ok();
}
}

View File

@ -0,0 +1,29 @@
package com.pj.current;
import cn.dev33.satoken.util.SaResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 全局异常处理
*/
@RestControllerAdvice
public class GlobalException {
// 全局异常拦截拦截项目中的所有异常
@ExceptionHandler
public SaResult handlerException(Exception e, HttpServletRequest request, HttpServletResponse response) {
// 打印堆栈以供调试
System.err.println("全局异常---------------");
e.printStackTrace();
// 返回给前端
return SaResult.error(e.getMessage());
}
}

View File

@ -0,0 +1,24 @@
package com.pj.current;
import cn.dev33.satoken.util.SaResult;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 处理 404
* @author click33
*/
@RestController
public class NotFoundHandle implements ErrorController {
@RequestMapping("/error")
public Object error(HttpServletRequest request, HttpServletResponse response) {
response.setStatus(200);
return SaResult.get(404, "not found", null);
}
}

View File

@ -0,0 +1,83 @@
package com.pj.model;
/**
* User 实体类
*
* @author click33
* @since 2022-10-15
*/
public class SysUser {
public SysUser() {}
public SysUser(long id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
/**
* 用户id
*/
private long id;
/**
* 用户名称
*/
private String name;
/**
* 用户年龄
*/
private int age;
/**
* @return id
*/
public long getId() {
return id;
}
/**
* @param id 要设置的 id
*/
public void setId(long id) {
this.id = id;
}
/**
* @return name
*/
public String getName() {
return name;
}
/**
* @param name 要设置的 name
*/
public void setName(String name) {
this.name = name;
}
/**
* @return age
*/
public int getAge() {
return age;
}
/**
* @param age 要设置的 age
*/
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "SysUser [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}

View File

@ -0,0 +1,32 @@
package com.pj.satoken;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.interceptor.SaInterceptor;
/**
* 路由拦截鉴权测试
* @author click33
* @since 2024/4/15
*/
public class SaInterceptorImpl extends SaInterceptor {
public SaInterceptorImpl() {
super(hadnle->{
System.out.println("-------------- SA 路由拦截鉴权,你访问的是:" + SaHolder.getRequest().getRequestPath());
// System.out.println("你访问的是:" + SaHolder.getRequest().getRequestPath());
// SaRouter.match("/test/test", r -> StpUtil.checkLogin());
// 根据路由划分模块不同模块不同鉴权
// SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
// SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
// SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
// SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
// SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
// SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
// 更多写法参考https://sa-token.cc/doc.html#/use/route-check
});
}
}

View File

@ -0,0 +1,54 @@
package com.pj.satoken;
import cn.dev33.satoken.application.ApplicationInfo;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.dao.SaTokenDaoRedisJackson;
import cn.dev33.satoken.log.SaLog;
import cn.dev33.satoken.spring.SaBeanInject;
import cn.dev33.satoken.spring.SaTokenContextForSpring;
import cn.dev33.satoken.spring.json.SaJsonTemplateForJackson;
import org.springframework.data.redis.connection.RedisConnectionFactory;
/**
* 手动注入 Sa-Token 所需要的组件
* @author click33
* @since 2024/4/15
*/
public class SaTokenBeanInjection {
public SaTokenBeanInjection(
SaLog log,
SaTokenConfig config,
RedisConnectionFactory connectionFactory,
String routePrefix
) {
System.out.println("---------------- 手动注入 Sa-Token 所需要的组件 start ----------------");
// 日志组件配置信息
SaBeanInject inject = new SaBeanInject(log, config);
// 基于 Spring 的上下文处理器
inject.setSaTokenContext(new SaTokenContextForSpring());
// 基于 Jackson json解析器
inject.setSaJsonTemplate(new SaJsonTemplateForJackson());
// 基于 Jackson 序列化的 Redis 持久化组件
SaTokenDaoRedisJackson saTokenDaoRedisJackson = new SaTokenDaoRedisJackson();
saTokenDaoRedisJackson.init(connectionFactory);
inject.setSaTokenDao(saTokenDaoRedisJackson);
// 权限和角色数据
inject.setStpInterface(new StpInterfaceImpl());
// 项目路由前缀方便路由拦截鉴权的
ApplicationInfo.routePrefix = routePrefix;
// System.out.println(routePrefix);
// 注入更多组件 ....
// inject.setXxx
System.out.println("---------------- 手动注入 Sa-Token 所需要的组件 end ----------------");
}
}

View File

@ -0,0 +1,41 @@
package com.pj.satoken;
import cn.dev33.satoken.stp.StpInterface;
import java.util.ArrayList;
import java.util.List;
/**
* 自定义权限验证接口扩展
*/
public class StpInterfaceImpl implements StpInterface {
/**
* 返回一个账号所拥有的权限码集合
*/
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
// 本list仅做模拟实际项目中要根据具体业务逻辑来查询权限
List<String> list = new ArrayList<String>();
list.add("101");
list.add("user-add");
list.add("user-delete");
list.add("user-update");
list.add("user-get");
list.add("article-get");
return list;
}
/**
* 返回一个账号所拥有的角色标识集合
*/
@Override
public List<String> getRoleList(Object loginId, String loginType) {
// 本list仅做模拟实际项目中要根据具体业务逻辑来查询角色
List<String> list = new ArrayList<String>();
list.add("admin");
list.add("super-admin");
return list;
}
}

View File

@ -0,0 +1,49 @@
# 端口
server:
port: 8081
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
sa-token:
# token 名称 (同时也是 cookie 名称)
token-name: satoken
# token 有效期(单位:秒) 默认30天-1 代表永久有效
timeout: 2592000
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
active-timeout: -1
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token
is-share: true
# token 风格默认可取值uuid、simple-uuid、random-32、random-64、random-128、tik
token-style: uuid
# 是否输出操作日志
is-log: true
spring:
# redis配置
redis:
# Redis数据库索引默认为0
database: 0
# Redis服务器地址
host: 127.0.0.1
# Redis服务器连接端口
port: 6379
# Redis服务器连接密码默认为空
password:
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池最大连接数
max-active: 200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
# 连接池中的最大空闲连接
max-idle: 10
# 连接池中的最小空闲连接
min-idle: 0

View File

@ -0,0 +1,22 @@
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- 导入配置 -->
<import resource="spring-sa-token.xml" />
<import resource="spring-redis.xml" />
</beans>

View File

@ -0,0 +1,59 @@
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--避免IE执行AJAX时返回JSON出现下载文件 -->
<bean id="mappingJackson2HttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>text/json;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 添加扫描注解,此包下 -->
<context:component-scan base-package="com.pj.controller,com.pj.current" />
<mvc:annotation-driven/>
<!-- 拦截器 -->
<mvc:interceptors>
<!-- 注解鉴权拦截器 -->
<!-- 想要使用注解鉴权,需要打开这个 -->
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cn.dev33.satoken.interceptor.SaInterceptor" />
</mvc:interceptor>
<!-- 路由鉴权拦截器 -->
<!--
注意:这里的 [路由拦截鉴权] 和上面的 [注解鉴权拦截器] 只能打开一个,
因为 SaInterceptor 自带注解鉴权效果,如果两个都打开了,会导致一个注解被拦截校验两次
-->
<!--<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="com.pj.satoken.SaInterceptorImpl" />
</mvc:interceptor>-->
</mvc:interceptors>
<!-- 配置视图解析器 -->
<!-- 对转向页面的路径解析。prefix前缀 suffix后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

View File

@ -0,0 +1,47 @@
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!-- Redis 连接信息 -->
<bean id="redisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="127.0.0.1"/>
<property name="port" value="6379"/>
<property name="password" value=""/>
<property name="database" value="10"/>
<property name="poolConfig" ref="poolConfig"/>
</bean>
<!-- Redis 连接池配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--最大空闲数-->
<property name="maxIdle" value="300"/>
<!--连接池的最大数据库连接数 -->
<property name="maxTotal" value="1000"/>
<!--最大建立连接等待时间-->
<property name="maxWaitMillis" value="1000"/>
<!--逐出连接的最小空闲时间 默认1800000毫秒(30分钟)-->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<!--每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3-->
<property name="numTestsPerEvictionRun" value="1024"/>
<!--逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1-->
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->
<property name="testOnBorrow" value="true"/>
<!--在空闲时检查有效性, 默认false -->
<property name="testWhileIdle" value="true"/>
</bean>
</beans>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
<!-- Spring 集成 Sa-Token 时需要的所有 Bean -->
<bean id="saTokenBeanInjection" class="com.pj.satoken.SaTokenBeanInjection">
<constructor-arg ref="saLog"/>
<constructor-arg ref="saTokenConfig"/>
<constructor-arg ref="redisConnectionFactory"/>
<!-- 项目路由前缀,至关重要的一个属性,想要使用路由拦截鉴权必须把这个属性配置对 -->
<constructor-arg value="/sa_token_demo_ssm_war"/>
</bean>
<!--Sa-Token 日志输出对象 -->
<bean id="saLog" class="cn.dev33.satoken.log.SaLogForConsole" />
<!--Sa-Token 配置-->
<bean id="saTokenConfig" class="cn.dev33.satoken.config.SaTokenConfig">
<!-- token 名称(同时也是 cookie 名称) -->
<property name="tokenName" value="satoken" />
<!-- token 有效期(单位:秒) 默认30天-1 代表永久有效 -->
<property name="timeout" value="2592000" />
<!-- token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 -->
<property name="activeTimeout" value="-1" />
<!-- 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) -->
<property name="isConcurrent" value="false" />
<!-- 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token -->
<property name="isShare" value="true" />
<!-- token 风格默认可取值uuid、simple-uuid、random-32、random-64、random-128、tik-->
<property name="tokenStyle" value="uuid" />
<!-- 是否输出操作日志 -->
<property name="isLog" value="true"/>
</bean>
<!-- 导入了 spring-redis.xml 才能使用里面的配置对象 -->
<import resource="spring-redis.xml" />
</beans>

View File

@ -0,0 +1,10 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Admin.jsp</title>
</head>
<body>
<h2> Admin.jsp </h2>
<p>具有 admin 角色才可以访问</p>
</body>
</html>

View File

@ -0,0 +1,10 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Home.jsp</title>
</head>
<body>
<h2> Home.jsp </h2>
<p>所有游客可访问</p>
</body>
</html>

View File

@ -0,0 +1,10 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>User.jsp</title>
</head>
<body>
<h2> User.jsp </h2>
<p>登录后才可以访问</p>
</body>
</html>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>yixiao2</display-name>
<!-- Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<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-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
<!-- 全局错误页 -->
<error-page>
<error-code>404</error-code>
<location>/error</location>
</error-page>
<!--<error-page>
<error-code>500</error-code>
<location>/jsp/error/500.jsp</location>
</error-page>-->
<!-- 欢迎页 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -0,0 +1,10 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>欢迎页 index.jsp</title>
</head>
<body>
<h2> 欢迎页 index.jsp </h2>
<p>这是个外置位的 jsp 页面,可以不经过 Controller 直接访问到</p>
</body>
</html>