换行符使用\n

Signed-off-by: 杜龙少 <sdvdxl@163.com>
This commit is contained in:
杜龙少
2020-03-19 11:19:07 +08:00
parent 40e7a508c3
commit b1498b3b5f
225 changed files with 26032 additions and 26032 deletions

84
ruoyi/.gitignore vendored
View File

@ -1,43 +1,43 @@
###################################################################### ######################################################################
# Build Tools # Build Tools
.gradle .gradle
/build/ /build/
!gradle/wrapper/gradle-wrapper.jar !gradle/wrapper/gradle-wrapper.jar
target/ target/
!.mvn/wrapper/maven-wrapper.jar !.mvn/wrapper/maven-wrapper.jar
###################################################################### ######################################################################
# IDE # IDE
### STS ### ### STS ###
.apt_generated .apt_generated
.classpath .classpath
.factorypath .factorypath
.project .project
.settings .settings
.springBeans .springBeans
### IntelliJ IDEA ### ### IntelliJ IDEA ###
.idea .idea
*.iws *.iws
*.iml *.iml
*.ipr *.ipr
### NetBeans ### ### NetBeans ###
nbproject/private/ nbproject/private/
build/* build/*
nbbuild/ nbbuild/
dist/ dist/
nbdist/ nbdist/
.nb-gradle/ .nb-gradle/
###################################################################### ######################################################################
# Others # Others
*.log *.log
*.xml.versionsBackup *.xml.versionsBackup
!*/build/*.java !*/build/*.java
!*/build/*.html !*/build/*.html
!*/build/*.xml !*/build/*.xml

View File

@ -1,287 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <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"> 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> <modelVersion>4.0.0</modelVersion>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>2.2.0</version> <version>2.2.0</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依管理系统</description> <description>若依管理系统</description>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version> <version>2.1.1.RELEASE</version>
<relativePath /> <relativePath />
</parent> </parent>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<mybatis.spring.boot.starter.version>1.3.2</mybatis.spring.boot.starter.version> <mybatis.spring.boot.starter.version>1.3.2</mybatis.spring.boot.starter.version>
<pagehelper.spring.boot.starter.version>1.2.5</pagehelper.spring.boot.starter.version> <pagehelper.spring.boot.starter.version>1.2.5</pagehelper.spring.boot.starter.version>
<fastjson.version>1.2.47</fastjson.version> <fastjson.version>1.2.47</fastjson.version>
<druid.version>1.1.14</druid.version> <druid.version>1.1.14</druid.version>
<commons.io.version>2.5</commons.io.version> <commons.io.version>2.5</commons.io.version>
<commons.fileupload.version>1.3.3</commons.fileupload.version> <commons.fileupload.version>1.3.3</commons.fileupload.version>
<bitwalker.version>1.19</bitwalker.version> <bitwalker.version>1.19</bitwalker.version>
<jwt.version>0.9.0</jwt.version> <jwt.version>0.9.0</jwt.version>
<swagger.version>2.9.2</swagger.version> <swagger.version>2.9.2</swagger.version>
<poi.version>3.17</poi.version> <poi.version>3.17</poi.version>
<oshi.version>3.9.1</oshi.version> <oshi.version>3.9.1</oshi.version>
<velocity.version>1.7</velocity.version> <velocity.version>1.7</velocity.version>
</properties> </properties>
<dependencies> <dependencies>
<!-- SpringBoot 核心包 --> <!-- SpringBoot 核心包 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId> <artifactId>spring-boot-starter</artifactId>
</dependency> </dependency>
<!-- SpringBoot 测试 --> <!-- SpringBoot 测试 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- SpringBoot 拦截器 --> <!-- SpringBoot 拦截器 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId> <artifactId>spring-boot-starter-aop</artifactId>
</dependency> </dependency>
<!-- SpringBoot Web容器 --> <!-- SpringBoot Web容器 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- spring-boot-devtools --> <!-- spring-boot-devtools -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId> <artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 --> <optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency> </dependency>
<!-- spring security 安全认证 --> <!-- spring security 安全认证 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<!-- redis 缓存操作 --> <!-- redis 缓存操作 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> </dependency>
<!-- pool 对象池 --> <!-- pool 对象池 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<!-- Mysql驱动包 --> <!-- Mysql驱动包 -->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- SpringBoot集成mybatis框架 --> <!-- SpringBoot集成mybatis框架 -->
<dependency> <dependency>
<groupId>org.mybatis.spring.boot</groupId> <groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId> <artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.starter.version}</version> <version>${mybatis.spring.boot.starter.version}</version>
</dependency> </dependency>
<!-- pagehelper 分页插件 --> <!-- pagehelper 分页插件 -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId> <artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.spring.boot.starter.version}</version> <version>${pagehelper.spring.boot.starter.version}</version>
</dependency> </dependency>
<!--阿里数据库连接池 --> <!--阿里数据库连接池 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version> <version>${druid.version}</version>
</dependency> </dependency>
<!--常用工具类 --> <!--常用工具类 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<!--io常用工具类 --> <!--io常用工具类 -->
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>${commons.io.version}</version> <version>${commons.io.version}</version>
</dependency> </dependency>
<!--文件上传工具类 --> <!--文件上传工具类 -->
<dependency> <dependency>
<groupId>commons-fileupload</groupId> <groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId> <artifactId>commons-fileupload</artifactId>
<version>${commons.fileupload.version}</version> <version>${commons.fileupload.version}</version>
</dependency> </dependency>
<!-- 解析客户端操作系统、浏览器等 --> <!-- 解析客户端操作系统、浏览器等 -->
<dependency> <dependency>
<groupId>eu.bitwalker</groupId> <groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId> <artifactId>UserAgentUtils</artifactId>
<version>${bitwalker.version}</version> <version>${bitwalker.version}</version>
</dependency> </dependency>
<!-- 阿里JSON解析器 --> <!-- 阿里JSON解析器 -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId> <artifactId>fastjson</artifactId>
<version>${fastjson.version}</version> <version>${fastjson.version}</version>
</dependency> </dependency>
<!--Spring框架基本的核心工具--> <!--Spring框架基本的核心工具-->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId> <artifactId>spring-context-support</artifactId>
</dependency> </dependency>
<!--Token生成与解析--> <!--Token生成与解析-->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId> <artifactId>jjwt</artifactId>
<version>${jwt.version}</version> <version>${jwt.version}</version>
</dependency> </dependency>
<!-- swagger2--> <!-- swagger2-->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId> <artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version> <version>${swagger.version}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId> <artifactId>swagger-annotations</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId> <artifactId>swagger-models</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<!--防止进入swagger页面报类型转换错误排除2.9.2中的引用手动增加1.5.21版本--> <!--防止进入swagger页面报类型转换错误排除2.9.2中的引用手动增加1.5.21版本-->
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId> <artifactId>swagger-annotations</artifactId>
<version>1.5.21</version> <version>1.5.21</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId> <artifactId>swagger-models</artifactId>
<version>1.5.21</version> <version>1.5.21</version>
</dependency> </dependency>
<!-- swagger2-UI--> <!-- swagger2-UI-->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId> <artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version> <version>${swagger.version}</version>
</dependency> </dependency>
<!-- 获取系统信息 --> <!-- 获取系统信息 -->
<dependency> <dependency>
<groupId>com.github.oshi</groupId> <groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId> <artifactId>oshi-core</artifactId>
<version>${oshi.version}</version> <version>${oshi.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.java.dev.jna</groupId> <groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId> <artifactId>jna</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.java.dev.jna</groupId> <groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId> <artifactId>jna-platform</artifactId>
</dependency> </dependency>
<!-- excel工具 --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version> <version>${poi.version}</version>
</dependency> </dependency>
<!--velocity代码生成使用模板 --> <!--velocity代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId> <artifactId>velocity</artifactId>
<version>${velocity.version}</version> <version>${velocity.version}</version>
</dependency> </dependency>
<!-- 定时任务 --> <!-- 定时任务 -->
<dependency> <dependency>
<groupId>org.quartz-scheduler</groupId> <groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId> <artifactId>quartz</artifactId>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>com.mchange</groupId> <groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId> <artifactId>c3p0</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>
<finalName>${project.artifactId}</finalName> <finalName>${project.artifactId}</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<configuration> <configuration>
<fork>true</fork> <!-- 如果没有该配置devtools不会生效 --> <fork>true</fork> <!-- 如果没有该配置devtools不会生效 -->
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<repositories> <repositories>
<repository> <repository>
<id>public</id> <id>public</id>
<name>aliyun nexus</name> <name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases> <releases>
<enabled>true</enabled> <enabled>true</enabled>
</releases> </releases>
</repository> </repository>
</repositories> </repositories>
<pluginRepositories> <pluginRepositories>
<pluginRepository> <pluginRepository>
<id>public</id> <id>public</id>
<name>aliyun nexus</name> <name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases> <releases>
<enabled>true</enabled> <enabled>true</enabled>
</releases> </releases>
<snapshots> <snapshots>
<enabled>false</enabled> <enabled>false</enabled>
</snapshots> </snapshots>
</pluginRepository> </pluginRepository>
</pluginRepositories> </pluginRepositories>
</project> </project>

View File

@ -1,86 +1,86 @@
#!/bin/bash #!/bin/bash
AppName=ruoyi.jar AppName=ruoyi.jar
#JVM参数 #JVM参数
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
APP_HOME=`pwd` APP_HOME=`pwd`
LOG_PATH=$APP_HOME/logs/$AppName.log LOG_PATH=$APP_HOME/logs/$AppName.log
if [ "$1" = "" ]; if [ "$1" = "" ];
then then
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m" echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
exit 1 exit 1
fi fi
if [ "$AppName" = "" ]; if [ "$AppName" = "" ];
then then
echo -e "\033[0;31m 未输入应用名 \033[0m" echo -e "\033[0;31m 未输入应用名 \033[0m"
exit 1 exit 1
fi fi
function start() function start()
{ {
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
if [ x"$PID" != x"" ]; then if [ x"$PID" != x"" ]; then
echo "$AppName is running..." echo "$AppName is running..."
else else
nohup java -jar $JVM_OPTS target/$AppName > /dev/null 2>&1 & nohup java -jar $JVM_OPTS target/$AppName > /dev/null 2>&1 &
echo "Start $AppName success..." echo "Start $AppName success..."
fi fi
} }
function stop() function stop()
{ {
echo "Stop $AppName" echo "Stop $AppName"
PID="" PID=""
query(){ query(){
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
} }
query query
if [ x"$PID" != x"" ]; then if [ x"$PID" != x"" ]; then
kill -TERM $PID kill -TERM $PID
echo "$AppName (pid:$PID) exiting..." echo "$AppName (pid:$PID) exiting..."
while [ x"$PID" != x"" ] while [ x"$PID" != x"" ]
do do
sleep 1 sleep 1
query query
done done
echo "$AppName exited." echo "$AppName exited."
else else
echo "$AppName already stopped." echo "$AppName already stopped."
fi fi
} }
function restart() function restart()
{ {
stop stop
sleep 2 sleep 2
start start
} }
function status() function status()
{ {
PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l` PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l`
if [ $PID != 0 ];then if [ $PID != 0 ];then
echo "$AppName is running..." echo "$AppName is running..."
else else
echo "$AppName is not running..." echo "$AppName is not running..."
fi fi
} }
case $1 in case $1 in
start) start)
start;; start;;
stop) stop)
stop;; stop;;
restart) restart)
restart;; restart;;
status) status)
status;; status;;
*) *)
esac esac

File diff suppressed because it is too large Load Diff

View File

@ -1,30 +1,30 @@
package com.ruoyi; package com.ruoyi;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/** /**
* 启动程序 * 启动程序
* *
* @author ruoyi * @author ruoyi
*/ */
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication public class RuoYiApplication
{ {
public static void main(String[] args) public static void main(String[] args)
{ {
System.setProperty("spring.devtools.restart.enabled", "false"); System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(RuoYiApplication.class, args); SpringApplication.run(RuoYiApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" + System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" + " .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" + " | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" + " | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" + " |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" + " | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" + " | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" + " | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" + " | | \\ / \\ / \n" +
" ''-' `'-' `-..-' "); " ''-' `'-' `-..-' ");
} }
} }

View File

@ -1,18 +1,18 @@
package com.ruoyi; package com.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/** /**
* web容器中进行部署 * web容器中进行部署
* *
* @author ruoyi * @author ruoyi
*/ */
public class RuoYiServletInitializer extends SpringBootServletInitializer public class RuoYiServletInitializer extends SpringBootServletInitializer
{ {
@Override @Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{ {
return application.sources(RuoYiApplication.class); return application.sources(RuoYiApplication.class);
} }
} }

View File

@ -1,101 +1,101 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
/** /**
* 通用常量信息 * 通用常量信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Constants public class Constants
{ {
/** /**
* UTF-8 字符集 * UTF-8 字符集
*/ */
public static final String UTF8 = "UTF-8"; public static final String UTF8 = "UTF-8";
/** /**
* 通用成功标识 * 通用成功标识
*/ */
public static final String SUCCESS = "0"; public static final String SUCCESS = "0";
/** /**
* 通用失败标识 * 通用失败标识
*/ */
public static final String FAIL = "1"; public static final String FAIL = "1";
/** /**
* 登录成功 * 登录成功
*/ */
public static final String LOGIN_SUCCESS = "Success"; public static final String LOGIN_SUCCESS = "Success";
/** /**
* 注销 * 注销
*/ */
public static final String LOGOUT = "Logout"; public static final String LOGOUT = "Logout";
/** /**
* 登录失败 * 登录失败
*/ */
public static final String LOGIN_FAIL = "Error"; public static final String LOGIN_FAIL = "Error";
/** /**
* 验证码 redis key * 验证码 redis key
*/ */
public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/** /**
* 登录用户 redis key * 登录用户 redis key
*/ */
public static final String LOGIN_TOKEN_KEY = "login_tokens:"; public static final String LOGIN_TOKEN_KEY = "login_tokens:";
/** /**
* 验证码有效期(分钟) * 验证码有效期(分钟)
*/ */
public static final Integer CAPTCHA_EXPIRATION = 2; public static final Integer CAPTCHA_EXPIRATION = 2;
/** /**
* 令牌 * 令牌
*/ */
public static final String TOKEN = "token"; public static final String TOKEN = "token";
/** /**
* 令牌前缀 * 令牌前缀
*/ */
public static final String TOKEN_PREFIX = "Bearer "; public static final String TOKEN_PREFIX = "Bearer ";
/** /**
* 令牌前缀 * 令牌前缀
*/ */
public static final String LOGIN_USER_KEY = "login_user_key"; public static final String LOGIN_USER_KEY = "login_user_key";
/** /**
* 用户ID * 用户ID
*/ */
public static final String JWT_USERID = "userid"; public static final String JWT_USERID = "userid";
/** /**
* 用户名称 * 用户名称
*/ */
public static final String JWT_USERNAME = Claims.SUBJECT; public static final String JWT_USERNAME = Claims.SUBJECT;
/** /**
* 用户头像 * 用户头像
*/ */
public static final String JWT_AVATAR = "avatar"; public static final String JWT_AVATAR = "avatar";
/** /**
* 创建时间 * 创建时间
*/ */
public static final String JWT_CREATED = "created"; public static final String JWT_CREATED = "created";
/** /**
* 用户权限 * 用户权限
*/ */
public static final String JWT_AUTHORITIES = "authorities"; public static final String JWT_AUTHORITIES = "authorities";
/** /**
* 资源映射路径 前缀 * 资源映射路径 前缀
*/ */
public static final String RESOURCE_PREFIX = "/profile"; public static final String RESOURCE_PREFIX = "/profile";
} }

View File

@ -1,94 +1,94 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 代码生成通用常量 * 代码生成通用常量
* *
* @author ruoyi * @author ruoyi
*/ */
public class GenConstants public class GenConstants
{ {
/** 单表(增删改查) */ /** 单表(增删改查) */
public static final String TPL_CRUD = "crud"; public static final String TPL_CRUD = "crud";
/** 树表(增删改查) */ /** 树表(增删改查) */
public static final String TPL_TREE = "tree"; public static final String TPL_TREE = "tree";
/** 树编码字段 */ /** 树编码字段 */
public static final String TREE_CODE = "treeCode"; public static final String TREE_CODE = "treeCode";
/** 树父编码字段 */ /** 树父编码字段 */
public static final String TREE_PARENT_CODE = "treeParentCode"; public static final String TREE_PARENT_CODE = "treeParentCode";
/** 树名称字段 */ /** 树名称字段 */
public static final String TREE_NAME = "treeName"; public static final String TREE_NAME = "treeName";
/** 数据库字符串类型 */ /** 数据库字符串类型 */
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "narchar", "varchar2", "tinytext", "text", public static final String[] COLUMNTYPE_STR = { "char", "varchar", "narchar", "varchar2", "tinytext", "text",
"mediumtext", "longtext" }; "mediumtext", "longtext" };
/** 数据库时间类型 */ /** 数据库时间类型 */
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
/** 数据库数字类型 */ /** 数据库数字类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
"bigint", "float", "float", "double", "decimal" }; "bigint", "float", "float", "double", "decimal" };
/** 页面不需要编辑字段 */ /** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
/** 页面不需要显示的列表字段 */ /** 页面不需要显示的列表字段 */
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time" }; "update_time" };
/** 页面不需要查询字段 */ /** 页面不需要查询字段 */
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
"update_time", "remark" }; "update_time", "remark" };
/** Entity基类字段 */ /** Entity基类字段 */
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
/** Tree基类字段 */ /** Tree基类字段 */
public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" }; public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
/** 文本框 */ /** 文本框 */
public static final String HTML_INPUT = "input"; public static final String HTML_INPUT = "input";
/** 文本域 */ /** 文本域 */
public static final String HTML_TEXTAREA = "textarea"; public static final String HTML_TEXTAREA = "textarea";
/** 下拉框 */ /** 下拉框 */
public static final String HTML_SELECT = "select"; public static final String HTML_SELECT = "select";
/** 单选框 */ /** 单选框 */
public static final String HTML_RADIO = "radio"; public static final String HTML_RADIO = "radio";
/** 复选框 */ /** 复选框 */
public static final String HTML_CHECKBOX = "checkbox"; public static final String HTML_CHECKBOX = "checkbox";
/** 日期控件 */ /** 日期控件 */
public static final String HTML_DATETIME = "datetime"; public static final String HTML_DATETIME = "datetime";
/** 字符串类型 */ /** 字符串类型 */
public static final String TYPE_STRING = "String"; public static final String TYPE_STRING = "String";
/** 整型 */ /** 整型 */
public static final String TYPE_INTEGER = "Integer"; public static final String TYPE_INTEGER = "Integer";
/** 长整型 */ /** 长整型 */
public static final String TYPE_LONG = "Long"; public static final String TYPE_LONG = "Long";
/** 浮点型 */ /** 浮点型 */
public static final String TYPE_DOUBLE = "Double"; public static final String TYPE_DOUBLE = "Double";
/** 高精度计算类型 */ /** 高精度计算类型 */
public static final String TYPE_BIGDECIMAL = "BigDecimal"; public static final String TYPE_BIGDECIMAL = "BigDecimal";
/** 时间类型 */ /** 时间类型 */
public static final String TYPE_DATE = "Date"; public static final String TYPE_DATE = "Date";
/** 模糊查询 */ /** 模糊查询 */
public static final String QUERY_LIKE = "LIKE"; public static final String QUERY_LIKE = "LIKE";
/** 需要 */ /** 需要 */
public static final String REQUIRE = "1"; public static final String REQUIRE = "1";
} }

View File

@ -1,89 +1,89 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 返回状态码 * 返回状态码
* *
* @author ruoyi * @author ruoyi
*/ */
public interface HttpStatus public interface HttpStatus
{ {
/** /**
* 操作成功 * 操作成功
*/ */
public static final int SUCCESS = 200; public static final int SUCCESS = 200;
/** /**
* 对象创建成功 * 对象创建成功
*/ */
public static final int CREATED = 201; public static final int CREATED = 201;
/** /**
* 请求已经被接受 * 请求已经被接受
*/ */
public static final int ACCEPTED = 202; public static final int ACCEPTED = 202;
/** /**
* 操作已经执行成功,但是没有返回数据 * 操作已经执行成功,但是没有返回数据
*/ */
public static final int NO_CONTENT = 204; public static final int NO_CONTENT = 204;
/** /**
* 资源已被移除 * 资源已被移除
*/ */
public static final int MOVED_PERM = 301; public static final int MOVED_PERM = 301;
/** /**
* 重定向 * 重定向
*/ */
public static final int SEE_OTHER = 303; public static final int SEE_OTHER = 303;
/** /**
* 资源没有被修改 * 资源没有被修改
*/ */
public static final int NOT_MODIFIED = 304; public static final int NOT_MODIFIED = 304;
/** /**
* 参数列表错误(缺少,格式不匹配) * 参数列表错误(缺少,格式不匹配)
*/ */
public static final int BAD_REQUEST = 400; public static final int BAD_REQUEST = 400;
/** /**
* 未授权 * 未授权
*/ */
public static final int UNAUTHORIZED = 401; public static final int UNAUTHORIZED = 401;
/** /**
* 访问受限,授权过期 * 访问受限,授权过期
*/ */
public static final int FORBIDDEN = 403; public static final int FORBIDDEN = 403;
/** /**
* 资源,服务未找到 * 资源,服务未找到
*/ */
public static final int NOT_FOUND = 404; public static final int NOT_FOUND = 404;
/** /**
* 不允许的http方法 * 不允许的http方法
*/ */
public static final int BAD_METHOD = 405; public static final int BAD_METHOD = 405;
/** /**
* 资源冲突,或者资源被锁 * 资源冲突,或者资源被锁
*/ */
public static final int CONFLICT = 409; public static final int CONFLICT = 409;
/** /**
* 不支持的数据,媒体类型 * 不支持的数据,媒体类型
*/ */
public static final int UNSUPPORTED_TYPE = 415; public static final int UNSUPPORTED_TYPE = 415;
/** /**
* 系统内部错误 * 系统内部错误
*/ */
public static final int ERROR = 500; public static final int ERROR = 500;
/** /**
* 接口未实现 * 接口未实现
*/ */
public static final int NOT_IMPLEMENTED = 501; public static final int NOT_IMPLEMENTED = 501;
} }

View File

@ -1,39 +1,39 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 用户常量信息 * 用户常量信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class UserConstants public class UserConstants
{ {
/** /**
* 平台内系统用户的唯一标志 * 平台内系统用户的唯一标志
*/ */
public static final String SYS_USER = "SYS_USER"; public static final String SYS_USER = "SYS_USER";
/** 正常状态 */ /** 正常状态 */
public static final String NORMAL = "0"; public static final String NORMAL = "0";
/** 异常状态 */ /** 异常状态 */
public static final String EXCEPTION = "1"; public static final String EXCEPTION = "1";
/** 用户封禁状态 */ /** 用户封禁状态 */
public static final String USER_BLOCKED = "1"; public static final String USER_BLOCKED = "1";
/** 角色封禁状态 */ /** 角色封禁状态 */
public static final String ROLE_BLOCKED = "1"; public static final String ROLE_BLOCKED = "1";
/** 部门正常状态 */ /** 部门正常状态 */
public static final String DEPT_NORMAL = "0"; public static final String DEPT_NORMAL = "0";
/** 字典正常状态 */ /** 字典正常状态 */
public static final String DICT_NORMAL = "0"; public static final String DICT_NORMAL = "0";
/** 是否为系统默认(是) */ /** 是否为系统默认(是) */
public static final String YES = "Y"; public static final String YES = "Y";
/** 校验返回结果码 */ /** 校验返回结果码 */
public final static String UNIQUE = "0"; public final static String UNIQUE = "0";
public final static String NOT_UNIQUE = "1"; public final static String NOT_UNIQUE = "1";
} }

View File

@ -1,481 +1,481 @@
package com.ruoyi.common.core.lang; package com.ruoyi.common.core.lang;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import com.ruoyi.common.exception.UtilException; import com.ruoyi.common.exception.UtilException;
/** /**
* 提供通用唯一识别码universally unique identifierUUID实现 * 提供通用唯一识别码universally unique identifierUUID实现
* *
* @author ruoyi * @author ruoyi
*/ */
public final class UUID implements java.io.Serializable, Comparable<UUID> public final class UUID implements java.io.Serializable, Comparable<UUID>
{ {
private static final long serialVersionUID = -1185015143654744140L; private static final long serialVersionUID = -1185015143654744140L;
/** /**
* SecureRandom 的单例 * SecureRandom 的单例
* *
*/ */
private static class Holder private static class Holder
{ {
static final SecureRandom numberGenerator = getSecureRandom(); static final SecureRandom numberGenerator = getSecureRandom();
} }
/** 此UUID的最高64有效位 */ /** 此UUID的最高64有效位 */
private final long mostSigBits; private final long mostSigBits;
/** 此UUID的最低64有效位 */ /** 此UUID的最低64有效位 */
private final long leastSigBits; private final long leastSigBits;
/** /**
* 私有构造 * 私有构造
* *
* @param data 数据 * @param data 数据
*/ */
private UUID(byte[] data) private UUID(byte[] data)
{ {
long msb = 0; long msb = 0;
long lsb = 0; long lsb = 0;
assert data.length == 16 : "data must be 16 bytes in length"; assert data.length == 16 : "data must be 16 bytes in length";
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
msb = (msb << 8) | (data[i] & 0xff); msb = (msb << 8) | (data[i] & 0xff);
} }
for (int i = 8; i < 16; i++) for (int i = 8; i < 16; i++)
{ {
lsb = (lsb << 8) | (data[i] & 0xff); lsb = (lsb << 8) | (data[i] & 0xff);
} }
this.mostSigBits = msb; this.mostSigBits = msb;
this.leastSigBits = lsb; this.leastSigBits = lsb;
} }
/** /**
* 使用指定的数据构造新的 UUID。 * 使用指定的数据构造新的 UUID。
* *
* @param mostSigBits 用于 {@code UUID} 的最高有效 64 位 * @param mostSigBits 用于 {@code UUID} 的最高有效 64 位
* @param leastSigBits 用于 {@code UUID} 的最低有效 64 位 * @param leastSigBits 用于 {@code UUID} 的最低有效 64 位
*/ */
public UUID(long mostSigBits, long leastSigBits) public UUID(long mostSigBits, long leastSigBits)
{ {
this.mostSigBits = mostSigBits; this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits; this.leastSigBits = leastSigBits;
} }
/** /**
* 获取类型 4伪随机生成的UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。 * 获取类型 4伪随机生成的UUID 的静态工厂。 使用加密的本地线程伪随机数生成器生成该 UUID。
* *
* @return 随机生成的 {@code UUID} * @return 随机生成的 {@code UUID}
*/ */
public static UUID fastUUID() public static UUID fastUUID()
{ {
return randomUUID(false); return randomUUID(false);
} }
/** /**
* 获取类型 4伪随机生成的UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 * 获取类型 4伪随机生成的UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
* *
* @return 随机生成的 {@code UUID} * @return 随机生成的 {@code UUID}
*/ */
public static UUID randomUUID() public static UUID randomUUID()
{ {
return randomUUID(true); return randomUUID(true);
} }
/** /**
* 获取类型 4伪随机生成的UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。 * 获取类型 4伪随机生成的UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
* *
* @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能 * @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能
* @return 随机生成的 {@code UUID} * @return 随机生成的 {@code UUID}
*/ */
public static UUID randomUUID(boolean isSecure) public static UUID randomUUID(boolean isSecure)
{ {
final Random ng = isSecure ? Holder.numberGenerator : getRandom(); final Random ng = isSecure ? Holder.numberGenerator : getRandom();
byte[] randomBytes = new byte[16]; byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes); ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */ randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */ randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */ randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */ randomBytes[8] |= 0x80; /* set to IETF variant */
return new UUID(randomBytes); return new UUID(randomBytes);
} }
/** /**
* 根据指定的字节数组获取类型 3基于名称的UUID 的静态工厂。 * 根据指定的字节数组获取类型 3基于名称的UUID 的静态工厂。
* *
* @param name 用于构造 UUID 的字节数组。 * @param name 用于构造 UUID 的字节数组。
* *
* @return 根据指定数组生成的 {@code UUID} * @return 根据指定数组生成的 {@code UUID}
*/ */
public static UUID nameUUIDFromBytes(byte[] name) public static UUID nameUUIDFromBytes(byte[] name)
{ {
MessageDigest md; MessageDigest md;
try try
{ {
md = MessageDigest.getInstance("MD5"); md = MessageDigest.getInstance("MD5");
} }
catch (NoSuchAlgorithmException nsae) catch (NoSuchAlgorithmException nsae)
{ {
throw new InternalError("MD5 not supported"); throw new InternalError("MD5 not supported");
} }
byte[] md5Bytes = md.digest(name); byte[] md5Bytes = md.digest(name);
md5Bytes[6] &= 0x0f; /* clear version */ md5Bytes[6] &= 0x0f; /* clear version */
md5Bytes[6] |= 0x30; /* set to version 3 */ md5Bytes[6] |= 0x30; /* set to version 3 */
md5Bytes[8] &= 0x3f; /* clear variant */ md5Bytes[8] &= 0x3f; /* clear variant */
md5Bytes[8] |= 0x80; /* set to IETF variant */ md5Bytes[8] |= 0x80; /* set to IETF variant */
return new UUID(md5Bytes); return new UUID(md5Bytes);
} }
/** /**
* 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。 * 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。
* *
* @param name 指定 {@code UUID} 字符串 * @param name 指定 {@code UUID} 字符串
* @return 具有指定值的 {@code UUID} * @return 具有指定值的 {@code UUID}
* @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常 * @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常
* *
*/ */
public static UUID fromString(String name) public static UUID fromString(String name)
{ {
String[] components = name.split("-"); String[] components = name.split("-");
if (components.length != 5) if (components.length != 5)
{ {
throw new IllegalArgumentException("Invalid UUID string: " + name); throw new IllegalArgumentException("Invalid UUID string: " + name);
} }
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
components[i] = "0x" + components[i]; components[i] = "0x" + components[i];
} }
long mostSigBits = Long.decode(components[0]).longValue(); long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits <<= 16; mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]).longValue(); mostSigBits |= Long.decode(components[1]).longValue();
mostSigBits <<= 16; mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]).longValue(); mostSigBits |= Long.decode(components[2]).longValue();
long leastSigBits = Long.decode(components[3]).longValue(); long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits <<= 48; leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]).longValue(); leastSigBits |= Long.decode(components[4]).longValue();
return new UUID(mostSigBits, leastSigBits); return new UUID(mostSigBits, leastSigBits);
} }
/** /**
* 返回此 UUID 的 128 位值中的最低有效 64 位。 * 返回此 UUID 的 128 位值中的最低有效 64 位。
* *
* @return 此 UUID 的 128 位值中的最低有效 64 位。 * @return 此 UUID 的 128 位值中的最低有效 64 位。
*/ */
public long getLeastSignificantBits() public long getLeastSignificantBits()
{ {
return leastSigBits; return leastSigBits;
} }
/** /**
* 返回此 UUID 的 128 位值中的最高有效 64 位。 * 返回此 UUID 的 128 位值中的最高有效 64 位。
* *
* @return 此 UUID 的 128 位值中最高有效 64 位。 * @return 此 UUID 的 128 位值中最高有效 64 位。
*/ */
public long getMostSignificantBits() public long getMostSignificantBits()
{ {
return mostSigBits; return mostSigBits;
} }
/** /**
* 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。 * 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。
* <p> * <p>
* 版本号具有以下含意: * 版本号具有以下含意:
* <ul> * <ul>
* <li>1 基于时间的 UUID * <li>1 基于时间的 UUID
* <li>2 DCE 安全 UUID * <li>2 DCE 安全 UUID
* <li>3 基于名称的 UUID * <li>3 基于名称的 UUID
* <li>4 随机生成的 UUID * <li>4 随机生成的 UUID
* </ul> * </ul>
* *
* @return 此 {@code UUID} 的版本号 * @return 此 {@code UUID} 的版本号
*/ */
public int version() public int version()
{ {
// Version is bits masked by 0x000000000000F000 in MS long // Version is bits masked by 0x000000000000F000 in MS long
return (int) ((mostSigBits >> 12) & 0x0f); return (int) ((mostSigBits >> 12) & 0x0f);
} }
/** /**
* 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。 * 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。
* <p> * <p>
* 变体号具有以下含意: * 变体号具有以下含意:
* <ul> * <ul>
* <li>0 为 NCS 向后兼容保留 * <li>0 为 NCS 向后兼容保留
* <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>(Leach-Salz), 用于此类 * <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF&nbsp;RFC&nbsp;4122</a>(Leach-Salz), 用于此类
* <li>6 保留,微软向后兼容 * <li>6 保留,微软向后兼容
* <li>7 保留供以后定义使用 * <li>7 保留供以后定义使用
* </ul> * </ul>
* *
* @return 此 {@code UUID} 相关联的变体号 * @return 此 {@code UUID} 相关联的变体号
*/ */
public int variant() public int variant()
{ {
// This field is composed of a varying number of bits. // This field is composed of a varying number of bits.
// 0 - - Reserved for NCS backward compatibility // 0 - - Reserved for NCS backward compatibility
// 1 0 - The IETF aka Leach-Salz variant (used by this class) // 1 0 - The IETF aka Leach-Salz variant (used by this class)
// 1 1 0 Reserved, Microsoft backward compatibility // 1 1 0 Reserved, Microsoft backward compatibility
// 1 1 1 Reserved for future definition. // 1 1 1 Reserved for future definition.
return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63)); return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
} }
/** /**
* 与此 UUID 相关联的时间戳值。 * 与此 UUID 相关联的时间戳值。
* *
* <p> * <p>
* 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。<br> * 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。<br>
* 所得到的时间戳以 100 毫微秒为单位,从 UTC通用协调时间 1582 年 10 月 15 日零时开始。 * 所得到的时间戳以 100 毫微秒为单位,从 UTC通用协调时间 1582 年 10 月 15 日零时开始。
* *
* <p> * <p>
* 时间戳值仅在在基于时间的 UUID其 version 类型为 1中才有意义。<br> * 时间戳值仅在在基于时间的 UUID其 version 类型为 1中才有意义。<br>
* 如果此 {@code UUID} 不是基于时间的 UUID则此方法抛出 UnsupportedOperationException。 * 如果此 {@code UUID} 不是基于时间的 UUID则此方法抛出 UnsupportedOperationException。
* *
* @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。 * @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。
*/ */
public long timestamp() throws UnsupportedOperationException public long timestamp() throws UnsupportedOperationException
{ {
checkTimeBase(); checkTimeBase();
return (mostSigBits & 0x0FFFL) << 48// return (mostSigBits & 0x0FFFL) << 48//
| ((mostSigBits >> 16) & 0x0FFFFL) << 32// | ((mostSigBits >> 16) & 0x0FFFFL) << 32//
| mostSigBits >>> 32; | mostSigBits >>> 32;
} }
/** /**
* 与此 UUID 相关联的时钟序列值。 * 与此 UUID 相关联的时钟序列值。
* *
* <p> * <p>
* 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。 * 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。
* <p> * <p>
* {@code clockSequence} 值仅在基于时间的 UUID其 version 类型为 1中才有意义。 如果此 UUID 不是基于时间的 UUID则此方法抛出 * {@code clockSequence} 值仅在基于时间的 UUID其 version 类型为 1中才有意义。 如果此 UUID 不是基于时间的 UUID则此方法抛出
* UnsupportedOperationException。 * UnsupportedOperationException。
* *
* @return 此 {@code UUID} 的时钟序列 * @return 此 {@code UUID} 的时钟序列
* *
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
*/ */
public int clockSequence() throws UnsupportedOperationException public int clockSequence() throws UnsupportedOperationException
{ {
checkTimeBase(); checkTimeBase();
return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48); return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
} }
/** /**
* 与此 UUID 相关的节点值。 * 与此 UUID 相关的节点值。
* *
* <p> * <p>
* 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。 * 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。
* <p> * <p>
* 节点值仅在基于时间的 UUID其 version 类型为 1中才有意义。<br> * 节点值仅在基于时间的 UUID其 version 类型为 1中才有意义。<br>
* 如果此 UUID 不是基于时间的 UUID则此方法抛出 UnsupportedOperationException。 * 如果此 UUID 不是基于时间的 UUID则此方法抛出 UnsupportedOperationException。
* *
* @return 此 {@code UUID} 的节点值 * @return 此 {@code UUID} 的节点值
* *
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1 * @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
*/ */
public long node() throws UnsupportedOperationException public long node() throws UnsupportedOperationException
{ {
checkTimeBase(); checkTimeBase();
return leastSigBits & 0x0000FFFFFFFFFFFFL; return leastSigBits & 0x0000FFFFFFFFFFFFL;
} }
/** /**
* 返回此{@code UUID} 的字符串表现形式。 * 返回此{@code UUID} 的字符串表现形式。
* *
* <p> * <p>
* UUID 的字符串表示形式由此 BNF 描述: * UUID 的字符串表示形式由此 BNF 描述:
* *
* <pre> * <pre>
* {@code * {@code
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node> * UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
* time_low = 4*<hexOctet> * time_low = 4*<hexOctet>
* time_mid = 2*<hexOctet> * time_mid = 2*<hexOctet>
* time_high_and_version = 2*<hexOctet> * time_high_and_version = 2*<hexOctet>
* variant_and_sequence = 2*<hexOctet> * variant_and_sequence = 2*<hexOctet>
* node = 6*<hexOctet> * node = 6*<hexOctet>
* hexOctet = <hexDigit><hexDigit> * hexOctet = <hexDigit><hexDigit>
* hexDigit = [0-9a-fA-F] * hexDigit = [0-9a-fA-F]
* } * }
* </pre> * </pre>
* *
* </blockquote> * </blockquote>
* *
* @return 此{@code UUID} 的字符串表现形式 * @return 此{@code UUID} 的字符串表现形式
* @see #toString(boolean) * @see #toString(boolean)
*/ */
@Override @Override
public String toString() public String toString()
{ {
return toString(false); return toString(false);
} }
/** /**
* 返回此{@code UUID} 的字符串表现形式。 * 返回此{@code UUID} 的字符串表现形式。
* *
* <p> * <p>
* UUID 的字符串表示形式由此 BNF 描述: * UUID 的字符串表示形式由此 BNF 描述:
* *
* <pre> * <pre>
* {@code * {@code
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node> * UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
* time_low = 4*<hexOctet> * time_low = 4*<hexOctet>
* time_mid = 2*<hexOctet> * time_mid = 2*<hexOctet>
* time_high_and_version = 2*<hexOctet> * time_high_and_version = 2*<hexOctet>
* variant_and_sequence = 2*<hexOctet> * variant_and_sequence = 2*<hexOctet>
* node = 6*<hexOctet> * node = 6*<hexOctet>
* hexOctet = <hexDigit><hexDigit> * hexOctet = <hexDigit><hexDigit>
* hexDigit = [0-9a-fA-F] * hexDigit = [0-9a-fA-F]
* } * }
* </pre> * </pre>
* *
* </blockquote> * </blockquote>
* *
* @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串 * @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串
* @return 此{@code UUID} 的字符串表现形式 * @return 此{@code UUID} 的字符串表现形式
*/ */
public String toString(boolean isSimple) public String toString(boolean isSimple)
{ {
final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36); final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
// time_low // time_low
builder.append(digits(mostSigBits >> 32, 8)); builder.append(digits(mostSigBits >> 32, 8));
if (false == isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// time_mid // time_mid
builder.append(digits(mostSigBits >> 16, 4)); builder.append(digits(mostSigBits >> 16, 4));
if (false == isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// time_high_and_version // time_high_and_version
builder.append(digits(mostSigBits, 4)); builder.append(digits(mostSigBits, 4));
if (false == isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// variant_and_sequence // variant_and_sequence
builder.append(digits(leastSigBits >> 48, 4)); builder.append(digits(leastSigBits >> 48, 4));
if (false == isSimple) if (false == isSimple)
{ {
builder.append('-'); builder.append('-');
} }
// node // node
builder.append(digits(leastSigBits, 12)); builder.append(digits(leastSigBits, 12));
return builder.toString(); return builder.toString();
} }
/** /**
* 返回此 UUID 的哈希码。 * 返回此 UUID 的哈希码。
* *
* @return UUID 的哈希码值。 * @return UUID 的哈希码值。
*/ */
public int hashCode() public int hashCode()
{ {
long hilo = mostSigBits ^ leastSigBits; long hilo = mostSigBits ^ leastSigBits;
return ((int) (hilo >> 32)) ^ (int) hilo; return ((int) (hilo >> 32)) ^ (int) hilo;
} }
/** /**
* 将此对象与指定对象比较。 * 将此对象与指定对象比较。
* <p> * <p>
* 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值每一位均相同结果才为 {@code true}。 * 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值每一位均相同结果才为 {@code true}。
* *
* @param obj 要与之比较的对象 * @param obj 要与之比较的对象
* *
* @return 如果对象相同,则返回 {@code true};否则返回 {@code false} * @return 如果对象相同,则返回 {@code true};否则返回 {@code false}
*/ */
public boolean equals(Object obj) public boolean equals(Object obj)
{ {
if ((null == obj) || (obj.getClass() != UUID.class)) if ((null == obj) || (obj.getClass() != UUID.class))
{ {
return false; return false;
} }
UUID id = (UUID) obj; UUID id = (UUID) obj;
return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits); return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
} }
// Comparison Operations // Comparison Operations
/** /**
* 将此 UUID 与指定的 UUID 比较。 * 将此 UUID 与指定的 UUID 比较。
* *
* <p> * <p>
* 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。 * 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。
* *
* @param val 与此 UUID 比较的 UUID * @param val 与此 UUID 比较的 UUID
* *
* @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。 * @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。
* *
*/ */
public int compareTo(UUID val) public int compareTo(UUID val)
{ {
// The ordering is intentionally set up so that the UUIDs // The ordering is intentionally set up so that the UUIDs
// can simply be numerically compared as two numbers // can simply be numerically compared as two numbers
return (this.mostSigBits < val.mostSigBits ? -1 : // return (this.mostSigBits < val.mostSigBits ? -1 : //
(this.mostSigBits > val.mostSigBits ? 1 : // (this.mostSigBits > val.mostSigBits ? 1 : //
(this.leastSigBits < val.leastSigBits ? -1 : // (this.leastSigBits < val.leastSigBits ? -1 : //
(this.leastSigBits > val.leastSigBits ? 1 : // (this.leastSigBits > val.leastSigBits ? 1 : //
0)))); 0))));
} }
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
// Private method start // Private method start
/** /**
* 返回指定数字对应的hex值 * 返回指定数字对应的hex值
* *
* @param val 值 * @param val 值
* @param digits 位 * @param digits 位
* @return 值 * @return 值
*/ */
private static String digits(long val, int digits) private static String digits(long val, int digits)
{ {
long hi = 1L << (digits * 4); long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1); return Long.toHexString(hi | (val & (hi - 1))).substring(1);
} }
/** /**
* 检查是否为time-based版本UUID * 检查是否为time-based版本UUID
*/ */
private void checkTimeBase() private void checkTimeBase()
{ {
if (version() != 1) if (version() != 1)
{ {
throw new UnsupportedOperationException("Not a time-based UUID"); throw new UnsupportedOperationException("Not a time-based UUID");
} }
} }
/** /**
* 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG) * 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
* *
* @return {@link SecureRandom} * @return {@link SecureRandom}
*/ */
public static SecureRandom getSecureRandom() public static SecureRandom getSecureRandom()
{ {
try try
{ {
return SecureRandom.getInstance("SHA1PRNG"); return SecureRandom.getInstance("SHA1PRNG");
} }
catch (NoSuchAlgorithmException e) catch (NoSuchAlgorithmException e)
{ {
throw new UtilException(e); throw new UtilException(e);
} }
} }
/** /**
* 获取随机数生成器对象<br> * 获取随机数生成器对象<br>
* ThreadLocalRandom是JDK 7之后提供并发产生随机数能够解决多个线程发生的竞争争夺。 * ThreadLocalRandom是JDK 7之后提供并发产生随机数能够解决多个线程发生的竞争争夺。
* *
* @return {@link ThreadLocalRandom} * @return {@link ThreadLocalRandom}
*/ */
public static ThreadLocalRandom getRandom() public static ThreadLocalRandom getRandom()
{ {
return ThreadLocalRandom.current(); return ThreadLocalRandom.current();
} }
} }

View File

@ -1,86 +1,86 @@
package com.ruoyi.common.core.text; package com.ruoyi.common.core.text;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 字符集工具类 * 字符集工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class CharsetKit public class CharsetKit
{ {
/** ISO-8859-1 */ /** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1"; public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */ /** UTF-8 */
public static final String UTF_8 = "UTF-8"; public static final String UTF_8 = "UTF-8";
/** GBK */ /** GBK */
public static final String GBK = "GBK"; public static final String GBK = "GBK";
/** ISO-8859-1 */ /** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */ /** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */ /** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK); public static final Charset CHARSET_GBK = Charset.forName(GBK);
/** /**
* 转换为Charset对象 * 转换为Charset对象
* *
* @param charset 字符集,为空则返回默认字符集 * @param charset 字符集,为空则返回默认字符集
* @return Charset * @return Charset
*/ */
public static Charset charset(String charset) public static Charset charset(String charset)
{ {
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
} }
/** /**
* 转换字符串的字符集编码 * 转换字符串的字符集编码
* *
* @param source 字符串 * @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1 * @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8 * @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集 * @return 转换后的字符集
*/ */
public static String convert(String source, String srcCharset, String destCharset) public static String convert(String source, String srcCharset, String destCharset)
{ {
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
} }
/** /**
* 转换字符串的字符集编码 * 转换字符串的字符集编码
* *
* @param source 字符串 * @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1 * @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8 * @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集 * @return 转换后的字符集
*/ */
public static String convert(String source, Charset srcCharset, Charset destCharset) public static String convert(String source, Charset srcCharset, Charset destCharset)
{ {
if (null == srcCharset) if (null == srcCharset)
{ {
srcCharset = StandardCharsets.ISO_8859_1; srcCharset = StandardCharsets.ISO_8859_1;
} }
if (null == destCharset) if (null == destCharset)
{ {
srcCharset = StandardCharsets.UTF_8; srcCharset = StandardCharsets.UTF_8;
} }
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{ {
return source; return source;
} }
return new String(source.getBytes(srcCharset), destCharset); return new String(source.getBytes(srcCharset), destCharset);
} }
/** /**
* @return 系统字符集编码 * @return 系统字符集编码
*/ */
public static String systemCharset() public static String systemCharset()
{ {
return Charset.defaultCharset().name(); return Charset.defaultCharset().name();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,92 +1,92 @@
package com.ruoyi.common.core.text; package com.ruoyi.common.core.text;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 字符串格式化 * 字符串格式化
* *
* @author ruoyi * @author ruoyi
*/ */
public class StrFormatter public class StrFormatter
{ {
public static final String EMPTY_JSON = "{}"; public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\'; public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{'; public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}'; public static final char C_DELIM_END = '}';
/** /**
* 格式化字符串<br> * 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br> * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br> * 例:<br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br> * 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> * 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> * 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
* *
* @param strPattern 字符串模板 * @param strPattern 字符串模板
* @param argArray 参数列表 * @param argArray 参数列表
* @return 结果 * @return 结果
*/ */
public static String format(final String strPattern, final Object... argArray) public static String format(final String strPattern, final Object... argArray)
{ {
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
{ {
return strPattern; return strPattern;
} }
final int strPatternLength = strPattern.length(); final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能 // 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50); StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0; int handledPosition = 0;
int delimIndex;// 占位符所在位置 int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++) for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{ {
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1) if (delimIndex == -1)
{ {
if (handledPosition == 0) if (handledPosition == 0)
{ {
return strPattern; return strPattern;
} }
else else
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength); sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString(); return sbuf.toString();
} }
} }
else else
{ {
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{ {
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{ {
// 转义符之前还有一个转义符,占位符依旧有效 // 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex])); sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2; handledPosition = delimIndex + 2;
} }
else else
{ {
// 占位符被转义 // 占位符被转义
argIndex--; argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START); sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1; handledPosition = delimIndex + 1;
} }
} }
else else
{ {
// 正常占位符 // 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex); sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex])); sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2; handledPosition = delimIndex + 2;
} }
} }
} }
// 加入最后一个占位符后所有的字符 // 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length()); sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString(); return sbuf.toString();
} }
} }

View File

@ -1,36 +1,36 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
* 请求方式 * 请求方式
* *
* @author ruoyi * @author ruoyi
*/ */
public enum HttpMethod public enum HttpMethod
{ {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
private static final Map<String, HttpMethod> mappings = new HashMap<>(16); private static final Map<String, HttpMethod> mappings = new HashMap<>(16);
static static
{ {
for (HttpMethod httpMethod : values()) for (HttpMethod httpMethod : values())
{ {
mappings.put(httpMethod.name(), httpMethod); mappings.put(httpMethod.name(), httpMethod);
} }
} }
@Nullable @Nullable
public static HttpMethod resolve(@Nullable String method) public static HttpMethod resolve(@Nullable String method)
{ {
return (method != null ? mappings.get(method) : null); return (method != null ? mappings.get(method) : null);
} }
public boolean matches(String method) public boolean matches(String method)
{ {
return (this == resolve(method)); return (this == resolve(method));
} }
} }

View File

@ -1,30 +1,30 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 用户状态 * 用户状态
* *
* @author ruoyi * @author ruoyi
*/ */
public enum UserStatus public enum UserStatus
{ {
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
private final String code; private final String code;
private final String info; private final String info;
UserStatus(String code, String info) UserStatus(String code, String info)
{ {
this.code = code; this.code = code;
this.info = info; this.info = info;
} }
public String getCode() public String getCode()
{ {
return code; return code;
} }
public String getInfo() public String getInfo()
{ {
return info; return info;
} }
} }

View File

@ -1,97 +1,97 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 基础异常 * 基础异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseException extends RuntimeException public class BaseException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 所属模块 * 所属模块
*/ */
private String module; private String module;
/** /**
* 错误码 * 错误码
*/ */
private String code; private String code;
/** /**
* 错误码对应的参数 * 错误码对应的参数
*/ */
private Object[] args; private Object[] args;
/** /**
* 错误消息 * 错误消息
*/ */
private String defaultMessage; private String defaultMessage;
public BaseException(String module, String code, Object[] args, String defaultMessage) public BaseException(String module, String code, Object[] args, String defaultMessage)
{ {
this.module = module; this.module = module;
this.code = code; this.code = code;
this.args = args; this.args = args;
this.defaultMessage = defaultMessage; this.defaultMessage = defaultMessage;
} }
public BaseException(String module, String code, Object[] args) public BaseException(String module, String code, Object[] args)
{ {
this(module, code, args, null); this(module, code, args, null);
} }
public BaseException(String module, String defaultMessage) public BaseException(String module, String defaultMessage)
{ {
this(module, null, null, defaultMessage); this(module, null, null, defaultMessage);
} }
public BaseException(String code, Object[] args) public BaseException(String code, Object[] args)
{ {
this(null, code, args, null); this(null, code, args, null);
} }
public BaseException(String defaultMessage) public BaseException(String defaultMessage)
{ {
this(null, null, null, defaultMessage); this(null, null, null, defaultMessage);
} }
@Override @Override
public String getMessage() public String getMessage()
{ {
String message = null; String message = null;
if (!StringUtils.isEmpty(code)) if (!StringUtils.isEmpty(code))
{ {
message = MessageUtils.message(code, args); message = MessageUtils.message(code, args);
} }
if (message == null) if (message == null)
{ {
message = defaultMessage; message = defaultMessage;
} }
return message; return message;
} }
public String getModule() public String getModule()
{ {
return module; return module;
} }
public String getCode() public String getCode()
{ {
return code; return code;
} }
public Object[] getArgs() public Object[] getArgs()
{ {
return args; return args;
} }
public String getDefaultMessage() public String getDefaultMessage()
{ {
return defaultMessage; return defaultMessage;
} }
} }

View File

@ -1,43 +1,43 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 自定义异常 * 自定义异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class CustomException extends RuntimeException public class CustomException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Integer code; private Integer code;
private String message; private String message;
public CustomException(String message) public CustomException(String message)
{ {
this.message = message; this.message = message;
} }
public CustomException(String message, Integer code) public CustomException(String message, Integer code)
{ {
this.message = message; this.message = message;
this.code = code; this.code = code;
} }
public CustomException(String message, Throwable e) public CustomException(String message, Throwable e)
{ {
super(message, e); super(message, e);
this.message = message; this.message = message;
} }
@Override @Override
public String getMessage() public String getMessage()
{ {
return message; return message;
} }
public Integer getCode() public Integer getCode()
{ {
return code; return code;
} }
} }

View File

@ -1,15 +1,15 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 演示模式异常 * 演示模式异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class DemoModeException extends RuntimeException public class DemoModeException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public DemoModeException() public DemoModeException()
{ {
} }
} }

View File

@ -1,26 +1,26 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 工具类异常 * 工具类异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class UtilException extends RuntimeException public class UtilException extends RuntimeException
{ {
private static final long serialVersionUID = 8247610319171014183L; private static final long serialVersionUID = 8247610319171014183L;
public UtilException(Throwable e) public UtilException(Throwable e)
{ {
super(e.getMessage(), e); super(e.getMessage(), e);
} }
public UtilException(String message) public UtilException(String message)
{ {
super(message); super(message);
} }
public UtilException(String message, Throwable throwable) public UtilException(String message, Throwable throwable)
{ {
super(message, throwable); super(message, throwable);
} }
} }

View File

@ -1,19 +1,19 @@
package com.ruoyi.common.exception.file; package com.ruoyi.common.exception.file;
import com.ruoyi.common.exception.BaseException; import com.ruoyi.common.exception.BaseException;
/** /**
* 文件信息异常类 * 文件信息异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileException extends BaseException public class FileException extends BaseException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FileException(String code, Object[] args) public FileException(String code, Object[] args)
{ {
super("file", code, args, null); super("file", code, args, null);
} }
} }

View File

@ -1,16 +1,16 @@
package com.ruoyi.common.exception.file; package com.ruoyi.common.exception.file;
/** /**
* 文件名称超长限制异常类 * 文件名称超长限制异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileNameLengthLimitExceededException extends FileException public class FileNameLengthLimitExceededException extends FileException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FileNameLengthLimitExceededException(int defaultFileNameLength) public FileNameLengthLimitExceededException(int defaultFileNameLength)
{ {
super("upload.filename.exceed.length", new Object[] { defaultFileNameLength }); super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
} }
} }

View File

@ -1,16 +1,16 @@
package com.ruoyi.common.exception.file; package com.ruoyi.common.exception.file;
/** /**
* 文件名大小限制异常类 * 文件名大小限制异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileSizeLimitExceededException extends FileException public class FileSizeLimitExceededException extends FileException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FileSizeLimitExceededException(long defaultMaxSize) public FileSizeLimitExceededException(long defaultMaxSize)
{ {
super("upload.exceed.maxSize", new Object[] { defaultMaxSize }); super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
} }
} }

View File

@ -1,71 +1,71 @@
package com.ruoyi.common.exception.file; package com.ruoyi.common.exception.file;
import java.util.Arrays; import java.util.Arrays;
import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.FileUploadException;
/** /**
* 文件上传 误异常类 * 文件上传 误异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class InvalidExtensionException extends FileUploadException public class InvalidExtensionException extends FileUploadException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String[] allowedExtension; private String[] allowedExtension;
private String extension; private String extension;
private String filename; private String filename;
public InvalidExtensionException(String[] allowedExtension, String extension, String filename) public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
{ {
super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]"); super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
this.allowedExtension = allowedExtension; this.allowedExtension = allowedExtension;
this.extension = extension; this.extension = extension;
this.filename = filename; this.filename = filename;
} }
public String[] getAllowedExtension() public String[] getAllowedExtension()
{ {
return allowedExtension; return allowedExtension;
} }
public String getExtension() public String getExtension()
{ {
return extension; return extension;
} }
public String getFilename() public String getFilename()
{ {
return filename; return filename;
} }
public static class InvalidImageExtensionException extends InvalidExtensionException public static class InvalidImageExtensionException extends InvalidExtensionException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename) public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
{ {
super(allowedExtension, extension, filename); super(allowedExtension, extension, filename);
} }
} }
public static class InvalidFlashExtensionException extends InvalidExtensionException public static class InvalidFlashExtensionException extends InvalidExtensionException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename) public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
{ {
super(allowedExtension, extension, filename); super(allowedExtension, extension, filename);
} }
} }
public static class InvalidMediaExtensionException extends InvalidExtensionException public static class InvalidMediaExtensionException extends InvalidExtensionException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename) public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
{ {
super(allowedExtension, extension, filename); super(allowedExtension, extension, filename);
} }
} }
} }

View File

@ -1,16 +1,16 @@
package com.ruoyi.common.exception.user; package com.ruoyi.common.exception.user;
/** /**
* 验证码错误异常类 * 验证码错误异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class CaptchaException extends UserException public class CaptchaException extends UserException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public CaptchaException() public CaptchaException()
{ {
super("user.jcaptcha.error", null); super("user.jcaptcha.error", null);
} }
} }

View File

@ -1,16 +1,16 @@
package com.ruoyi.common.exception.user; package com.ruoyi.common.exception.user;
/** /**
* 验证码失效异常类 * 验证码失效异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class CaptchaExpireException extends UserException public class CaptchaExpireException extends UserException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public CaptchaExpireException() public CaptchaExpireException()
{ {
super("user.jcaptcha.expire", null); super("user.jcaptcha.expire", null);
} }
} }

View File

@ -1,18 +1,18 @@
package com.ruoyi.common.exception.user; package com.ruoyi.common.exception.user;
import com.ruoyi.common.exception.BaseException; import com.ruoyi.common.exception.BaseException;
/** /**
* 用户信息异常类 * 用户信息异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class UserException extends BaseException public class UserException extends BaseException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UserException(String code, Object[] args) public UserException(String code, Object[] args)
{ {
super("user", code, args, null); super("user", code, args, null);
} }
} }

View File

@ -1,16 +1,16 @@
package com.ruoyi.common.exception.user; package com.ruoyi.common.exception.user;
/** /**
* 用户密码不正确或不符合规范异常类 * 用户密码不正确或不符合规范异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class UserPasswordNotMatchException extends UserException public class UserPasswordNotMatchException extends UserException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public UserPasswordNotMatchException() public UserPasswordNotMatchException()
{ {
super("user.password.not.match", null); super("user.password.not.match", null);
} }
} }

View File

@ -1,97 +1,97 @@
package com.ruoyi.common.filter; package com.ruoyi.common.filter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 防止XSS攻击的过滤器 * 防止XSS攻击的过滤器
* *
* @author ruoyi * @author ruoyi
*/ */
public class XssFilter implements Filter public class XssFilter implements Filter
{ {
/** /**
* 排除链接 * 排除链接
*/ */
public List<String> excludes = new ArrayList<>(); public List<String> excludes = new ArrayList<>();
/** /**
* xss过滤开关 * xss过滤开关
*/ */
public boolean enabled = false; public boolean enabled = false;
@Override @Override
public void init(FilterConfig filterConfig) throws ServletException public void init(FilterConfig filterConfig) throws ServletException
{ {
String tempExcludes = filterConfig.getInitParameter("excludes"); String tempExcludes = filterConfig.getInitParameter("excludes");
String tempEnabled = filterConfig.getInitParameter("enabled"); String tempEnabled = filterConfig.getInitParameter("enabled");
if (StringUtils.isNotEmpty(tempExcludes)) if (StringUtils.isNotEmpty(tempExcludes))
{ {
String[] url = tempExcludes.split(","); String[] url = tempExcludes.split(",");
for (int i = 0; url != null && i < url.length; i++) for (int i = 0; url != null && i < url.length; i++)
{ {
excludes.add(url[i]); excludes.add(url[i]);
} }
} }
if (StringUtils.isNotEmpty(tempEnabled)) if (StringUtils.isNotEmpty(tempEnabled))
{ {
enabled = Boolean.valueOf(tempEnabled); enabled = Boolean.valueOf(tempEnabled);
} }
} }
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException throws IOException, ServletException
{ {
HttpServletRequest req = (HttpServletRequest) request; HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response; HttpServletResponse resp = (HttpServletResponse) response;
if (handleExcludeURL(req, resp)) if (handleExcludeURL(req, resp))
{ {
chain.doFilter(request, response); chain.doFilter(request, response);
return; return;
} }
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request);
chain.doFilter(xssRequest, response); chain.doFilter(xssRequest, response);
} }
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response)
{ {
if (!enabled) if (!enabled)
{ {
return true; return true;
} }
if (excludes == null || excludes.isEmpty()) if (excludes == null || excludes.isEmpty())
{ {
return false; return false;
} }
String url = request.getServletPath(); String url = request.getServletPath();
for (String pattern : excludes) for (String pattern : excludes)
{ {
Pattern p = Pattern.compile("^" + pattern); Pattern p = Pattern.compile("^" + pattern);
Matcher m = p.matcher(url); Matcher m = p.matcher(url);
if (m.find()) if (m.find())
{ {
return true; return true;
} }
} }
return false; return false;
} }
@Override @Override
public void destroy() public void destroy()
{ {
} }
} }

View File

@ -1,105 +1,105 @@
package com.ruoyi.common.filter; package com.ruoyi.common.filter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import javax.servlet.ReadListener; import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream; import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.html.EscapeUtil; import com.ruoyi.common.utils.html.EscapeUtil;
/** /**
* XSS过滤处理 * XSS过滤处理
* *
* @author ruoyi * @author ruoyi
*/ */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper
{ {
/** /**
* @param request * @param request
*/ */
public XssHttpServletRequestWrapper(HttpServletRequest request) public XssHttpServletRequestWrapper(HttpServletRequest request)
{ {
super(request); super(request);
} }
@Override @Override
public String[] getParameterValues(String name) public String[] getParameterValues(String name)
{ {
String[] values = super.getParameterValues(name); String[] values = super.getParameterValues(name);
if (values != null) if (values != null)
{ {
int length = values.length; int length = values.length;
String[] escapseValues = new String[length]; String[] escapseValues = new String[length];
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
// 防xss攻击和过滤前后空格 // 防xss攻击和过滤前后空格
escapseValues[i] = EscapeUtil.clean(values[i]).trim(); escapseValues[i] = EscapeUtil.clean(values[i]).trim();
} }
return escapseValues; return escapseValues;
} }
return super.getParameterValues(name); return super.getParameterValues(name);
} }
@Override @Override
public ServletInputStream getInputStream() throws IOException public ServletInputStream getInputStream() throws IOException
{ {
// 非json类型直接返回 // 非json类型直接返回
if (!isJsonRequest()) if (!isJsonRequest())
{ {
return super.getInputStream(); return super.getInputStream();
} }
// 为空,直接返回 // 为空,直接返回
String json = IOUtils.toString(super.getInputStream(), "utf-8"); String json = IOUtils.toString(super.getInputStream(), "utf-8");
if (StringUtils.isEmpty(json)) if (StringUtils.isEmpty(json))
{ {
return super.getInputStream(); return super.getInputStream();
} }
// xss过滤 // xss过滤
json = EscapeUtil.clean(json).trim(); json = EscapeUtil.clean(json).trim();
final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8")); final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8"));
return new ServletInputStream() return new ServletInputStream()
{ {
@Override @Override
public boolean isFinished() public boolean isFinished()
{ {
return true; return true;
} }
@Override @Override
public boolean isReady() public boolean isReady()
{ {
return true; return true;
} }
@Override @Override
public void setReadListener(ReadListener readListener) public void setReadListener(ReadListener readListener)
{ {
} }
@Override @Override
public int read() throws IOException public int read() throws IOException
{ {
return bis.read(); return bis.read();
} }
}; };
} }
/** /**
* 是否是Json请求 * 是否是Json请求
* *
* @param request * @param request
*/ */
public boolean isJsonRequest() public boolean isJsonRequest()
{ {
String header = super.getHeader(HttpHeaders.CONTENT_TYPE); String header = super.getHeader(HttpHeaders.CONTENT_TYPE);
return MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(header) return MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(header)
|| MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(header); || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(header);
} }
} }

View File

@ -1,114 +1,114 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
/** /**
* 精确的浮点数运算 * 精确的浮点数运算
* *
* @author ruoyi * @author ruoyi
*/ */
public class Arith public class Arith
{ {
/** 默认除法运算精度 */ /** 默认除法运算精度 */
private static final int DEF_DIV_SCALE = 10; private static final int DEF_DIV_SCALE = 10;
/** 这个类不能实例化 */ /** 这个类不能实例化 */
private Arith() private Arith()
{ {
} }
/** /**
* 提供精确的加法运算。 * 提供精确的加法运算。
* @param v1 被加数 * @param v1 被加数
* @param v2 加数 * @param v2 加数
* @return 两个参数的和 * @return 两个参数的和
*/ */
public static double add(double v1, double v2) public static double add(double v1, double v2)
{ {
BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2)); BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue(); return b1.add(b2).doubleValue();
} }
/** /**
* 提供精确的减法运算。 * 提供精确的减法运算。
* @param v1 被减数 * @param v1 被减数
* @param v2 减数 * @param v2 减数
* @return 两个参数的差 * @return 两个参数的差
*/ */
public static double sub(double v1, double v2) public static double sub(double v1, double v2)
{ {
BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2)); BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue(); return b1.subtract(b2).doubleValue();
} }
/** /**
* 提供精确的乘法运算。 * 提供精确的乘法运算。
* @param v1 被乘数 * @param v1 被乘数
* @param v2 乘数 * @param v2 乘数
* @return 两个参数的积 * @return 两个参数的积
*/ */
public static double mul(double v1, double v2) public static double mul(double v1, double v2)
{ {
BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2)); BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue(); return b1.multiply(b2).doubleValue();
} }
/** /**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位以后的数字四舍五入。 * 小数点以后10位以后的数字四舍五入。
* @param v1 被除数 * @param v1 被除数
* @param v2 除数 * @param v2 除数
* @return 两个参数的商 * @return 两个参数的商
*/ */
public static double div(double v1, double v2) public static double div(double v1, double v2)
{ {
return div(v1, v2, DEF_DIV_SCALE); return div(v1, v2, DEF_DIV_SCALE);
} }
/** /**
* 提供相对精确的除法运算。当发生除不尽的情况时由scale参数指 * 提供相对精确的除法运算。当发生除不尽的情况时由scale参数指
* 定精度,以后的数字四舍五入。 * 定精度,以后的数字四舍五入。
* @param v1 被除数 * @param v1 被除数
* @param v2 除数 * @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。 * @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商 * @return 两个参数的商
*/ */
public static double div(double v1, double v2, int scale) public static double div(double v1, double v2, int scale)
{ {
if (scale < 0) if (scale < 0)
{ {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The scale must be a positive integer or zero"); "The scale must be a positive integer or zero");
} }
BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2)); BigDecimal b2 = new BigDecimal(Double.toString(v2));
if (b1.compareTo(BigDecimal.ZERO) == 0) if (b1.compareTo(BigDecimal.ZERO) == 0)
{ {
return BigDecimal.ZERO.doubleValue(); return BigDecimal.ZERO.doubleValue();
} }
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue(); return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
} }
/** /**
* 提供精确的小数位四舍五入处理。 * 提供精确的小数位四舍五入处理。
* @param v 需要四舍五入的数字 * @param v 需要四舍五入的数字
* @param scale 小数点后保留几位 * @param scale 小数点后保留几位
* @return 四舍五入后的结果 * @return 四舍五入后的结果
*/ */
public static double round(double v, int scale) public static double round(double v, int scale)
{ {
if (scale < 0) if (scale < 0)
{ {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"The scale must be a positive integer or zero"); "The scale must be a positive integer or zero");
} }
BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1"); BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue(); return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
} }
} }

View File

@ -1,155 +1,155 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateFormatUtils;
/** /**
* 时间工具类 * 时间工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{ {
public static String YYYY = "yyyy"; public static String YYYY = "yyyy";
public static String YYYY_MM = "yyyy-MM"; public static String YYYY_MM = "yyyy-MM";
public static String YYYY_MM_DD = "yyyy-MM-dd"; public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss"; public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss"; public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = { private static String[] parsePatterns = {
"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"}; "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
/** /**
* 获取当前Date型日期 * 获取当前Date型日期
* *
* @return Date() 当前日期 * @return Date() 当前日期
*/ */
public static Date getNowDate() public static Date getNowDate()
{ {
return new Date(); return new Date();
} }
/** /**
* 获取当前日期, 默认格式为yyyy-MM-dd * 获取当前日期, 默认格式为yyyy-MM-dd
* *
* @return String * @return String
*/ */
public static String getDate() public static String getDate()
{ {
return dateTimeNow(YYYY_MM_DD); return dateTimeNow(YYYY_MM_DD);
} }
public static final String getTime() public static final String getTime()
{ {
return dateTimeNow(YYYY_MM_DD_HH_MM_SS); return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
} }
public static final String dateTimeNow() public static final String dateTimeNow()
{ {
return dateTimeNow(YYYYMMDDHHMMSS); return dateTimeNow(YYYYMMDDHHMMSS);
} }
public static final String dateTimeNow(final String format) public static final String dateTimeNow(final String format)
{ {
return parseDateToStr(format, new Date()); return parseDateToStr(format, new Date());
} }
public static final String dateTime(final Date date) public static final String dateTime(final Date date)
{ {
return parseDateToStr(YYYY_MM_DD, date); return parseDateToStr(YYYY_MM_DD, date);
} }
public static final String parseDateToStr(final String format, final Date date) public static final String parseDateToStr(final String format, final Date date)
{ {
return new SimpleDateFormat(format).format(date); return new SimpleDateFormat(format).format(date);
} }
public static final Date dateTime(final String format, final String ts) public static final Date dateTime(final String format, final String ts)
{ {
try try
{ {
return new SimpleDateFormat(format).parse(ts); return new SimpleDateFormat(format).parse(ts);
} }
catch (ParseException e) catch (ParseException e)
{ {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
/** /**
* 日期路径 即年/月/日 如2018/08/08 * 日期路径 即年/月/日 如2018/08/08
*/ */
public static final String datePath() public static final String datePath()
{ {
Date now = new Date(); Date now = new Date();
return DateFormatUtils.format(now, "yyyy/MM/dd"); return DateFormatUtils.format(now, "yyyy/MM/dd");
} }
/** /**
* 日期路径 即年/月/日 如20180808 * 日期路径 即年/月/日 如20180808
*/ */
public static final String dateTime() public static final String dateTime()
{ {
Date now = new Date(); Date now = new Date();
return DateFormatUtils.format(now, "yyyyMMdd"); return DateFormatUtils.format(now, "yyyyMMdd");
} }
/** /**
* 日期型字符串转化为日期 格式 * 日期型字符串转化为日期 格式
*/ */
public static Date parseDate(Object str) public static Date parseDate(Object str)
{ {
if (str == null) if (str == null)
{ {
return null; return null;
} }
try try
{ {
return parseDate(str.toString(), parsePatterns); return parseDate(str.toString(), parsePatterns);
} }
catch (ParseException e) catch (ParseException e)
{ {
return null; return null;
} }
} }
/** /**
* 获取服务器启动时间 * 获取服务器启动时间
*/ */
public static Date getServerStartDate() public static Date getServerStartDate()
{ {
long time = ManagementFactory.getRuntimeMXBean().getStartTime(); long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time); return new Date(time);
} }
/** /**
* 计算两个时间差 * 计算两个时间差
*/ */
public static String getDatePoor(Date endDate, Date nowDate) public static String getDatePoor(Date endDate, Date nowDate)
{ {
long nd = 1000 * 24 * 60 * 60; long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60; long nh = 1000 * 60 * 60;
long nm = 1000 * 60; long nm = 1000 * 60;
// long ns = 1000; // long ns = 1000;
// 获得两个时间的毫秒时间差异 // 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime(); long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天 // 计算差多少天
long day = diff / nd; long day = diff / nd;
// 计算差多少小时 // 计算差多少小时
long hour = diff % nd / nh; long hour = diff % nd / nh;
// 计算差多少分钟 // 计算差多少分钟
long min = diff % nd % nh / nm; long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果 // 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns; // long sec = diff % nd % nh % nm / ns;
return day + "" + hour + "小时" + min + "分钟"; return day + "" + hour + "小时" + min + "分钟";
} }
} }

View File

@ -1,51 +1,51 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import com.ruoyi.common.core.lang.UUID; import com.ruoyi.common.core.lang.UUID;
/** /**
* ID生成器工具类 * ID生成器工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class IdUtils public class IdUtils
{ {
/** /**
* 获取随机UUID * 获取随机UUID
* *
* @return 随机UUID * @return 随机UUID
*/ */
public static String randomUUID() public static String randomUUID()
{ {
return UUID.randomUUID().toString(); return UUID.randomUUID().toString();
} }
/** /**
* 简化的UUID去掉了横线 * 简化的UUID去掉了横线
* *
* @return 简化的UUID去掉了横线 * @return 简化的UUID去掉了横线
*/ */
public static String simpleUUID() public static String simpleUUID()
{ {
return UUID.randomUUID().toString(true); return UUID.randomUUID().toString(true);
} }
/** /**
* 获取随机UUID使用性能更好的ThreadLocalRandom生成UUID * 获取随机UUID使用性能更好的ThreadLocalRandom生成UUID
* *
* @return 随机UUID * @return 随机UUID
*/ */
public static String fastUUID() public static String fastUUID()
{ {
return UUID.fastUUID().toString(); return UUID.fastUUID().toString();
} }
/** /**
* 简化的UUID去掉了横线使用性能更好的ThreadLocalRandom生成UUID * 简化的UUID去掉了横线使用性能更好的ThreadLocalRandom生成UUID
* *
* @return 简化的UUID去掉了横线 * @return 简化的UUID去掉了横线
*/ */
public static String fastSimpleUUID() public static String fastSimpleUUID()
{ {
return UUID.fastUUID().toString(true); return UUID.fastUUID().toString(true);
} }
} }

View File

@ -1,18 +1,18 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
/** /**
* 处理并记录日志文件 * 处理并记录日志文件
* *
* @author ruoyi * @author ruoyi
*/ */
public class LogUtils public class LogUtils
{ {
public static String getBlock(Object msg) public static String getBlock(Object msg)
{ {
if (msg == null) if (msg == null)
{ {
msg = ""; msg = "";
} }
return "[" + msg.toString() + "]"; return "[" + msg.toString() + "]";
} }
} }

View File

@ -1,26 +1,26 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
/** /**
* 获取i18n资源文件 * 获取i18n资源文件
* *
* @author ruoyi * @author ruoyi
*/ */
public class MessageUtils public class MessageUtils
{ {
/** /**
* 根据消息键和参数 获取消息 委托给spring messageSource * 根据消息键和参数 获取消息 委托给spring messageSource
* *
* @param code 消息键 * @param code 消息键
* @param args 参数 * @param args 参数
* @return 获取国际化翻译值 * @return 获取国际化翻译值
*/ */
public static String message(String code, Object... args) public static String message(String code, Object... args)
{ {
MessageSource messageSource = SpringUtils.getBean(MessageSource.class); MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
return messageSource.getMessage(code, args, LocaleContextHolder.getLocale()); return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
} }
} }

View File

@ -1,90 +1,90 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.exception.CustomException; import com.ruoyi.common.exception.CustomException;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
/** /**
* 安全服务工具类 * 安全服务工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class SecurityUtils public class SecurityUtils
{ {
/** /**
* 获取用户账户 * 获取用户账户
**/ **/
public static String getUsername() public static String getUsername()
{ {
try try
{ {
return getLoginUser().getUsername(); return getLoginUser().getUsername();
} }
catch (Exception e) catch (Exception e)
{ {
throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED); throw new CustomException("获取用户账户异常", HttpStatus.UNAUTHORIZED);
} }
} }
/** /**
* 获取用户 * 获取用户
**/ **/
public static LoginUser getLoginUser() public static LoginUser getLoginUser()
{ {
try try
{ {
return (LoginUser) getAuthentication().getPrincipal(); return (LoginUser) getAuthentication().getPrincipal();
} }
catch (Exception e) catch (Exception e)
{ {
throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED); throw new CustomException("获取用户信息异常", HttpStatus.UNAUTHORIZED);
} }
} }
/** /**
* 获取Authentication * 获取Authentication
*/ */
public static Authentication getAuthentication() public static Authentication getAuthentication()
{ {
return SecurityContextHolder.getContext().getAuthentication(); return SecurityContextHolder.getContext().getAuthentication();
} }
/** /**
* 生成BCryptPasswordEncoder密码 * 生成BCryptPasswordEncoder密码
* *
* @param password 密码 * @param password 密码
* @return 加密字符串 * @return 加密字符串
*/ */
public static String encryptPassword(String password) public static String encryptPassword(String password)
{ {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.encode(password); return passwordEncoder.encode(password);
} }
/** /**
* 判断密码是否相同 * 判断密码是否相同
* *
* @param rawPassword 真实密码 * @param rawPassword 真实密码
* @param encodedPassword 加密后字符 * @param encodedPassword 加密后字符
* @return 结果 * @return 结果
*/ */
public static boolean matchesPassword(String rawPassword, String encodedPassword) public static boolean matchesPassword(String rawPassword, String encodedPassword)
{ {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.matches(rawPassword, encodedPassword); return passwordEncoder.matches(rawPassword, encodedPassword);
} }
/** /**
* 是否为管理员 * 是否为管理员
* *
* @param userId 用户ID * @param userId 用户ID
* @return 结果 * @return 结果
*/ */
public static boolean isAdmin(Long userId) public static boolean isAdmin(Long userId)
{ {
return userId != null && 1L == userId; return userId != null && 1L == userId;
} }
} }

View File

@ -1,136 +1,136 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.io.IOException; import java.io.IOException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
/** /**
* 客户端工具类 * 客户端工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class ServletUtils public class ServletUtils
{ {
/** /**
* 获取String参数 * 获取String参数
*/ */
public static String getParameter(String name) public static String getParameter(String name)
{ {
return getRequest().getParameter(name); return getRequest().getParameter(name);
} }
/** /**
* 获取String参数 * 获取String参数
*/ */
public static String getParameter(String name, String defaultValue) public static String getParameter(String name, String defaultValue)
{ {
return Convert.toStr(getRequest().getParameter(name), defaultValue); return Convert.toStr(getRequest().getParameter(name), defaultValue);
} }
/** /**
* 获取Integer参数 * 获取Integer参数
*/ */
public static Integer getParameterToInt(String name) public static Integer getParameterToInt(String name)
{ {
return Convert.toInt(getRequest().getParameter(name)); return Convert.toInt(getRequest().getParameter(name));
} }
/** /**
* 获取Integer参数 * 获取Integer参数
*/ */
public static Integer getParameterToInt(String name, Integer defaultValue) public static Integer getParameterToInt(String name, Integer defaultValue)
{ {
return Convert.toInt(getRequest().getParameter(name), defaultValue); return Convert.toInt(getRequest().getParameter(name), defaultValue);
} }
/** /**
* 获取request * 获取request
*/ */
public static HttpServletRequest getRequest() public static HttpServletRequest getRequest()
{ {
return getRequestAttributes().getRequest(); return getRequestAttributes().getRequest();
} }
/** /**
* 获取response * 获取response
*/ */
public static HttpServletResponse getResponse() public static HttpServletResponse getResponse()
{ {
return getRequestAttributes().getResponse(); return getRequestAttributes().getResponse();
} }
/** /**
* 获取session * 获取session
*/ */
public static HttpSession getSession() public static HttpSession getSession()
{ {
return getRequest().getSession(); return getRequest().getSession();
} }
public static ServletRequestAttributes getRequestAttributes() public static ServletRequestAttributes getRequestAttributes()
{ {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes(); RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes) attributes; return (ServletRequestAttributes) attributes;
} }
/** /**
* 将字符串渲染到客户端 * 将字符串渲染到客户端
* *
* @param response 渲染对象 * @param response 渲染对象
* @param string 待渲染的字符串 * @param string 待渲染的字符串
* @return null * @return null
*/ */
public static String renderString(HttpServletResponse response, String string) public static String renderString(HttpServletResponse response, String string)
{ {
try try
{ {
response.setStatus(200); response.setStatus(200);
response.setContentType("application/json"); response.setContentType("application/json");
response.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8");
response.getWriter().print(string); response.getWriter().print(string);
} }
catch (IOException e) catch (IOException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
/** /**
* 是否是Ajax异步请求 * 是否是Ajax异步请求
* *
* @param request * @param request
*/ */
public static boolean isAjaxRequest(HttpServletRequest request) public static boolean isAjaxRequest(HttpServletRequest request)
{ {
String accept = request.getHeader("accept"); String accept = request.getHeader("accept");
if (accept != null && accept.indexOf("application/json") != -1) if (accept != null && accept.indexOf("application/json") != -1)
{ {
return true; return true;
} }
String xRequestedWith = request.getHeader("X-Requested-With"); String xRequestedWith = request.getHeader("X-Requested-With");
if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
{ {
return true; return true;
} }
String uri = request.getRequestURI(); String uri = request.getRequestURI();
if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
{ {
return true; return true;
} }
String ajax = request.getParameter("__ajax"); String ajax = request.getParameter("__ajax");
if (StringUtils.inStringIgnoreCase(ajax, "json", "xml")) if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
{ {
return true; return true;
} }
return false; return false;
} }
} }

View File

@ -1,453 +1,453 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import com.ruoyi.common.core.text.StrFormatter; import com.ruoyi.common.core.text.StrFormatter;
/** /**
* 字符串工具类 * 字符串工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class StringUtils extends org.apache.commons.lang3.StringUtils public class StringUtils extends org.apache.commons.lang3.StringUtils
{ {
/** 空字符串 */ /** 空字符串 */
private static final String NULLSTR = ""; private static final String NULLSTR = "";
/** 下划线 */ /** 下划线 */
private static final char SEPARATOR = '_'; private static final char SEPARATOR = '_';
/** /**
* 获取参数不为空值 * 获取参数不为空值
* *
* @param value defaultValue 要判断的value * @param value defaultValue 要判断的value
* @return value 返回值 * @return value 返回值
*/ */
public static <T> T nvl(T value, T defaultValue) public static <T> T nvl(T value, T defaultValue)
{ {
return value != null ? value : defaultValue; return value != null ? value : defaultValue;
} }
/** /**
* * 判断一个Collection是否为空 包含ListSetQueue * * 判断一个Collection是否为空 包含ListSetQueue
* *
* @param coll 要判断的Collection * @param coll 要判断的Collection
* @return true为空 false非空 * @return true为空 false非空
*/ */
public static boolean isEmpty(Collection<?> coll) public static boolean isEmpty(Collection<?> coll)
{ {
return isNull(coll) || coll.isEmpty(); return isNull(coll) || coll.isEmpty();
} }
/** /**
* * 判断一个Collection是否非空包含ListSetQueue * * 判断一个Collection是否非空包含ListSetQueue
* *
* @param coll 要判断的Collection * @param coll 要判断的Collection
* @return true非空 false * @return true非空 false
*/ */
public static boolean isNotEmpty(Collection<?> coll) public static boolean isNotEmpty(Collection<?> coll)
{ {
return !isEmpty(coll); return !isEmpty(coll);
} }
/** /**
* * 判断一个对象数组是否为空 * * 判断一个对象数组是否为空
* *
* @param objects 要判断的对象数组 * @param objects 要判断的对象数组
** @return true为空 false非空 ** @return true为空 false非空
*/ */
public static boolean isEmpty(Object[] objects) public static boolean isEmpty(Object[] objects)
{ {
return isNull(objects) || (objects.length == 0); return isNull(objects) || (objects.length == 0);
} }
/** /**
* * 判断一个对象数组是否非空 * * 判断一个对象数组是否非空
* *
* @param objects 要判断的对象数组 * @param objects 要判断的对象数组
* @return true非空 false * @return true非空 false
*/ */
public static boolean isNotEmpty(Object[] objects) public static boolean isNotEmpty(Object[] objects)
{ {
return !isEmpty(objects); return !isEmpty(objects);
} }
/** /**
* * 判断一个Map是否为空 * * 判断一个Map是否为空
* *
* @param map 要判断的Map * @param map 要判断的Map
* @return true为空 false非空 * @return true为空 false非空
*/ */
public static boolean isEmpty(Map<?, ?> map) public static boolean isEmpty(Map<?, ?> map)
{ {
return isNull(map) || map.isEmpty(); return isNull(map) || map.isEmpty();
} }
/** /**
* * 判断一个Map是否为空 * * 判断一个Map是否为空
* *
* @param map 要判断的Map * @param map 要判断的Map
* @return true非空 false * @return true非空 false
*/ */
public static boolean isNotEmpty(Map<?, ?> map) public static boolean isNotEmpty(Map<?, ?> map)
{ {
return !isEmpty(map); return !isEmpty(map);
} }
/** /**
* * 判断一个字符串是否为空串 * * 判断一个字符串是否为空串
* *
* @param str String * @param str String
* @return true为空 false非空 * @return true为空 false非空
*/ */
public static boolean isEmpty(String str) public static boolean isEmpty(String str)
{ {
return isNull(str) || NULLSTR.equals(str.trim()); return isNull(str) || NULLSTR.equals(str.trim());
} }
/** /**
* * 判断一个字符串是否为非空串 * * 判断一个字符串是否为非空串
* *
* @param str String * @param str String
* @return true非空串 false空串 * @return true非空串 false空串
*/ */
public static boolean isNotEmpty(String str) public static boolean isNotEmpty(String str)
{ {
return !isEmpty(str); return !isEmpty(str);
} }
/** /**
* * 判断一个对象是否为空 * * 判断一个对象是否为空
* *
* @param object Object * @param object Object
* @return true为空 false非空 * @return true为空 false非空
*/ */
public static boolean isNull(Object object) public static boolean isNull(Object object)
{ {
return object == null; return object == null;
} }
/** /**
* * 判断一个对象是否非空 * * 判断一个对象是否非空
* *
* @param object Object * @param object Object
* @return true非空 false * @return true非空 false
*/ */
public static boolean isNotNull(Object object) public static boolean isNotNull(Object object)
{ {
return !isNull(object); return !isNull(object);
} }
/** /**
* * 判断一个对象是否是数组类型Java基本型别的数组 * * 判断一个对象是否是数组类型Java基本型别的数组
* *
* @param object 对象 * @param object 对象
* @return true是数组 false不是数组 * @return true是数组 false不是数组
*/ */
public static boolean isArray(Object object) public static boolean isArray(Object object)
{ {
return isNotNull(object) && object.getClass().isArray(); return isNotNull(object) && object.getClass().isArray();
} }
/** /**
* 去空格 * 去空格
*/ */
public static String trim(String str) public static String trim(String str)
{ {
return (str == null ? "" : str.trim()); return (str == null ? "" : str.trim());
} }
/** /**
* 截取字符串 * 截取字符串
* *
* @param str 字符串 * @param str 字符串
* @param start 开始 * @param start 开始
* @return 结果 * @return 结果
*/ */
public static String substring(final String str, int start) public static String substring(final String str, int start)
{ {
if (str == null) if (str == null)
{ {
return NULLSTR; return NULLSTR;
} }
if (start < 0) if (start < 0)
{ {
start = str.length() + start; start = str.length() + start;
} }
if (start < 0) if (start < 0)
{ {
start = 0; start = 0;
} }
if (start > str.length()) if (start > str.length())
{ {
return NULLSTR; return NULLSTR;
} }
return str.substring(start); return str.substring(start);
} }
/** /**
* 截取字符串 * 截取字符串
* *
* @param str 字符串 * @param str 字符串
* @param start 开始 * @param start 开始
* @param end 结束 * @param end 结束
* @return 结果 * @return 结果
*/ */
public static String substring(final String str, int start, int end) public static String substring(final String str, int start, int end)
{ {
if (str == null) if (str == null)
{ {
return NULLSTR; return NULLSTR;
} }
if (end < 0) if (end < 0)
{ {
end = str.length() + end; end = str.length() + end;
} }
if (start < 0) if (start < 0)
{ {
start = str.length() + start; start = str.length() + start;
} }
if (end > str.length()) if (end > str.length())
{ {
end = str.length(); end = str.length();
} }
if (start > end) if (start > end)
{ {
return NULLSTR; return NULLSTR;
} }
if (start < 0) if (start < 0)
{ {
start = 0; start = 0;
} }
if (end < 0) if (end < 0)
{ {
end = 0; end = 0;
} }
return str.substring(start, end); return str.substring(start, end);
} }
/** /**
* 格式化文本, {} 表示占位符<br> * 格式化文本, {} 表示占位符<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br> * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br> * 例:<br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br> * 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> * 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> * 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
* *
* @param template 文本模板,被替换的部分用 {} 表示 * @param template 文本模板,被替换的部分用 {} 表示
* @param params 参数值 * @param params 参数值
* @return 格式化后的文本 * @return 格式化后的文本
*/ */
public static String format(String template, Object... params) public static String format(String template, Object... params)
{ {
if (isEmpty(params) || isEmpty(template)) if (isEmpty(params) || isEmpty(template))
{ {
return template; return template;
} }
return StrFormatter.format(template, params); return StrFormatter.format(template, params);
} }
/** /**
* 字符串转set * 字符串转set
* *
* @param str 字符串 * @param str 字符串
* @param sep 分隔符 * @param sep 分隔符
* @return set集合 * @return set集合
*/ */
public static final Set<String> str2Set(String str, String sep) public static final Set<String> str2Set(String str, String sep)
{ {
return new HashSet<String>(str2List(str, sep, true, false)); return new HashSet<String>(str2List(str, sep, true, false));
} }
/** /**
* 字符串转list * 字符串转list
* *
* @param str 字符串 * @param str 字符串
* @param sep 分隔符 * @param sep 分隔符
* @param filterBlank 过滤纯空白 * @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白 * @param trim 去掉首尾空白
* @return list集合 * @return list集合
*/ */
public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
{ {
List<String> list = new ArrayList<String>(); List<String> list = new ArrayList<String>();
if (StringUtils.isEmpty(str)) if (StringUtils.isEmpty(str))
{ {
return list; return list;
} }
// 过滤空白字符串 // 过滤空白字符串
if (filterBlank && StringUtils.isBlank(str)) if (filterBlank && StringUtils.isBlank(str))
{ {
return list; return list;
} }
String[] split = str.split(sep); String[] split = str.split(sep);
for (String string : split) for (String string : split)
{ {
if (filterBlank && StringUtils.isBlank(string)) if (filterBlank && StringUtils.isBlank(string))
{ {
continue; continue;
} }
if (trim) if (trim)
{ {
string = string.trim(); string = string.trim();
} }
list.add(string); list.add(string);
} }
return list; return list;
} }
/** /**
* 下划线转驼峰命名 * 下划线转驼峰命名
*/ */
public static String toUnderScoreCase(String str) public static String toUnderScoreCase(String str)
{ {
if (str == null) if (str == null)
{ {
return null; return null;
} }
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
// 前置字符是否大写 // 前置字符是否大写
boolean preCharIsUpperCase = true; boolean preCharIsUpperCase = true;
// 当前字符是否大写 // 当前字符是否大写
boolean curreCharIsUpperCase = true; boolean curreCharIsUpperCase = true;
// 下一字符是否大写 // 下一字符是否大写
boolean nexteCharIsUpperCase = true; boolean nexteCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++) for (int i = 0; i < str.length(); i++)
{ {
char c = str.charAt(i); char c = str.charAt(i);
if (i > 0) if (i > 0)
{ {
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1)); preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
} }
else else
{ {
preCharIsUpperCase = false; preCharIsUpperCase = false;
} }
curreCharIsUpperCase = Character.isUpperCase(c); curreCharIsUpperCase = Character.isUpperCase(c);
if (i < (str.length() - 1)) if (i < (str.length() - 1))
{ {
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1)); nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
} }
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
{ {
sb.append(SEPARATOR); sb.append(SEPARATOR);
} }
else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
{ {
sb.append(SEPARATOR); sb.append(SEPARATOR);
} }
sb.append(Character.toLowerCase(c)); sb.append(Character.toLowerCase(c));
} }
return sb.toString(); return sb.toString();
} }
/** /**
* 是否包含字符串 * 是否包含字符串
* *
* @param str 验证字符串 * @param str 验证字符串
* @param strs 字符串组 * @param strs 字符串组
* @return 包含返回true * @return 包含返回true
*/ */
public static boolean inStringIgnoreCase(String str, String... strs) public static boolean inStringIgnoreCase(String str, String... strs)
{ {
if (str != null && strs != null) if (str != null && strs != null)
{ {
for (String s : strs) for (String s : strs)
{ {
if (str.equalsIgnoreCase(trim(s))) if (str.equalsIgnoreCase(trim(s)))
{ {
return true; return true;
} }
} }
} }
return false; return false;
} }
/** /**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如HELLO_WORLD->HelloWorld * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如HELLO_WORLD->HelloWorld
* *
* @param name 转换前的下划线大写方式命名的字符串 * @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串 * @return 转换后的驼峰式命名的字符串
*/ */
public static String convertToCamelCase(String name) public static String convertToCamelCase(String name)
{ {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
// 快速检查 // 快速检查
if (name == null || name.isEmpty()) if (name == null || name.isEmpty())
{ {
// 没必要转换 // 没必要转换
return ""; return "";
} }
else if (!name.contains("_")) else if (!name.contains("_"))
{ {
// 不含下划线,仅将首字母大写 // 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1); return name.substring(0, 1).toUpperCase() + name.substring(1);
} }
// 用下划线将原始字符串分割 // 用下划线将原始字符串分割
String[] camels = name.split("_"); String[] camels = name.split("_");
for (String camel : camels) for (String camel : camels)
{ {
// 跳过原始字符串中开头、结尾的下换线或双重下划线 // 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty()) if (camel.isEmpty())
{ {
continue; continue;
} }
// 首字母大写 // 首字母大写
result.append(camel.substring(0, 1).toUpperCase()); result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase()); result.append(camel.substring(1).toLowerCase());
} }
return result.toString(); return result.toString();
} }
/** /**
* 驼峰式命名法 例如user_name->userName * 驼峰式命名法 例如user_name->userName
*/ */
public static String toCamelCase(String s) public static String toCamelCase(String s)
{ {
if (s == null) if (s == null)
{ {
return null; return null;
} }
s = s.toLowerCase(); s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length()); StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false; boolean upperCase = false;
for (int i = 0; i < s.length(); i++) for (int i = 0; i < s.length(); i++)
{ {
char c = s.charAt(i); char c = s.charAt(i);
if (c == SEPARATOR) if (c == SEPARATOR)
{ {
upperCase = true; upperCase = true;
} }
else if (upperCase) else if (upperCase)
{ {
sb.append(Character.toUpperCase(c)); sb.append(Character.toUpperCase(c));
upperCase = false; upperCase = false;
} }
else else
{ {
sb.append(c); sb.append(c);
} }
} }
return sb.toString(); return sb.toString();
} }
} }

View File

@ -1,99 +1,99 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* 线程相关工具类. * 线程相关工具类.
* *
* @author ruoyi * @author ruoyi
*/ */
public class Threads public class Threads
{ {
private static final Logger logger = LoggerFactory.getLogger(Threads.class); private static final Logger logger = LoggerFactory.getLogger(Threads.class);
/** /**
* sleep等待,单位为毫秒 * sleep等待,单位为毫秒
*/ */
public static void sleep(long milliseconds) public static void sleep(long milliseconds)
{ {
try try
{ {
Thread.sleep(milliseconds); Thread.sleep(milliseconds);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
return; return;
} }
} }
/** /**
* 停止线程池 * 停止线程池
* 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务. * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
* 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数. * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
* 如果仍人超時,則強制退出. * 如果仍人超時,則強制退出.
* 另对在shutdown时线程本身被调用中断做了处理. * 另对在shutdown时线程本身被调用中断做了处理.
*/ */
public static void shutdownAndAwaitTermination(ExecutorService pool) public static void shutdownAndAwaitTermination(ExecutorService pool)
{ {
if (pool != null && !pool.isShutdown()) if (pool != null && !pool.isShutdown())
{ {
pool.shutdown(); pool.shutdown();
try try
{ {
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) if (!pool.awaitTermination(120, TimeUnit.SECONDS))
{ {
pool.shutdownNow(); pool.shutdownNow();
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) if (!pool.awaitTermination(120, TimeUnit.SECONDS))
{ {
logger.info("Pool did not terminate"); logger.info("Pool did not terminate");
} }
} }
} }
catch (InterruptedException ie) catch (InterruptedException ie)
{ {
pool.shutdownNow(); pool.shutdownNow();
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
} }
} }
/** /**
* 打印线程异常信息 * 打印线程异常信息
*/ */
public static void printException(Runnable r, Throwable t) public static void printException(Runnable r, Throwable t)
{ {
if (t == null && r instanceof Future<?>) if (t == null && r instanceof Future<?>)
{ {
try try
{ {
Future<?> future = (Future<?>) r; Future<?> future = (Future<?>) r;
if (future.isDone()) if (future.isDone())
{ {
future.get(); future.get();
} }
} }
catch (CancellationException ce) catch (CancellationException ce)
{ {
t = ce; t = ce;
} }
catch (ExecutionException ee) catch (ExecutionException ee)
{ {
t = ee.getCause(); t = ee.getCause();
} }
catch (InterruptedException ie) catch (InterruptedException ie)
{ {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
} }
} }
if (t != null) if (t != null)
{ {
logger.error(t.getMessage(), t); logger.error(t.getMessage(), t);
} }
} }
} }

View File

@ -1,226 +1,226 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.Random; import java.util.Random;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
/** /**
* 验证码工具类 * 验证码工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class VerifyCodeUtils public class VerifyCodeUtils
{ {
// 使用到Algerian字体系统里没有的话需要安装字体字体只显示大写去掉了1,0,i,o几个容易混淆的字符 // 使用到Algerian字体系统里没有的话需要安装字体字体只显示大写去掉了1,0,i,o几个容易混淆的字符
public static final String VERIFY_CODES = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ"; public static final String VERIFY_CODES = "123456789ABCDEFGHJKLMNPQRSTUVWXYZ";
private static Random random = new SecureRandom(); private static Random random = new SecureRandom();
/** /**
* 使用系统默认字符源生成验证码 * 使用系统默认字符源生成验证码
* *
* @param verifySize 验证码长度 * @param verifySize 验证码长度
* @return * @return
*/ */
public static String generateVerifyCode(int verifySize) public static String generateVerifyCode(int verifySize)
{ {
return generateVerifyCode(verifySize, VERIFY_CODES); return generateVerifyCode(verifySize, VERIFY_CODES);
} }
/** /**
* 使用指定源生成验证码 * 使用指定源生成验证码
* *
* @param verifySize 验证码长度 * @param verifySize 验证码长度
* @param sources 验证码字符源 * @param sources 验证码字符源
* @return * @return
*/ */
public static String generateVerifyCode(int verifySize, String sources) public static String generateVerifyCode(int verifySize, String sources)
{ {
if (sources == null || sources.length() == 0) if (sources == null || sources.length() == 0)
{ {
sources = VERIFY_CODES; sources = VERIFY_CODES;
} }
int codesLen = sources.length(); int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis()); Random rand = new Random(System.currentTimeMillis());
StringBuilder verifyCode = new StringBuilder(verifySize); StringBuilder verifyCode = new StringBuilder(verifySize);
for (int i = 0; i < verifySize; i++) for (int i = 0; i < verifySize; i++)
{ {
verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1))); verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
} }
return verifyCode.toString(); return verifyCode.toString();
} }
/** /**
* 输出指定验证码图片流 * 输出指定验证码图片流
* *
* @param w * @param w
* @param h * @param h
* @param os * @param os
* @param code * @param code
* @throws IOException * @throws IOException
*/ */
public static void outputImage(int w, int h, OutputStream os, String code) throws IOException public static void outputImage(int w, int h, OutputStream os, String code) throws IOException
{ {
int verifySize = code.length(); int verifySize = code.length();
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Random rand = new Random(); Random rand = new Random();
Graphics2D g2 = image.createGraphics(); Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color[] colors = new Color[5]; Color[] colors = new Color[5];
Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,
Color.ORANGE, Color.PINK, Color.YELLOW }; Color.ORANGE, Color.PINK, Color.YELLOW };
float[] fractions = new float[colors.length]; float[] fractions = new float[colors.length];
for (int i = 0; i < colors.length; i++) for (int i = 0; i < colors.length; i++)
{ {
colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
fractions[i] = rand.nextFloat(); fractions[i] = rand.nextFloat();
} }
Arrays.sort(fractions); Arrays.sort(fractions);
g2.setColor(Color.GRAY);// 设置边框色 g2.setColor(Color.GRAY);// 设置边框色
g2.fillRect(0, 0, w, h); g2.fillRect(0, 0, w, h);
Color c = getRandColor(200, 250); Color c = getRandColor(200, 250);
g2.setColor(c);// 设置背景色 g2.setColor(c);// 设置背景色
g2.fillRect(0, 2, w, h - 4); g2.fillRect(0, 2, w, h - 4);
// 绘制干扰线 // 绘制干扰线
Random random = new Random(); Random random = new Random();
g2.setColor(getRandColor(160, 200));// 设置线条的颜色 g2.setColor(getRandColor(160, 200));// 设置线条的颜色
for (int i = 0; i < 20; i++) for (int i = 0; i < 20; i++)
{ {
int x = random.nextInt(w - 1); int x = random.nextInt(w - 1);
int y = random.nextInt(h - 1); int y = random.nextInt(h - 1);
int xl = random.nextInt(6) + 1; int xl = random.nextInt(6) + 1;
int yl = random.nextInt(12) + 1; int yl = random.nextInt(12) + 1;
g2.drawLine(x, y, x + xl + 40, y + yl + 20); g2.drawLine(x, y, x + xl + 40, y + yl + 20);
} }
// 添加噪点 // 添加噪点
float yawpRate = 0.05f;// 噪声率 float yawpRate = 0.05f;// 噪声率
int area = (int) (yawpRate * w * h); int area = (int) (yawpRate * w * h);
for (int i = 0; i < area; i++) for (int i = 0; i < area; i++)
{ {
int x = random.nextInt(w); int x = random.nextInt(w);
int y = random.nextInt(h); int y = random.nextInt(h);
int rgb = getRandomIntColor(); int rgb = getRandomIntColor();
image.setRGB(x, y, rgb); image.setRGB(x, y, rgb);
} }
shear(g2, w, h, c);// 使图片扭曲 shear(g2, w, h, c);// 使图片扭曲
g2.setColor(getRandColor(100, 160)); g2.setColor(getRandColor(100, 160));
int fontSize = h - 4; int fontSize = h - 4;
Font font = new Font("Algerian", Font.ITALIC, fontSize); Font font = new Font("Algerian", Font.ITALIC, fontSize);
g2.setFont(font); g2.setFont(font);
char[] chars = code.toCharArray(); char[] chars = code.toCharArray();
for (int i = 0; i < verifySize; i++) for (int i = 0; i < verifySize; i++)
{ {
AffineTransform affine = new AffineTransform(); AffineTransform affine = new AffineTransform();
affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
(w / verifySize) * i + fontSize / 2, h / 2); (w / verifySize) * i + fontSize / 2, h / 2);
g2.setTransform(affine); g2.setTransform(affine);
g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10); g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
} }
g2.dispose(); g2.dispose();
ImageIO.write(image, "jpg", os); ImageIO.write(image, "jpg", os);
} }
private static Color getRandColor(int fc, int bc) private static Color getRandColor(int fc, int bc)
{ {
if (fc > 255) if (fc > 255)
fc = 255; fc = 255;
if (bc > 255) if (bc > 255)
bc = 255; bc = 255;
int r = fc + random.nextInt(bc - fc); int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b); return new Color(r, g, b);
} }
private static int getRandomIntColor() private static int getRandomIntColor()
{ {
int[] rgb = getRandomRgb(); int[] rgb = getRandomRgb();
int color = 0; int color = 0;
for (int c : rgb) for (int c : rgb)
{ {
color = color << 8; color = color << 8;
color = color | c; color = color | c;
} }
return color; return color;
} }
private static int[] getRandomRgb() private static int[] getRandomRgb()
{ {
int[] rgb = new int[3]; int[] rgb = new int[3];
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
rgb[i] = random.nextInt(255); rgb[i] = random.nextInt(255);
} }
return rgb; return rgb;
} }
private static void shear(Graphics g, int w1, int h1, Color color) private static void shear(Graphics g, int w1, int h1, Color color)
{ {
shearX(g, w1, h1, color); shearX(g, w1, h1, color);
shearY(g, w1, h1, color); shearY(g, w1, h1, color);
} }
private static void shearX(Graphics g, int w1, int h1, Color color) private static void shearX(Graphics g, int w1, int h1, Color color)
{ {
int period = random.nextInt(2); int period = random.nextInt(2);
boolean borderGap = true; boolean borderGap = true;
int frames = 1; int frames = 1;
int phase = random.nextInt(2); int phase = random.nextInt(2);
for (int i = 0; i < h1; i++) for (int i = 0; i < h1; i++)
{ {
double d = (double) (period >> 1) double d = (double) (period >> 1)
* Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
g.copyArea(0, i, w1, 1, (int) d, 0); g.copyArea(0, i, w1, 1, (int) d, 0);
if (borderGap) if (borderGap)
{ {
g.setColor(color); g.setColor(color);
g.drawLine((int) d, i, 0, i); g.drawLine((int) d, i, 0, i);
g.drawLine((int) d + w1, i, w1, i); g.drawLine((int) d + w1, i, w1, i);
} }
} }
} }
private static void shearY(Graphics g, int w1, int h1, Color color) private static void shearY(Graphics g, int w1, int h1, Color color)
{ {
int period = random.nextInt(40) + 10; // 50; int period = random.nextInt(40) + 10; // 50;
boolean borderGap = true; boolean borderGap = true;
int frames = 20; int frames = 20;
int phase = 7; int phase = 7;
for (int i = 0; i < w1; i++) for (int i = 0; i < w1; i++)
{ {
double d = (double) (period >> 1) double d = (double) (period >> 1)
* Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);
g.copyArea(i, 0, 1, h1, 0, (int) d); g.copyArea(i, 0, 1, h1, 0, (int) d);
if (borderGap) if (borderGap)
{ {
g.setColor(color); g.setColor(color);
g.drawLine(i, (int) d, i, 0); g.drawLine(i, (int) d, i, 0);
g.drawLine(i, (int) d + h1, i, h1); g.drawLine(i, (int) d + h1, i, h1);
} }
} }
} }
} }

View File

@ -1,243 +1,243 @@
package com.ruoyi.common.utils.file; package com.ruoyi.common.utils.file;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException; import com.ruoyi.common.exception.file.FileNameLengthLimitExceededException;
import com.ruoyi.common.exception.file.FileSizeLimitExceededException; import com.ruoyi.common.exception.file.FileSizeLimitExceededException;
import com.ruoyi.common.exception.file.InvalidExtensionException; import com.ruoyi.common.exception.file.InvalidExtensionException;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.security.Md5Utils; import com.ruoyi.common.utils.security.Md5Utils;
import com.ruoyi.framework.config.RuoYiConfig; import com.ruoyi.framework.config.RuoYiConfig;
/** /**
* 文件上传工具类 * 文件上传工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileUploadUtils public class FileUploadUtils
{ {
/** /**
* 默认大小 50M * 默认大小 50M
*/ */
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
/** /**
* 默认的文件名最大长度 100 * 默认的文件名最大长度 100
*/ */
public static final int DEFAULT_FILE_NAME_LENGTH = 100; public static final int DEFAULT_FILE_NAME_LENGTH = 100;
/** /**
* 默认上传的地址 * 默认上传的地址
*/ */
private static String defaultBaseDir = RuoYiConfig.getProfile(); private static String defaultBaseDir = RuoYiConfig.getProfile();
private static int counter = 0; private static int counter = 0;
public static void setDefaultBaseDir(String defaultBaseDir) public static void setDefaultBaseDir(String defaultBaseDir)
{ {
FileUploadUtils.defaultBaseDir = defaultBaseDir; FileUploadUtils.defaultBaseDir = defaultBaseDir;
} }
public static String getDefaultBaseDir() public static String getDefaultBaseDir()
{ {
return defaultBaseDir; return defaultBaseDir;
} }
/** /**
* 以默认配置进行文件上传 * 以默认配置进行文件上传
* *
* @param file 上传的文件 * @param file 上传的文件
* @return 文件名称 * @return 文件名称
* @throws Exception * @throws Exception
*/ */
public static final String upload(MultipartFile file) throws IOException public static final String upload(MultipartFile file) throws IOException
{ {
try try
{ {
return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); return upload(getDefaultBaseDir(), file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
} }
catch (Exception e) catch (Exception e)
{ {
throw new IOException(e.getMessage(), e); throw new IOException(e.getMessage(), e);
} }
} }
/** /**
* 根据文件路径上传 * 根据文件路径上传
* *
* @param baseDir 相对应用的基目录 * @param baseDir 相对应用的基目录
* @param file 上传的文件 * @param file 上传的文件
* @return 文件名称 * @return 文件名称
* @throws IOException * @throws IOException
*/ */
public static final String upload(String baseDir, MultipartFile file) throws IOException public static final String upload(String baseDir, MultipartFile file) throws IOException
{ {
try try
{ {
return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION); return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
} }
catch (Exception e) catch (Exception e)
{ {
throw new IOException(e.getMessage(), e); throw new IOException(e.getMessage(), e);
} }
} }
/** /**
* 文件上传 * 文件上传
* *
* @param baseDir 相对应用的基目录 * @param baseDir 相对应用的基目录
* @param file 上传的文件 * @param file 上传的文件
* @param extension 上传文件类型 * @param extension 上传文件类型
* @return 返回上传成功的文件名 * @return 返回上传成功的文件名
* @throws FileSizeLimitExceededException 如果超出最大大小 * @throws FileSizeLimitExceededException 如果超出最大大小
* @throws FileNameLengthLimitExceededException 文件名太长 * @throws FileNameLengthLimitExceededException 文件名太长
* @throws IOException 比如读写文件出错时 * @throws IOException 比如读写文件出错时
* @throws InvalidExtensionException 文件校验异常 * @throws InvalidExtensionException 文件校验异常
*/ */
public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension) public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException, throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException InvalidExtensionException
{ {
int fileNamelength = file.getOriginalFilename().length(); int fileNamelength = file.getOriginalFilename().length();
if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH) if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{ {
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH); throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
} }
assertAllowed(file, allowedExtension); assertAllowed(file, allowedExtension);
String fileName = extractFilename(file); String fileName = extractFilename(file);
File desc = getAbsoluteFile(baseDir, fileName); File desc = getAbsoluteFile(baseDir, fileName);
file.transferTo(desc); file.transferTo(desc);
String pathFileName = getPathFileName(baseDir, fileName); String pathFileName = getPathFileName(baseDir, fileName);
return pathFileName; return pathFileName;
} }
/** /**
* 编码文件名 * 编码文件名
*/ */
public static final String extractFilename(MultipartFile file) public static final String extractFilename(MultipartFile file)
{ {
String fileName = file.getOriginalFilename(); String fileName = file.getOriginalFilename();
String extension = getExtension(file); String extension = getExtension(file);
fileName = DateUtils.datePath() + "/" + encodingFilename(fileName) + "." + extension; fileName = DateUtils.datePath() + "/" + encodingFilename(fileName) + "." + extension;
return fileName; return fileName;
} }
private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{ {
File desc = new File(uploadDir + File.separator + fileName); File desc = new File(uploadDir + File.separator + fileName);
if (!desc.getParentFile().exists()) if (!desc.getParentFile().exists())
{ {
desc.getParentFile().mkdirs(); desc.getParentFile().mkdirs();
} }
if (!desc.exists()) if (!desc.exists())
{ {
desc.createNewFile(); desc.createNewFile();
} }
return desc; return desc;
} }
private static final String getPathFileName(String uploadDir, String fileName) throws IOException private static final String getPathFileName(String uploadDir, String fileName) throws IOException
{ {
int dirLastIndex = RuoYiConfig.getProfile().length() + 1; int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
String currentDir = StringUtils.substring(uploadDir, dirLastIndex); String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName; String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
return pathFileName; return pathFileName;
} }
/** /**
* 编码文件名 * 编码文件名
*/ */
private static final String encodingFilename(String fileName) private static final String encodingFilename(String fileName)
{ {
fileName = fileName.replace("_", " "); fileName = fileName.replace("_", " ");
fileName = Md5Utils.hash(fileName + System.nanoTime() + counter++); fileName = Md5Utils.hash(fileName + System.nanoTime() + counter++);
return fileName; return fileName;
} }
/** /**
* 文件大小校验 * 文件大小校验
* *
* @param file 上传的文件 * @param file 上传的文件
* @return * @return
* @throws FileSizeLimitExceededException 如果超出最大大小 * @throws FileSizeLimitExceededException 如果超出最大大小
* @throws InvalidExtensionException * @throws InvalidExtensionException
*/ */
public static final void assertAllowed(MultipartFile file, String[] allowedExtension) public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
throws FileSizeLimitExceededException, InvalidExtensionException throws FileSizeLimitExceededException, InvalidExtensionException
{ {
long size = file.getSize(); long size = file.getSize();
if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE) if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
{ {
throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024); throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
} }
String fileName = file.getOriginalFilename(); String fileName = file.getOriginalFilename();
String extension = getExtension(file); String extension = getExtension(file);
if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)) if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
{ {
if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION) if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
{ {
throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension, throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
fileName); fileName);
} }
else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION) else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
{ {
throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension, throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
fileName); fileName);
} }
else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION) else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
{ {
throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension, throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
fileName); fileName);
} }
else else
{ {
throw new InvalidExtensionException(allowedExtension, extension, fileName); throw new InvalidExtensionException(allowedExtension, extension, fileName);
} }
} }
} }
/** /**
* 判断MIME类型是否是允许的MIME类型 * 判断MIME类型是否是允许的MIME类型
* *
* @param extension * @param extension
* @param allowedExtension * @param allowedExtension
* @return * @return
*/ */
public static final boolean isAllowedExtension(String extension, String[] allowedExtension) public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
{ {
for (String str : allowedExtension) for (String str : allowedExtension)
{ {
if (str.equalsIgnoreCase(extension)) if (str.equalsIgnoreCase(extension))
{ {
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* 获取文件名的后缀 * 获取文件名的后缀
* *
* @param file 表单文件 * @param file 表单文件
* @return 后缀名 * @return 后缀名
*/ */
public static final String getExtension(MultipartFile file) public static final String getExtension(MultipartFile file)
{ {
String extension = FilenameUtils.getExtension(file.getOriginalFilename()); String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension)) if (StringUtils.isEmpty(extension))
{ {
extension = MimeTypeUtils.getExtension(file.getContentType()); extension = MimeTypeUtils.getExtension(file.getContentType());
} }
return extension; return extension;
} }
} }

View File

@ -1,142 +1,142 @@
package com.ruoyi.common.utils.file; package com.ruoyi.common.utils.file;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
* 文件处理工具类 * 文件处理工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileUtils public class FileUtils
{ {
public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
/** /**
* 输出指定文件的byte数组 * 输出指定文件的byte数组
* *
* @param filePath 文件路径 * @param filePath 文件路径
* @param os 输出流 * @param os 输出流
* @return * @return
*/ */
public static void writeBytes(String filePath, OutputStream os) throws IOException public static void writeBytes(String filePath, OutputStream os) throws IOException
{ {
FileInputStream fis = null; FileInputStream fis = null;
try try
{ {
File file = new File(filePath); File file = new File(filePath);
if (!file.exists()) if (!file.exists())
{ {
throw new FileNotFoundException(filePath); throw new FileNotFoundException(filePath);
} }
fis = new FileInputStream(file); fis = new FileInputStream(file);
byte[] b = new byte[1024]; byte[] b = new byte[1024];
int length; int length;
while ((length = fis.read(b)) > 0) while ((length = fis.read(b)) > 0)
{ {
os.write(b, 0, length); os.write(b, 0, length);
} }
} }
catch (IOException e) catch (IOException e)
{ {
throw e; throw e;
} }
finally finally
{ {
if (os != null) if (os != null)
{ {
try try
{ {
os.close(); os.close();
} }
catch (IOException e1) catch (IOException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
} }
if (fis != null) if (fis != null)
{ {
try try
{ {
fis.close(); fis.close();
} }
catch (IOException e1) catch (IOException e1)
{ {
e1.printStackTrace(); e1.printStackTrace();
} }
} }
} }
} }
/** /**
* 删除文件 * 删除文件
* *
* @param filePath 文件 * @param filePath 文件
* @return * @return
*/ */
public static boolean deleteFile(String filePath) public static boolean deleteFile(String filePath)
{ {
boolean flag = false; boolean flag = false;
File file = new File(filePath); File file = new File(filePath);
// 路径为文件且不为空则进行删除 // 路径为文件且不为空则进行删除
if (file.isFile() && file.exists()) if (file.isFile() && file.exists())
{ {
file.delete(); file.delete();
flag = true; flag = true;
} }
return flag; return flag;
} }
/** /**
* 文件名称验证 * 文件名称验证
* *
* @param filename 文件名称 * @param filename 文件名称
* @return true 正常 false 非法 * @return true 正常 false 非法
*/ */
public static boolean isValidFilename(String filename) public static boolean isValidFilename(String filename)
{ {
return filename.matches(FILENAME_PATTERN); return filename.matches(FILENAME_PATTERN);
} }
/** /**
* 下载文件名重新编码 * 下载文件名重新编码
* *
* @param request 请求对象 * @param request 请求对象
* @param fileName 文件名 * @param fileName 文件名
* @return 编码后的文件名 * @return 编码后的文件名
*/ */
public static String setFileDownloadHeader(HttpServletRequest request, String fileName) public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
throws UnsupportedEncodingException throws UnsupportedEncodingException
{ {
final String agent = request.getHeader("USER-AGENT"); final String agent = request.getHeader("USER-AGENT");
String filename = fileName; String filename = fileName;
if (agent.contains("MSIE")) if (agent.contains("MSIE"))
{ {
// IE浏览器 // IE浏览器
filename = URLEncoder.encode(filename, "utf-8"); filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+", " "); filename = filename.replace("+", " ");
} }
else if (agent.contains("Firefox")) else if (agent.contains("Firefox"))
{ {
// 火狐浏览器 // 火狐浏览器
filename = new String(fileName.getBytes(), "ISO8859-1"); filename = new String(fileName.getBytes(), "ISO8859-1");
} }
else if (agent.contains("Chrome")) else if (agent.contains("Chrome"))
{ {
// google浏览器 // google浏览器
filename = URLEncoder.encode(filename, "utf-8"); filename = URLEncoder.encode(filename, "utf-8");
} }
else else
{ {
// 其它浏览器 // 其它浏览器
filename = URLEncoder.encode(filename, "utf-8"); filename = URLEncoder.encode(filename, "utf-8");
} }
return filename; return filename;
} }
} }

View File

@ -1,55 +1,55 @@
package com.ruoyi.common.utils.file; package com.ruoyi.common.utils.file;
/** /**
* 媒体类型工具类 * 媒体类型工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class MimeTypeUtils public class MimeTypeUtils
{ {
public static final String IMAGE_PNG = "image/png"; public static final String IMAGE_PNG = "image/png";
public static final String IMAGE_JPG = "image/jpg"; public static final String IMAGE_JPG = "image/jpg";
public static final String IMAGE_JPEG = "image/jpeg"; public static final String IMAGE_JPEG = "image/jpeg";
public static final String IMAGE_BMP = "image/bmp"; public static final String IMAGE_BMP = "image/bmp";
public static final String IMAGE_GIF = "image/gif"; public static final String IMAGE_GIF = "image/gif";
public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" }; public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
public static final String[] FLASH_EXTENSION = { "swf", "flv" }; public static final String[] FLASH_EXTENSION = { "swf", "flv" };
public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg", public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
"asf", "rm", "rmvb" }; "asf", "rm", "rmvb" };
public static final String[] DEFAULT_ALLOWED_EXTENSION = { public static final String[] DEFAULT_ALLOWED_EXTENSION = {
// 图片 // 图片
"bmp", "gif", "jpg", "jpeg", "png", "bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint // word excel powerpoint
"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
// 压缩文件 // 压缩文件
"rar", "zip", "gz", "bz2", "rar", "zip", "gz", "bz2",
// pdf // pdf
"pdf" }; "pdf" };
public static String getExtension(String prefix) public static String getExtension(String prefix)
{ {
switch (prefix) switch (prefix)
{ {
case IMAGE_PNG: case IMAGE_PNG:
return "png"; return "png";
case IMAGE_JPG: case IMAGE_JPG:
return "jpg"; return "jpg";
case IMAGE_JPEG: case IMAGE_JPEG:
return "jpeg"; return "jpeg";
case IMAGE_BMP: case IMAGE_BMP:
return "bmp"; return "bmp";
case IMAGE_GIF: case IMAGE_GIF:
return "gif"; return "gif";
default: default:
return ""; return "";
} }
} }
} }

View File

@ -1,152 +1,152 @@
package com.ruoyi.common.utils.html; package com.ruoyi.common.utils.html;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 转义和反转义工具类 * 转义和反转义工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class EscapeUtil public class EscapeUtil
{ {
public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"; public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
private static final char[][] TEXT = new char[64][]; private static final char[][] TEXT = new char[64][];
static static
{ {
for (int i = 0; i < 64; i++) for (int i = 0; i < 64; i++)
{ {
TEXT[i] = new char[] { (char) i }; TEXT[i] = new char[] { (char) i };
} }
// special HTML characters // special HTML characters
TEXT['\''] = "&#039;".toCharArray(); // 单引号 TEXT['\''] = "&#039;".toCharArray(); // 单引号
TEXT['"'] = "&#34;".toCharArray(); // 单引号 TEXT['"'] = "&#34;".toCharArray(); // 单引号
TEXT['&'] = "&#38;".toCharArray(); // &符 TEXT['&'] = "&#38;".toCharArray(); // &符
TEXT['<'] = "&#60;".toCharArray(); // 小于号 TEXT['<'] = "&#60;".toCharArray(); // 小于号
TEXT['>'] = "&#62;".toCharArray(); // 大于号 TEXT['>'] = "&#62;".toCharArray(); // 大于号
} }
/** /**
* 转义文本中的HTML字符为安全的字符 * 转义文本中的HTML字符为安全的字符
* *
* @param text 被转义的文本 * @param text 被转义的文本
* @return 转义后的文本 * @return 转义后的文本
*/ */
public static String escape(String text) public static String escape(String text)
{ {
return encode(text); return encode(text);
} }
/** /**
* 还原被转义的HTML特殊字符 * 还原被转义的HTML特殊字符
* *
* @param content 包含转义符的HTML内容 * @param content 包含转义符的HTML内容
* @return 转换后的字符串 * @return 转换后的字符串
*/ */
public static String unescape(String content) public static String unescape(String content)
{ {
return decode(content); return decode(content);
} }
/** /**
* 清除所有HTML标签但是不删除标签内的内容 * 清除所有HTML标签但是不删除标签内的内容
* *
* @param content 文本 * @param content 文本
* @return 清除标签后的文本 * @return 清除标签后的文本
*/ */
public static String clean(String content) public static String clean(String content)
{ {
return new HTMLFilter().filter(content); return new HTMLFilter().filter(content);
} }
/** /**
* Escape编码 * Escape编码
* *
* @param text 被编码的文本 * @param text 被编码的文本
* @return 编码后的字符 * @return 编码后的字符
*/ */
private static String encode(String text) private static String encode(String text)
{ {
int len; int len;
if ((text == null) || ((len = text.length()) == 0)) if ((text == null) || ((len = text.length()) == 0))
{ {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
StringBuilder buffer = new StringBuilder(len + (len >> 2)); StringBuilder buffer = new StringBuilder(len + (len >> 2));
char c; char c;
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
c = text.charAt(i); c = text.charAt(i);
if (c < 64) if (c < 64)
{ {
buffer.append(TEXT[c]); buffer.append(TEXT[c]);
} }
else else
{ {
buffer.append(c); buffer.append(c);
} }
} }
return buffer.toString(); return buffer.toString();
} }
/** /**
* Escape解码 * Escape解码
* *
* @param content 被转义的内容 * @param content 被转义的内容
* @return 解码后的字符串 * @return 解码后的字符串
*/ */
public static String decode(String content) public static String decode(String content)
{ {
if (StringUtils.isEmpty(content)) if (StringUtils.isEmpty(content))
{ {
return content; return content;
} }
StringBuilder tmp = new StringBuilder(content.length()); StringBuilder tmp = new StringBuilder(content.length());
int lastPos = 0, pos = 0; int lastPos = 0, pos = 0;
char ch; char ch;
while (lastPos < content.length()) while (lastPos < content.length())
{ {
pos = content.indexOf("%", lastPos); pos = content.indexOf("%", lastPos);
if (pos == lastPos) if (pos == lastPos)
{ {
if (content.charAt(pos + 1) == 'u') if (content.charAt(pos + 1) == 'u')
{ {
ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16); ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
tmp.append(ch); tmp.append(ch);
lastPos = pos + 6; lastPos = pos + 6;
} }
else else
{ {
ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16); ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
tmp.append(ch); tmp.append(ch);
lastPos = pos + 3; lastPos = pos + 3;
} }
} }
else else
{ {
if (pos == -1) if (pos == -1)
{ {
tmp.append(content.substring(lastPos)); tmp.append(content.substring(lastPos));
lastPos = content.length(); lastPos = content.length();
} }
else else
{ {
tmp.append(content.substring(lastPos, pos)); tmp.append(content.substring(lastPos, pos));
lastPos = pos; lastPos = pos;
} }
} }
} }
return tmp.toString(); return tmp.toString();
} }
public static void main(String[] args) public static void main(String[] args)
{ {
String html = "alert('11111');"; String html = "alert('11111');";
System.out.println(EscapeUtil.clean(html)); System.out.println(EscapeUtil.clean(html));
System.out.println(EscapeUtil.escape(html)); System.out.println(EscapeUtil.escape(html));
System.out.println(EscapeUtil.unescape(html)); System.out.println(EscapeUtil.unescape(html));
} }
} }

View File

@ -1,248 +1,248 @@
package com.ruoyi.common.utils.http; package com.ruoyi.common.utils.http;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.net.ConnectException; import java.net.ConnectException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* 通用http发送方法 * 通用http发送方法
* *
* @author ruoyi * @author ruoyi
*/ */
public class HttpUtils public class HttpUtils
{ {
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class); private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
/** /**
* 向指定 URL 发送GET方法的请求 * 向指定 URL 发送GET方法的请求
* *
* @param url 发送请求的 URL * @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果 * @return 所代表远程资源的响应结果
*/ */
public static String sendGet(String url, String param) public static String sendGet(String url, String param)
{ {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
BufferedReader in = null; BufferedReader in = null;
try try
{ {
String urlNameString = url + "?" + param; String urlNameString = url + "?" + param;
log.info("sendGet - {}", urlNameString); log.info("sendGet - {}", urlNameString);
URL realUrl = new URL(urlNameString); URL realUrl = new URL(urlNameString);
URLConnection connection = realUrl.openConnection(); URLConnection connection = realUrl.openConnection();
connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.connect(); connection.connect();
in = new BufferedReader(new InputStreamReader(connection.getInputStream())); in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line; String line;
while ((line = in.readLine()) != null) while ((line = in.readLine()) != null)
{ {
result.append(line); result.append(line);
} }
log.info("recv - {}", result); log.info("recv - {}", result);
} }
catch (ConnectException e) catch (ConnectException e)
{ {
log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
} }
catch (SocketTimeoutException e) catch (SocketTimeoutException e)
{ {
log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
} }
catch (Exception e) catch (Exception e)
{ {
log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e); log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
} }
finally finally
{ {
try try
{ {
if (in != null) if (in != null)
{ {
in.close(); in.close();
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
} }
} }
return result.toString(); return result.toString();
} }
/** /**
* 向指定 URL 发送POST方法的请求 * 向指定 URL 发送POST方法的请求
* *
* @param url 发送请求的 URL * @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果 * @return 所代表远程资源的响应结果
*/ */
public static String sendPost(String url, String param) public static String sendPost(String url, String param)
{ {
PrintWriter out = null; PrintWriter out = null;
BufferedReader in = null; BufferedReader in = null;
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
try try
{ {
String urlNameString = url + "?" + param; String urlNameString = url + "?" + param;
log.info("sendPost - {}", urlNameString); log.info("sendPost - {}", urlNameString);
URL realUrl = new URL(urlNameString); URL realUrl = new URL(urlNameString);
URLConnection conn = realUrl.openConnection(); URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8"); conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true); conn.setDoOutput(true);
conn.setDoInput(true); conn.setDoInput(true);
out = new PrintWriter(conn.getOutputStream()); out = new PrintWriter(conn.getOutputStream());
out.print(param); out.print(param);
out.flush(); out.flush();
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
String line; String line;
while ((line = in.readLine()) != null) while ((line = in.readLine()) != null)
{ {
result.append(line); result.append(line);
} }
log.info("recv - {}", result); log.info("recv - {}", result);
} }
catch (ConnectException e) catch (ConnectException e)
{ {
log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
} }
catch (SocketTimeoutException e) catch (SocketTimeoutException e)
{ {
log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
} }
catch (Exception e) catch (Exception e)
{ {
log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
} }
finally finally
{ {
try try
{ {
if (out != null) if (out != null)
{ {
out.close(); out.close();
} }
if (in != null) if (in != null)
{ {
in.close(); in.close();
} }
} }
catch (IOException ex) catch (IOException ex)
{ {
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
} }
} }
return result.toString(); return result.toString();
} }
public static String sendSSLPost(String url, String param) public static String sendSSLPost(String url, String param)
{ {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
String urlNameString = url + "?" + param; String urlNameString = url + "?" + param;
try try
{ {
log.info("sendSSLPost - {}", urlNameString); log.info("sendSSLPost - {}", urlNameString);
SSLContext sc = SSLContext.getInstance("SSL"); SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
URL console = new URL(urlNameString); URL console = new URL(urlNameString);
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8"); conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true); conn.setDoOutput(true);
conn.setDoInput(true); conn.setDoInput(true);
conn.setSSLSocketFactory(sc.getSocketFactory()); conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier()); conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.connect(); conn.connect();
InputStream is = conn.getInputStream(); InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is)); BufferedReader br = new BufferedReader(new InputStreamReader(is));
String ret = ""; String ret = "";
while ((ret = br.readLine()) != null) while ((ret = br.readLine()) != null)
{ {
if (ret != null && !ret.trim().equals("")) if (ret != null && !ret.trim().equals(""))
{ {
result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8")); result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
} }
} }
log.info("recv - {}", result); log.info("recv - {}", result);
conn.disconnect(); conn.disconnect();
br.close(); br.close();
} }
catch (ConnectException e) catch (ConnectException e)
{ {
log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
} }
catch (SocketTimeoutException e) catch (SocketTimeoutException e)
{ {
log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
} }
catch (IOException e) catch (IOException e)
{ {
log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e); log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
} }
catch (Exception e) catch (Exception e)
{ {
log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e); log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
} }
return result.toString(); return result.toString();
} }
private static class TrustAnyTrustManager implements X509TrustManager private static class TrustAnyTrustManager implements X509TrustManager
{ {
@Override @Override
public void checkClientTrusted(X509Certificate[] chain, String authType) public void checkClientTrusted(X509Certificate[] chain, String authType)
{ {
} }
@Override @Override
public void checkServerTrusted(X509Certificate[] chain, String authType) public void checkServerTrusted(X509Certificate[] chain, String authType)
{ {
} }
@Override @Override
public X509Certificate[] getAcceptedIssuers() public X509Certificate[] getAcceptedIssuers()
{ {
return new X509Certificate[] {}; return new X509Certificate[] {};
} }
} }
private static class TrustAnyHostnameVerifier implements HostnameVerifier private static class TrustAnyHostnameVerifier implements HostnameVerifier
{ {
@Override @Override
public boolean verify(String hostname, SSLSession session) public boolean verify(String hostname, SSLSession session)
{ {
return true; return true;
} }
} }
} }

View File

@ -1,45 +1,45 @@
package com.ruoyi.common.utils.ip; package com.ruoyi.common.utils.ip;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.framework.config.RuoYiConfig; import com.ruoyi.framework.config.RuoYiConfig;
/** /**
* 获取地址类 * 获取地址类
* *
* @author ruoyi * @author ruoyi
*/ */
public class AddressUtils public class AddressUtils
{ {
private static final Logger log = LoggerFactory.getLogger(AddressUtils.class); private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
public static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php"; public static final String IP_URL = "http://ip.taobao.com/service/getIpInfo.php";
public static String getRealAddressByIP(String ip) public static String getRealAddressByIP(String ip)
{ {
String address = "XX XX"; String address = "XX XX";
// 内网不查询 // 内网不查询
if (IpUtils.internalIp(ip)) if (IpUtils.internalIp(ip))
{ {
return "内网IP"; return "内网IP";
} }
if (RuoYiConfig.isAddressEnabled()) if (RuoYiConfig.isAddressEnabled())
{ {
String rspStr = HttpUtils.sendPost(IP_URL, "ip=" + ip); String rspStr = HttpUtils.sendPost(IP_URL, "ip=" + ip);
if (StringUtils.isEmpty(rspStr)) if (StringUtils.isEmpty(rspStr))
{ {
log.error("获取地理位置异常 {}", ip); log.error("获取地理位置异常 {}", ip);
return address; return address;
} }
JSONObject obj = JSONObject.parseObject(rspStr); JSONObject obj = JSONObject.parseObject(rspStr);
JSONObject data = obj.getObject("data", JSONObject.class); JSONObject data = obj.getObject("data", JSONObject.class);
String region = data.getString("region"); String region = data.getString("region");
String city = data.getString("city"); String city = data.getString("city");
address = region + " " + city; address = region + " " + city;
} }
return address; return address;
} }
} }

View File

@ -1,189 +1,189 @@
package com.ruoyi.common.utils.ip; package com.ruoyi.common.utils.ip;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 获取IP方法 * 获取IP方法
* *
* @author ruoyi * @author ruoyi
*/ */
public class IpUtils public class IpUtils
{ {
public static String getIpAddr(HttpServletRequest request) public static String getIpAddr(HttpServletRequest request)
{ {
if (request == null) if (request == null)
{ {
return "unknown"; return "unknown";
} }
String ip = request.getHeader("x-forwarded-for"); String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
ip = request.getHeader("Proxy-Client-IP"); ip = request.getHeader("Proxy-Client-IP");
} }
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
ip = request.getHeader("X-Forwarded-For"); ip = request.getHeader("X-Forwarded-For");
} }
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
ip = request.getHeader("WL-Proxy-Client-IP"); ip = request.getHeader("WL-Proxy-Client-IP");
} }
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
ip = request.getHeader("X-Real-IP"); ip = request.getHeader("X-Real-IP");
} }
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{ {
ip = request.getRemoteAddr(); ip = request.getRemoteAddr();
} }
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
} }
public static boolean internalIp(String ip) public static boolean internalIp(String ip)
{ {
byte[] addr = textToNumericFormatV4(ip); byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip); return internalIp(addr) || "127.0.0.1".equals(ip);
} }
private static boolean internalIp(byte[] addr) private static boolean internalIp(byte[] addr)
{ {
if (StringUtils.isNull(addr) || addr.length < 2) if (StringUtils.isNull(addr) || addr.length < 2)
{ {
return true; return true;
} }
final byte b0 = addr[0]; final byte b0 = addr[0];
final byte b1 = addr[1]; final byte b1 = addr[1];
// 10.x.x.x/8 // 10.x.x.x/8
final byte SECTION_1 = 0x0A; final byte SECTION_1 = 0x0A;
// 172.16.x.x/12 // 172.16.x.x/12
final byte SECTION_2 = (byte) 0xAC; final byte SECTION_2 = (byte) 0xAC;
final byte SECTION_3 = (byte) 0x10; final byte SECTION_3 = (byte) 0x10;
final byte SECTION_4 = (byte) 0x1F; final byte SECTION_4 = (byte) 0x1F;
// 192.168.x.x/16 // 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0; final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8; final byte SECTION_6 = (byte) 0xA8;
switch (b0) switch (b0)
{ {
case SECTION_1: case SECTION_1:
return true; return true;
case SECTION_2: case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4) if (b1 >= SECTION_3 && b1 <= SECTION_4)
{ {
return true; return true;
} }
case SECTION_5: case SECTION_5:
switch (b1) switch (b1)
{ {
case SECTION_6: case SECTION_6:
return true; return true;
} }
default: default:
return false; return false;
} }
} }
/** /**
* 将IPv4地址转换成字节 * 将IPv4地址转换成字节
* *
* @param text IPv4地址 * @param text IPv4地址
* @return byte 字节 * @return byte 字节
*/ */
public static byte[] textToNumericFormatV4(String text) public static byte[] textToNumericFormatV4(String text)
{ {
if (text.length() == 0) if (text.length() == 0)
{ {
return null; return null;
} }
byte[] bytes = new byte[4]; byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1); String[] elements = text.split("\\.", -1);
try try
{ {
long l; long l;
int i; int i;
switch (elements.length) switch (elements.length)
{ {
case 1: case 1:
l = Long.parseLong(elements[0]); l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L)) if ((l < 0L) || (l > 4294967295L))
return null; return null;
bytes[0] = (byte) (int) (l >> 24 & 0xFF); bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF); bytes[3] = (byte) (int) (l & 0xFF);
break; break;
case 2: case 2:
l = Integer.parseInt(elements[0]); l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L)) if ((l < 0L) || (l > 255L))
return null; return null;
bytes[0] = (byte) (int) (l & 0xFF); bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]); l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L)) if ((l < 0L) || (l > 16777215L))
return null; return null;
bytes[1] = (byte) (int) (l >> 16 & 0xFF); bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF); bytes[3] = (byte) (int) (l & 0xFF);
break; break;
case 3: case 3:
for (i = 0; i < 2; ++i) for (i = 0; i < 2; ++i)
{ {
l = Integer.parseInt(elements[i]); l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)) if ((l < 0L) || (l > 255L))
return null; return null;
bytes[i] = (byte) (int) (l & 0xFF); bytes[i] = (byte) (int) (l & 0xFF);
} }
l = Integer.parseInt(elements[2]); l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L)) if ((l < 0L) || (l > 65535L))
return null; return null;
bytes[2] = (byte) (int) (l >> 8 & 0xFF); bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF); bytes[3] = (byte) (int) (l & 0xFF);
break; break;
case 4: case 4:
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
{ {
l = Integer.parseInt(elements[i]); l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)) if ((l < 0L) || (l > 255L))
return null; return null;
bytes[i] = (byte) (int) (l & 0xFF); bytes[i] = (byte) (int) (l & 0xFF);
} }
break; break;
default: default:
return null; return null;
} }
} }
catch (NumberFormatException e) catch (NumberFormatException e)
{ {
return null; return null;
} }
return bytes; return bytes;
} }
public static String getHostIp() public static String getHostIp()
{ {
try try
{ {
return InetAddress.getLocalHost().getHostAddress(); return InetAddress.getLocalHost().getHostAddress();
} }
catch (UnknownHostException e) catch (UnknownHostException e)
{ {
} }
return "127.0.0.1"; return "127.0.0.1";
} }
public static String getHostName() public static String getHostName()
{ {
try try
{ {
return InetAddress.getLocalHost().getHostName(); return InetAddress.getLocalHost().getHostName();
} }
catch (UnknownHostException e) catch (UnknownHostException e)
{ {
} }
return "未知"; return "未知";
} }
} }

View File

@ -1,66 +1,66 @@
package com.ruoyi.common.utils.security; package com.ruoyi.common.utils.security;
import java.security.MessageDigest; import java.security.MessageDigest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* Md5加密方法 * Md5加密方法
* *
* @author ruoyi * @author ruoyi
*/ */
public class Md5Utils public class Md5Utils
{ {
private static final Logger log = LoggerFactory.getLogger(Md5Utils.class); private static final Logger log = LoggerFactory.getLogger(Md5Utils.class);
private static byte[] md5(String s) private static byte[] md5(String s)
{ {
MessageDigest algorithm; MessageDigest algorithm;
try try
{ {
algorithm = MessageDigest.getInstance("MD5"); algorithm = MessageDigest.getInstance("MD5");
algorithm.reset(); algorithm.reset();
algorithm.update(s.getBytes("UTF-8")); algorithm.update(s.getBytes("UTF-8"));
byte[] messageDigest = algorithm.digest(); byte[] messageDigest = algorithm.digest();
return messageDigest; return messageDigest;
} }
catch (Exception e) catch (Exception e)
{ {
log.error("MD5 Error...", e); log.error("MD5 Error...", e);
} }
return null; return null;
} }
private static final String toHex(byte hash[]) private static final String toHex(byte hash[])
{ {
if (hash == null) if (hash == null)
{ {
return null; return null;
} }
StringBuffer buf = new StringBuffer(hash.length * 2); StringBuffer buf = new StringBuffer(hash.length * 2);
int i; int i;
for (i = 0; i < hash.length; i++) for (i = 0; i < hash.length; i++)
{ {
if ((hash[i] & 0xff) < 0x10) if ((hash[i] & 0xff) < 0x10)
{ {
buf.append("0"); buf.append("0");
} }
buf.append(Long.toString(hash[i] & 0xff, 16)); buf.append(Long.toString(hash[i] & 0xff, 16));
} }
return buf.toString(); return buf.toString();
} }
public static String hash(String s) public static String hash(String s)
{ {
try try
{ {
return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8"); return new String(toHex(md5(s)).getBytes("UTF-8"), "UTF-8");
} }
catch (Exception e) catch (Exception e)
{ {
log.error("not supported charset...{}", e); log.error("not supported charset...{}", e);
return s; return s;
} }
} }
} }

View File

@ -1,291 +1,291 @@
package com.ruoyi.common.utils.sign; package com.ruoyi.common.utils.sign;
/** /**
* Base64工具类 * Base64工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public final class Base64 public final class Base64
{ {
static private final int BASELENGTH = 128; static private final int BASELENGTH = 128;
static private final int LOOKUPLENGTH = 64; static private final int LOOKUPLENGTH = 64;
static private final int TWENTYFOURBITGROUP = 24; static private final int TWENTYFOURBITGROUP = 24;
static private final int EIGHTBIT = 8; static private final int EIGHTBIT = 8;
static private final int SIXTEENBIT = 16; static private final int SIXTEENBIT = 16;
static private final int FOURBYTE = 4; static private final int FOURBYTE = 4;
static private final int SIGN = -128; static private final int SIGN = -128;
static private final char PAD = '='; static private final char PAD = '=';
static final private byte[] base64Alphabet = new byte[BASELENGTH]; static final private byte[] base64Alphabet = new byte[BASELENGTH];
static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
static static
{ {
for (int i = 0; i < BASELENGTH; ++i) for (int i = 0; i < BASELENGTH; ++i)
{ {
base64Alphabet[i] = -1; base64Alphabet[i] = -1;
} }
for (int i = 'Z'; i >= 'A'; i--) for (int i = 'Z'; i >= 'A'; i--)
{ {
base64Alphabet[i] = (byte) (i - 'A'); base64Alphabet[i] = (byte) (i - 'A');
} }
for (int i = 'z'; i >= 'a'; i--) for (int i = 'z'; i >= 'a'; i--)
{ {
base64Alphabet[i] = (byte) (i - 'a' + 26); base64Alphabet[i] = (byte) (i - 'a' + 26);
} }
for (int i = '9'; i >= '0'; i--) for (int i = '9'; i >= '0'; i--)
{ {
base64Alphabet[i] = (byte) (i - '0' + 52); base64Alphabet[i] = (byte) (i - '0' + 52);
} }
base64Alphabet['+'] = 62; base64Alphabet['+'] = 62;
base64Alphabet['/'] = 63; base64Alphabet['/'] = 63;
for (int i = 0; i <= 25; i++) for (int i = 0; i <= 25; i++)
{ {
lookUpBase64Alphabet[i] = (char) ('A' + i); lookUpBase64Alphabet[i] = (char) ('A' + i);
} }
for (int i = 26, j = 0; i <= 51; i++, j++) for (int i = 26, j = 0; i <= 51; i++, j++)
{ {
lookUpBase64Alphabet[i] = (char) ('a' + j); lookUpBase64Alphabet[i] = (char) ('a' + j);
} }
for (int i = 52, j = 0; i <= 61; i++, j++) for (int i = 52, j = 0; i <= 61; i++, j++)
{ {
lookUpBase64Alphabet[i] = (char) ('0' + j); lookUpBase64Alphabet[i] = (char) ('0' + j);
} }
lookUpBase64Alphabet[62] = (char) '+'; lookUpBase64Alphabet[62] = (char) '+';
lookUpBase64Alphabet[63] = (char) '/'; lookUpBase64Alphabet[63] = (char) '/';
} }
private static boolean isWhiteSpace(char octect) private static boolean isWhiteSpace(char octect)
{ {
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
} }
private static boolean isPad(char octect) private static boolean isPad(char octect)
{ {
return (octect == PAD); return (octect == PAD);
} }
private static boolean isData(char octect) private static boolean isData(char octect)
{ {
return (octect < BASELENGTH && base64Alphabet[octect] != -1); return (octect < BASELENGTH && base64Alphabet[octect] != -1);
} }
/** /**
* Encodes hex octects into Base64 * Encodes hex octects into Base64
* *
* @param binaryData Array containing binaryData * @param binaryData Array containing binaryData
* @return Encoded Base64 array * @return Encoded Base64 array
*/ */
public static String encode(byte[] binaryData) public static String encode(byte[] binaryData)
{ {
if (binaryData == null) if (binaryData == null)
{ {
return null; return null;
} }
int lengthDataBits = binaryData.length * EIGHTBIT; int lengthDataBits = binaryData.length * EIGHTBIT;
if (lengthDataBits == 0) if (lengthDataBits == 0)
{ {
return ""; return "";
} }
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets; int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
char encodedData[] = null; char encodedData[] = null;
encodedData = new char[numberQuartet * 4]; encodedData = new char[numberQuartet * 4];
byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
int encodedIndex = 0; int encodedIndex = 0;
int dataIndex = 0; int dataIndex = 0;
for (int i = 0; i < numberTriplets; i++) for (int i = 0; i < numberTriplets; i++)
{ {
b1 = binaryData[dataIndex++]; b1 = binaryData[dataIndex++];
b2 = binaryData[dataIndex++]; b2 = binaryData[dataIndex++];
b3 = binaryData[dataIndex++]; b3 = binaryData[dataIndex++];
l = (byte) (b2 & 0x0f); l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03); k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3]; encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f]; encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
} }
// form integral number of 6-bit groups // form integral number of 6-bit groups
if (fewerThan24bits == EIGHTBIT) if (fewerThan24bits == EIGHTBIT)
{ {
b1 = binaryData[dataIndex]; b1 = binaryData[dataIndex];
k = (byte) (b1 & 0x03); k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4]; encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
encodedData[encodedIndex++] = PAD; encodedData[encodedIndex++] = PAD;
encodedData[encodedIndex++] = PAD; encodedData[encodedIndex++] = PAD;
} }
else if (fewerThan24bits == SIXTEENBIT) else if (fewerThan24bits == SIXTEENBIT)
{ {
b1 = binaryData[dataIndex]; b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1]; b2 = binaryData[dataIndex + 1];
l = (byte) (b2 & 0x0f); l = (byte) (b2 & 0x0f);
k = (byte) (b1 & 0x03); k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
encodedData[encodedIndex++] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)]; encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2]; encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
encodedData[encodedIndex++] = PAD; encodedData[encodedIndex++] = PAD;
} }
return new String(encodedData); return new String(encodedData);
} }
/** /**
* Decodes Base64 data into octects * Decodes Base64 data into octects
* *
* @param encoded string containing Base64 data * @param encoded string containing Base64 data
* @return Array containind decoded data. * @return Array containind decoded data.
*/ */
public static byte[] decode(String encoded) public static byte[] decode(String encoded)
{ {
if (encoded == null) if (encoded == null)
{ {
return null; return null;
} }
char[] base64Data = encoded.toCharArray(); char[] base64Data = encoded.toCharArray();
// remove white spaces // remove white spaces
int len = removeWhiteSpace(base64Data); int len = removeWhiteSpace(base64Data);
if (len % FOURBYTE != 0) if (len % FOURBYTE != 0)
{ {
return null;// should be divisible by four return null;// should be divisible by four
} }
int numberQuadruple = (len / FOURBYTE); int numberQuadruple = (len / FOURBYTE);
if (numberQuadruple == 0) if (numberQuadruple == 0)
{ {
return new byte[0]; return new byte[0];
} }
byte decodedData[] = null; byte decodedData[] = null;
byte b1 = 0, b2 = 0, b3 = 0, b4 = 0; byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
char d1 = 0, d2 = 0, d3 = 0, d4 = 0; char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
int i = 0; int i = 0;
int encodedIndex = 0; int encodedIndex = 0;
int dataIndex = 0; int dataIndex = 0;
decodedData = new byte[(numberQuadruple) * 3]; decodedData = new byte[(numberQuadruple) * 3];
for (; i < numberQuadruple - 1; i++) for (; i < numberQuadruple - 1; i++)
{ {
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])) if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
|| !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) || !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++])))
{ {
return null; return null;
} // if found "no data" just return null } // if found "no data" just return null
b1 = base64Alphabet[d1]; b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2]; b2 = base64Alphabet[d2];
b3 = base64Alphabet[d3]; b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4]; b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
} }
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])))
{ {
return null;// if found "no data" just return null return null;// if found "no data" just return null
} }
b1 = base64Alphabet[d1]; b1 = base64Alphabet[d1];
b2 = base64Alphabet[d2]; b2 = base64Alphabet[d2];
d3 = base64Data[dataIndex++]; d3 = base64Data[dataIndex++];
d4 = base64Data[dataIndex++]; d4 = base64Data[dataIndex++];
if (!isData((d3)) || !isData((d4))) if (!isData((d3)) || !isData((d4)))
{// Check if they are PAD characters {// Check if they are PAD characters
if (isPad(d3) && isPad(d4)) if (isPad(d3) && isPad(d4))
{ {
if ((b2 & 0xf) != 0)// last 4 bits should be zero if ((b2 & 0xf) != 0)// last 4 bits should be zero
{ {
return null; return null;
} }
byte[] tmp = new byte[i * 3 + 1]; byte[] tmp = new byte[i * 3 + 1];
System.arraycopy(decodedData, 0, tmp, 0, i * 3); System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
return tmp; return tmp;
} }
else if (!isPad(d3) && isPad(d4)) else if (!isPad(d3) && isPad(d4))
{ {
b3 = base64Alphabet[d3]; b3 = base64Alphabet[d3];
if ((b3 & 0x3) != 0)// last 2 bits should be zero if ((b3 & 0x3) != 0)// last 2 bits should be zero
{ {
return null; return null;
} }
byte[] tmp = new byte[i * 3 + 2]; byte[] tmp = new byte[i * 3 + 2];
System.arraycopy(decodedData, 0, tmp, 0, i * 3); System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
return tmp; return tmp;
} }
else else
{ {
return null; return null;
} }
} }
else else
{ // No PAD e.g 3cQl { // No PAD e.g 3cQl
b3 = base64Alphabet[d3]; b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4]; b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4); decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
} }
return decodedData; return decodedData;
} }
/** /**
* remove WhiteSpace from MIME containing encoded Base64 data. * remove WhiteSpace from MIME containing encoded Base64 data.
* *
* @param data the byte array of base64 data (with WS) * @param data the byte array of base64 data (with WS)
* @return the new length * @return the new length
*/ */
private static int removeWhiteSpace(char[] data) private static int removeWhiteSpace(char[] data)
{ {
if (data == null) if (data == null)
{ {
return 0; return 0;
} }
// count characters that's not whitespace // count characters that's not whitespace
int newSize = 0; int newSize = 0;
int len = data.length; int len = data.length;
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
if (!isWhiteSpace(data[i])) if (!isWhiteSpace(data[i]))
{ {
data[newSize++] = data[i]; data[newSize++] = data[i];
} }
} }
return newSize; return newSize;
} }
} }

View File

@ -1,114 +1,114 @@
package com.ruoyi.common.utils.spring; package com.ruoyi.common.utils.spring;
import org.springframework.aop.framework.AopContext; import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* spring工具类 方便在非spring管理环境中获取bean * spring工具类 方便在非spring管理环境中获取bean
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public final class SpringUtils implements BeanFactoryPostProcessor public final class SpringUtils implements BeanFactoryPostProcessor
{ {
/** Spring应用上下文环境 */ /** Spring应用上下文环境 */
private static ConfigurableListableBeanFactory beanFactory; private static ConfigurableListableBeanFactory beanFactory;
@Override @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
{ {
SpringUtils.beanFactory = beanFactory; SpringUtils.beanFactory = beanFactory;
} }
/** /**
* 获取对象 * 获取对象
* *
* @param name * @param name
* @return Object 一个以所给名字注册的bean的实例 * @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException * @throws org.springframework.beans.BeansException
* *
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException public static <T> T getBean(String name) throws BeansException
{ {
return (T) beanFactory.getBean(name); return (T) beanFactory.getBean(name);
} }
/** /**
* 获取类型为requiredType的对象 * 获取类型为requiredType的对象
* *
* @param clz * @param clz
* @return * @return
* @throws org.springframework.beans.BeansException * @throws org.springframework.beans.BeansException
* *
*/ */
public static <T> T getBean(Class<T> clz) throws BeansException public static <T> T getBean(Class<T> clz) throws BeansException
{ {
T result = (T) beanFactory.getBean(clz); T result = (T) beanFactory.getBean(clz);
return result; return result;
} }
/** /**
* 如果BeanFactory包含一个与所给名称匹配的bean定义则返回true * 如果BeanFactory包含一个与所给名称匹配的bean定义则返回true
* *
* @param name * @param name
* @return boolean * @return boolean
*/ */
public static boolean containsBean(String name) public static boolean containsBean(String name)
{ {
return beanFactory.containsBean(name); return beanFactory.containsBean(name);
} }
/** /**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到将会抛出一个异常NoSuchBeanDefinitionException * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到将会抛出一个异常NoSuchBeanDefinitionException
* *
* @param name * @param name
* @return boolean * @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
* *
*/ */
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
{ {
return beanFactory.isSingleton(name); return beanFactory.isSingleton(name);
} }
/** /**
* @param name * @param name
* @return Class 注册对象的类型 * @return Class 注册对象的类型
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
* *
*/ */
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
{ {
return beanFactory.getType(name); return beanFactory.getType(name);
} }
/** /**
* 如果给定的bean名字在bean定义中有别名则返回这些别名 * 如果给定的bean名字在bean定义中有别名则返回这些别名
* *
* @param name * @param name
* @return * @return
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
* *
*/ */
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
{ {
return beanFactory.getAliases(name); return beanFactory.getAliases(name);
} }
/** /**
* 获取aop代理对象 * 获取aop代理对象
* *
* @param invoker * @param invoker
* @return * @return
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T getAopProxy(T invoker) public static <T> T getAopProxy(T invoker)
{ {
return (T) AopContext.currentProxy(); return (T) AopContext.currentProxy();
} }
} }

View File

@ -1,36 +1,36 @@
package com.ruoyi.common.utils.sql; package com.ruoyi.common.utils.sql;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* sql操作工具类 * sql操作工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class SqlUtil public class SqlUtil
{ {
/** /**
* 仅支持字母、数字、下划线、空格、逗号(支持多个字段排序) * 仅支持字母、数字、下划线、空格、逗号(支持多个字段排序)
*/ */
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+"; public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+";
/** /**
* 检查字符,防止注入绕过 * 检查字符,防止注入绕过
*/ */
public static String escapeOrderBySql(String value) public static String escapeOrderBySql(String value)
{ {
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
{ {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
return value; return value;
} }
/** /**
* 验证 order by 语法是否符合规范 * 验证 order by 语法是否符合规范
*/ */
public static boolean isValidOrderBySql(String value) public static boolean isValidOrderBySql(String value)
{ {
return value.matches(SQL_PATTERN); return value.matches(SQL_PATTERN);
} }
} }

View File

@ -1,160 +1,160 @@
package com.ruoyi.framework.aspectj; package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature; import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.aspectj.lang.annotation.DataScope; import com.ruoyi.framework.aspectj.lang.annotation.DataScope;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.security.service.TokenService; import com.ruoyi.framework.security.service.TokenService;
import com.ruoyi.framework.web.domain.BaseEntity; import com.ruoyi.framework.web.domain.BaseEntity;
import com.ruoyi.project.system.domain.SysRole; import com.ruoyi.project.system.domain.SysRole;
import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.domain.SysUser;
/** /**
* 数据过滤处理 * 数据过滤处理
* *
* @author ruoyi * @author ruoyi
*/ */
@Aspect @Aspect
@Component @Component
public class DataScopeAspect public class DataScopeAspect
{ {
/** /**
* 全部数据权限 * 全部数据权限
*/ */
public static final String DATA_SCOPE_ALL = "1"; public static final String DATA_SCOPE_ALL = "1";
/** /**
* 自定数据权限 * 自定数据权限
*/ */
public static final String DATA_SCOPE_CUSTOM = "2"; public static final String DATA_SCOPE_CUSTOM = "2";
/** /**
* 部门数据权限 * 部门数据权限
*/ */
public static final String DATA_SCOPE_DEPT = "3"; public static final String DATA_SCOPE_DEPT = "3";
/** /**
* 部门及以下数据权限 * 部门及以下数据权限
*/ */
public static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
/** /**
* 仅本人数据权限 * 仅本人数据权限
*/ */
public static final String DATA_SCOPE_SELF = "5"; public static final String DATA_SCOPE_SELF = "5";
// 配置织入点 // 配置织入点
@Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataScope)") @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataScope)")
public void dataScopePointCut() public void dataScopePointCut()
{ {
} }
@Before("dataScopePointCut()") @Before("dataScopePointCut()")
public void doBefore(JoinPoint point) throws Throwable public void doBefore(JoinPoint point) throws Throwable
{ {
handleDataScope(point); handleDataScope(point);
} }
protected void handleDataScope(final JoinPoint joinPoint) protected void handleDataScope(final JoinPoint joinPoint)
{ {
// 获得注解 // 获得注解
DataScope controllerDataScope = getAnnotationLog(joinPoint); DataScope controllerDataScope = getAnnotationLog(joinPoint);
if (controllerDataScope == null) if (controllerDataScope == null)
{ {
return; return;
} }
// 获取当前的用户 // 获取当前的用户
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
SysUser currentUser = loginUser.getUser(); SysUser currentUser = loginUser.getUser();
if (currentUser != null) if (currentUser != null)
{ {
// 如果是超级管理员,则不过滤数据 // 如果是超级管理员,则不过滤数据
if (!currentUser.isAdmin()) if (!currentUser.isAdmin())
{ {
dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
controllerDataScope.userAlias()); controllerDataScope.userAlias());
} }
} }
} }
/** /**
* 数据范围过滤 * 数据范围过滤
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param user 用户 * @param user 用户
* @param alias 别名 * @param alias 别名
*/ */
public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias) public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
{ {
StringBuilder sqlString = new StringBuilder(); StringBuilder sqlString = new StringBuilder();
for (SysRole role : user.getRoles()) for (SysRole role : user.getRoles())
{ {
String dataScope = role.getDataScope(); String dataScope = role.getDataScope();
if (DATA_SCOPE_ALL.equals(dataScope)) if (DATA_SCOPE_ALL.equals(dataScope))
{ {
sqlString = new StringBuilder(); sqlString = new StringBuilder();
break; break;
} }
else if (DATA_SCOPE_CUSTOM.equals(dataScope)) else if (DATA_SCOPE_CUSTOM.equals(dataScope))
{ {
sqlString.append(StringUtils.format( sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
role.getRoleId())); role.getRoleId()));
} }
else if (DATA_SCOPE_DEPT.equals(dataScope)) else if (DATA_SCOPE_DEPT.equals(dataScope))
{ {
sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId())); sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
} }
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
{ {
sqlString.append(StringUtils.format( sqlString.append(StringUtils.format(
" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
deptAlias, user.getDeptId(), user.getDeptId())); deptAlias, user.getDeptId(), user.getDeptId()));
} }
else if (DATA_SCOPE_SELF.equals(dataScope)) else if (DATA_SCOPE_SELF.equals(dataScope))
{ {
if (StringUtils.isNotBlank(userAlias)) if (StringUtils.isNotBlank(userAlias))
{ {
sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId())); sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
} }
else else
{ {
// 数据权限为仅本人且没有userAlias别名不查询任何数据 // 数据权限为仅本人且没有userAlias别名不查询任何数据
sqlString.append(" OR 1=0 "); sqlString.append(" OR 1=0 ");
} }
} }
} }
if (StringUtils.isNotBlank(sqlString.toString())) if (StringUtils.isNotBlank(sqlString.toString()))
{ {
BaseEntity baseEntity = (BaseEntity) joinPoint.getArgs()[0]; BaseEntity baseEntity = (BaseEntity) joinPoint.getArgs()[0];
baseEntity.setDataScope(" AND (" + sqlString.substring(4) + ")"); baseEntity.setDataScope(" AND (" + sqlString.substring(4) + ")");
} }
} }
/** /**
* 是否存在注解,如果存在就获取 * 是否存在注解,如果存在就获取
*/ */
private DataScope getAnnotationLog(JoinPoint joinPoint) private DataScope getAnnotationLog(JoinPoint joinPoint)
{ {
Signature signature = joinPoint.getSignature(); Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature; MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod(); Method method = methodSignature.getMethod();
if (method != null) if (method != null)
{ {
return method.getAnnotation(DataScope.class); return method.getAnnotation(DataScope.class);
} }
return null; return null;
} }
} }

View File

@ -1,76 +1,76 @@
package com.ruoyi.framework.aspectj; package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.aspectj.lang.annotation.DataSource; import com.ruoyi.framework.aspectj.lang.annotation.DataSource;
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder; import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;
/** /**
* 多数据源处理 * 多数据源处理
* *
* @author ruoyi * @author ruoyi
*/ */
@Aspect @Aspect
@Order(1) @Order(1)
@Component @Component
public class DataSourceAspect public class DataSourceAspect
{ {
protected Logger logger = LoggerFactory.getLogger(getClass()); protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataSource)" @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.DataSource)"
+ "|| @within(com.ruoyi.framework.aspectj.lang.annotation.DataSource)") + "|| @within(com.ruoyi.framework.aspectj.lang.annotation.DataSource)")
public void dsPointCut() public void dsPointCut()
{ {
} }
@Around("dsPointCut()") @Around("dsPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable public Object around(ProceedingJoinPoint point) throws Throwable
{ {
DataSource dataSource = getDataSource(point); DataSource dataSource = getDataSource(point);
if (StringUtils.isNotNull(dataSource)) if (StringUtils.isNotNull(dataSource))
{ {
DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
} }
try try
{ {
return point.proceed(); return point.proceed();
} }
finally finally
{ {
// 销毁数据源 在执行方法之后 // 销毁数据源 在执行方法之后
DynamicDataSourceContextHolder.clearDataSourceType(); DynamicDataSourceContextHolder.clearDataSourceType();
} }
} }
/** /**
* 获取需要切换的数据源 * 获取需要切换的数据源
*/ */
public DataSource getDataSource(ProceedingJoinPoint point) public DataSource getDataSource(ProceedingJoinPoint point)
{ {
MethodSignature signature = (MethodSignature) point.getSignature(); MethodSignature signature = (MethodSignature) point.getSignature();
Class<? extends Object> targetClass = point.getTarget().getClass(); Class<? extends Object> targetClass = point.getTarget().getClass();
DataSource targetDataSource = targetClass.getAnnotation(DataSource.class); DataSource targetDataSource = targetClass.getAnnotation(DataSource.class);
if (StringUtils.isNotNull(targetDataSource)) if (StringUtils.isNotNull(targetDataSource))
{ {
return targetDataSource; return targetDataSource;
} }
else else
{ {
Method method = signature.getMethod(); Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class); DataSource dataSource = method.getAnnotation(DataSource.class);
return dataSource; return dataSource;
} }
} }
} }

View File

@ -1,217 +1,217 @@
package com.ruoyi.framework.aspectj; package com.ruoyi.framework.aspectj;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature; import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature; import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.HandlerMapping;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.ruoyi.common.enums.HttpMethod; import com.ruoyi.common.enums.HttpMethod;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessStatus; import com.ruoyi.framework.aspectj.lang.enums.BusinessStatus;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.security.service.TokenService; import com.ruoyi.framework.security.service.TokenService;
import com.ruoyi.project.monitor.domain.SysOperLog; import com.ruoyi.project.monitor.domain.SysOperLog;
/** /**
* 操作日志记录处理 * 操作日志记录处理
* *
* @author ruoyi * @author ruoyi
*/ */
@Aspect @Aspect
@Component @Component
public class LogAspect public class LogAspect
{ {
private static final Logger log = LoggerFactory.getLogger(LogAspect.class); private static final Logger log = LoggerFactory.getLogger(LogAspect.class);
// 配置织入点 // 配置织入点
@Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Log)") @Pointcut("@annotation(com.ruoyi.framework.aspectj.lang.annotation.Log)")
public void logPointCut() public void logPointCut()
{ {
} }
/** /**
* 处理完请求后执行 * 处理完请求后执行
* *
* @param joinPoint 切点 * @param joinPoint 切点
*/ */
@AfterReturning(pointcut = "logPointCut()", returning = "jsonResult") @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
{ {
handleLog(joinPoint, null, jsonResult); handleLog(joinPoint, null, jsonResult);
} }
/** /**
* 拦截异常操作 * 拦截异常操作
* *
* @param joinPoint 切点 * @param joinPoint 切点
* @param e 异常 * @param e 异常
*/ */
@AfterThrowing(value = "logPointCut()", throwing = "e") @AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Exception e) public void doAfterThrowing(JoinPoint joinPoint, Exception e)
{ {
handleLog(joinPoint, e, null); handleLog(joinPoint, e, null);
} }
protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)
{ {
try try
{ {
// 获得注解 // 获得注解
Log controllerLog = getAnnotationLog(joinPoint); Log controllerLog = getAnnotationLog(joinPoint);
if (controllerLog == null) if (controllerLog == null)
{ {
return; return;
} }
// 获取当前的用户 // 获取当前的用户
LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest()); LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
// *========数据库日志=========*// // *========数据库日志=========*//
SysOperLog operLog = new SysOperLog(); SysOperLog operLog = new SysOperLog();
operLog.setStatus(BusinessStatus.SUCCESS.ordinal()); operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
// 请求的地址 // 请求的地址
String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
operLog.setOperIp(ip); operLog.setOperIp(ip);
// 返回参数 // 返回参数
operLog.setJsonResult(JSON.toJSONString(jsonResult)); operLog.setJsonResult(JSON.toJSONString(jsonResult));
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
if (loginUser != null) if (loginUser != null)
{ {
operLog.setOperName(loginUser.getUsername()); operLog.setOperName(loginUser.getUsername());
} }
if (e != null) if (e != null)
{ {
operLog.setStatus(BusinessStatus.FAIL.ordinal()); operLog.setStatus(BusinessStatus.FAIL.ordinal());
operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000)); operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
} }
// 设置方法名称 // 设置方法名称
String className = joinPoint.getTarget().getClass().getName(); String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName(); String methodName = joinPoint.getSignature().getName();
operLog.setMethod(className + "." + methodName + "()"); operLog.setMethod(className + "." + methodName + "()");
// 设置请求方式 // 设置请求方式
operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
// 处理设置注解上的参数 // 处理设置注解上的参数
getControllerMethodDescription(joinPoint, controllerLog, operLog); getControllerMethodDescription(joinPoint, controllerLog, operLog);
// 保存数据库 // 保存数据库
AsyncManager.me().execute(AsyncFactory.recordOper(operLog)); AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
} }
catch (Exception exp) catch (Exception exp)
{ {
// 记录本地异常日志 // 记录本地异常日志
log.error("==前置通知异常=="); log.error("==前置通知异常==");
log.error("异常信息:{}", exp.getMessage()); log.error("异常信息:{}", exp.getMessage());
exp.printStackTrace(); exp.printStackTrace();
} }
} }
/** /**
* 获取注解中对方法的描述信息 用于Controller层注解 * 获取注解中对方法的描述信息 用于Controller层注解
* *
* @param log 日志 * @param log 日志
* @param operLog 操作日志 * @param operLog 操作日志
* @throws Exception * @throws Exception
*/ */
public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception public void getControllerMethodDescription(JoinPoint joinPoint, Log log, SysOperLog operLog) throws Exception
{ {
// 设置action动作 // 设置action动作
operLog.setBusinessType(log.businessType().ordinal()); operLog.setBusinessType(log.businessType().ordinal());
// 设置标题 // 设置标题
operLog.setTitle(log.title()); operLog.setTitle(log.title());
// 设置操作人类别 // 设置操作人类别
operLog.setOperatorType(log.operatorType().ordinal()); operLog.setOperatorType(log.operatorType().ordinal());
// 是否需要保存request参数和值 // 是否需要保存request参数和值
if (log.isSaveRequestData()) if (log.isSaveRequestData())
{ {
// 获取参数的信息,传入到数据库中。 // 获取参数的信息,传入到数据库中。
setRequestValue(joinPoint, operLog); setRequestValue(joinPoint, operLog);
} }
} }
/** /**
* 获取请求的参数放到log中 * 获取请求的参数放到log中
* *
* @param operLog 操作日志 * @param operLog 操作日志
* @throws Exception 异常 * @throws Exception 异常
*/ */
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog) throws Exception
{ {
String requestMethod = operLog.getRequestMethod(); String requestMethod = operLog.getRequestMethod();
if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod)) if (HttpMethod.PUT.name().equals(requestMethod) || HttpMethod.POST.name().equals(requestMethod))
{ {
String params = argsArrayToString(joinPoint.getArgs()); String params = argsArrayToString(joinPoint.getArgs());
operLog.setOperParam(StringUtils.substring(params, 0, 2000)); operLog.setOperParam(StringUtils.substring(params, 0, 2000));
} }
else else
{ {
Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE); Map<?, ?> paramsMap = (Map<?, ?>) ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000)); operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
} }
} }
/** /**
* 是否存在注解,如果存在就获取 * 是否存在注解,如果存在就获取
*/ */
private Log getAnnotationLog(JoinPoint joinPoint) throws Exception private Log getAnnotationLog(JoinPoint joinPoint) throws Exception
{ {
Signature signature = joinPoint.getSignature(); Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature; MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod(); Method method = methodSignature.getMethod();
if (method != null) if (method != null)
{ {
return method.getAnnotation(Log.class); return method.getAnnotation(Log.class);
} }
return null; return null;
} }
/** /**
* 参数拼装 * 参数拼装
*/ */
private String argsArrayToString(Object[] paramsArray) private String argsArrayToString(Object[] paramsArray)
{ {
String params = ""; String params = "";
if (paramsArray != null && paramsArray.length > 0) if (paramsArray != null && paramsArray.length > 0)
{ {
for (int i = 0; i < paramsArray.length; i++) for (int i = 0; i < paramsArray.length; i++)
{ {
if (!isFilterObject(paramsArray[i])) if (!isFilterObject(paramsArray[i]))
{ {
Object jsonObj = JSON.toJSON(paramsArray[i]); Object jsonObj = JSON.toJSON(paramsArray[i]);
params += jsonObj.toString() + " "; params += jsonObj.toString() + " ";
} }
} }
} }
return params.trim(); return params.trim();
} }
/** /**
* 判断是否需要过滤的对象。 * 判断是否需要过滤的对象。
* *
* @param o 对象信息。 * @param o 对象信息。
* @return 如果是需要过滤的对象则返回true否则返回false。 * @return 如果是需要过滤的对象则返回true否则返回false。
*/ */
public boolean isFilterObject(final Object o) public boolean isFilterObject(final Object o)
{ {
return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse; return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse;
} }
} }

View File

@ -1,28 +1,28 @@
package com.ruoyi.framework.aspectj.lang.annotation; package com.ruoyi.framework.aspectj.lang.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 数据权限过滤注解 * 数据权限过滤注解
* *
* @author ruoyi * @author ruoyi
*/ */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface DataScope public @interface DataScope
{ {
/** /**
* 部门表的别名 * 部门表的别名
*/ */
public String deptAlias() default ""; public String deptAlias() default "";
/** /**
* 用户表的别名 * 用户表的别名
*/ */
public String userAlias() default ""; public String userAlias() default "";
} }

View File

@ -1,26 +1,26 @@
package com.ruoyi.framework.aspectj.lang.annotation; package com.ruoyi.framework.aspectj.lang.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited; import java.lang.annotation.Inherited;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import com.ruoyi.framework.aspectj.lang.enums.DataSourceType; import com.ruoyi.framework.aspectj.lang.enums.DataSourceType;
/** /**
* 自定义多数据源切换注解 * 自定义多数据源切换注解
* *
* @author ruoyi * @author ruoyi
*/ */
@Target({ ElementType.METHOD, ElementType.TYPE }) @Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Inherited @Inherited
public @interface DataSource public @interface DataSource
{ {
/** /**
* 切换数据源名称 * 切换数据源名称
*/ */
public DataSourceType value() default DataSourceType.MASTER; public DataSourceType value() default DataSourceType.MASTER;
} }

View File

@ -1,41 +1,41 @@
package com.ruoyi.framework.aspectj.lang.annotation; package com.ruoyi.framework.aspectj.lang.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.aspectj.lang.enums.OperatorType; import com.ruoyi.framework.aspectj.lang.enums.OperatorType;
/** /**
* 自定义操作日志记录注解 * 自定义操作日志记录注解
* *
* @author ruoyi * @author ruoyi
* *
*/ */
@Target({ ElementType.PARAMETER, ElementType.METHOD }) @Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface Log public @interface Log
{ {
/** /**
* 模块 * 模块
*/ */
public String title() default ""; public String title() default "";
/** /**
* 功能 * 功能
*/ */
public BusinessType businessType() default BusinessType.OTHER; public BusinessType businessType() default BusinessType.OTHER;
/** /**
* 操作人类别 * 操作人类别
*/ */
public OperatorType operatorType() default OperatorType.MANAGE; public OperatorType operatorType() default OperatorType.MANAGE;
/** /**
* 是否保存请求的参数 * 是否保存请求的参数
*/ */
public boolean isSaveRequestData() default true; public boolean isSaveRequestData() default true;
} }

View File

@ -1,20 +1,20 @@
package com.ruoyi.framework.aspectj.lang.enums; package com.ruoyi.framework.aspectj.lang.enums;
/** /**
* 操作状态 * 操作状态
* *
* @author ruoyi * @author ruoyi
* *
*/ */
public enum BusinessStatus public enum BusinessStatus
{ {
/** /**
* 成功 * 成功
*/ */
SUCCESS, SUCCESS,
/** /**
* 失败 * 失败
*/ */
FAIL, FAIL,
} }

View File

@ -1,59 +1,59 @@
package com.ruoyi.framework.aspectj.lang.enums; package com.ruoyi.framework.aspectj.lang.enums;
/** /**
* 业务操作类型 * 业务操作类型
* *
* @author ruoyi * @author ruoyi
*/ */
public enum BusinessType public enum BusinessType
{ {
/** /**
* 其它 * 其它
*/ */
OTHER, OTHER,
/** /**
* 新增 * 新增
*/ */
INSERT, INSERT,
/** /**
* 修改 * 修改
*/ */
UPDATE, UPDATE,
/** /**
* 删除 * 删除
*/ */
DELETE, DELETE,
/** /**
* 授权 * 授权
*/ */
GRANT, GRANT,
/** /**
* 导出 * 导出
*/ */
EXPORT, EXPORT,
/** /**
* 导入 * 导入
*/ */
IMPORT, IMPORT,
/** /**
* 强退 * 强退
*/ */
FORCE, FORCE,
/** /**
* 生成代码 * 生成代码
*/ */
GENCODE, GENCODE,
/** /**
* 清空数据 * 清空数据
*/ */
CLEAN, CLEAN,
} }

View File

@ -1,19 +1,19 @@
package com.ruoyi.framework.aspectj.lang.enums; package com.ruoyi.framework.aspectj.lang.enums;
/** /**
* 数据源 * 数据源
* *
* @author ruoyi * @author ruoyi
*/ */
public enum DataSourceType public enum DataSourceType
{ {
/** /**
* 主库 * 主库
*/ */
MASTER, MASTER,
/** /**
* 从库 * 从库
*/ */
SLAVE SLAVE
} }

View File

@ -1,24 +1,24 @@
package com.ruoyi.framework.aspectj.lang.enums; package com.ruoyi.framework.aspectj.lang.enums;
/** /**
* 操作人类别 * 操作人类别
* *
* @author ruoyi * @author ruoyi
*/ */
public enum OperatorType public enum OperatorType
{ {
/** /**
* 其它 * 其它
*/ */
OTHER, OTHER,
/** /**
* 后台用户 * 后台用户
*/ */
MANAGE, MANAGE,
/** /**
* 手机端用户 * 手机端用户
*/ */
MOBILE MOBILE
} }

View File

@ -1,30 +1,30 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.util.TimeZone; import java.util.TimeZone;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
/** /**
* 程序注解配置 * 程序注解配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问 // 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true) @EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径 // 指定要扫描的Mapper类的包的路径
@MapperScan("com.ruoyi.project.**.mapper") @MapperScan("com.ruoyi.project.**.mapper")
public class ApplicationConfig public class ApplicationConfig
{ {
/** /**
* 时区配置 * 时区配置
*/ */
@Bean @Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
{ {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault()); return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
} }
} }

View File

@ -1,126 +1,126 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils; import com.alibaba.druid.util.Utils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.aspectj.lang.enums.DataSourceType; import com.ruoyi.framework.aspectj.lang.enums.DataSourceType;
import com.ruoyi.framework.config.properties.DruidProperties; import com.ruoyi.framework.config.properties.DruidProperties;
import com.ruoyi.framework.datasource.DynamicDataSource; import com.ruoyi.framework.datasource.DynamicDataSource;
/** /**
* druid 配置多数据源 * druid 配置多数据源
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
public class DruidConfig public class DruidConfig
{ {
@Bean @Bean
@ConfigurationProperties("spring.datasource.druid.master") @ConfigurationProperties("spring.datasource.druid.master")
public DataSource masterDataSource(DruidProperties druidProperties) public DataSource masterDataSource(DruidProperties druidProperties)
{ {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource); return druidProperties.dataSource(dataSource);
} }
@Bean @Bean
@ConfigurationProperties("spring.datasource.druid.slave") @ConfigurationProperties("spring.datasource.druid.slave")
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true") @ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
public DataSource slaveDataSource(DruidProperties druidProperties) public DataSource slaveDataSource(DruidProperties druidProperties)
{ {
DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource); return druidProperties.dataSource(dataSource);
} }
@Bean(name = "dynamicDataSource") @Bean(name = "dynamicDataSource")
@Primary @Primary
public DynamicDataSource dataSource(DataSource masterDataSource) public DynamicDataSource dataSource(DataSource masterDataSource)
{ {
Map<Object, Object> targetDataSources = new HashMap<>(); Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource); targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource);
setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource"); setDataSource(targetDataSources, DataSourceType.SLAVE.name(), "slaveDataSource");
return new DynamicDataSource(masterDataSource, targetDataSources); return new DynamicDataSource(masterDataSource, targetDataSources);
} }
/** /**
* 设置数据源 * 设置数据源
* *
* @param targetDataSources 备选数据源集合 * @param targetDataSources 备选数据源集合
* @param sourceName 数据源名称 * @param sourceName 数据源名称
* @param beanName bean名称 * @param beanName bean名称
*/ */
public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName) public void setDataSource(Map<Object, Object> targetDataSources, String sourceName, String beanName)
{ {
try try
{ {
DataSource dataSource = SpringUtils.getBean(beanName); DataSource dataSource = SpringUtils.getBean(beanName);
targetDataSources.put(sourceName, dataSource); targetDataSources.put(sourceName, dataSource);
} }
catch (Exception e) catch (Exception e)
{ {
} }
} }
/** /**
* 去除监控页面底部的广告 * 去除监控页面底部的广告
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Bean @Bean
@ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
{ {
// 获取web监控页面的参数 // 获取web监控页面的参数
DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
// 提取common.js的配置路径 // 提取common.js的配置路径
String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
final String filePath = "support/http/resources/js/common.js"; final String filePath = "support/http/resources/js/common.js";
// 创建filter进行过滤 // 创建filter进行过滤
Filter filter = new Filter() Filter filter = new Filter()
{ {
@Override @Override
public void init(javax.servlet.FilterConfig filterConfig) throws ServletException public void init(javax.servlet.FilterConfig filterConfig) throws ServletException
{ {
} }
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException throws IOException, ServletException
{ {
chain.doFilter(request, response); chain.doFilter(request, response);
// 重置缓冲区,响应头不会被重置 // 重置缓冲区,响应头不会被重置
response.resetBuffer(); response.resetBuffer();
// 获取common.js // 获取common.js
String text = Utils.readFromResource(filePath); String text = Utils.readFromResource(filePath);
// 正则替换banner, 除去底部的广告信息 // 正则替换banner, 除去底部的广告信息
text = text.replaceAll("<a.*?banner\"></a><br/>", ""); text = text.replaceAll("<a.*?banner\"></a><br/>", "");
text = text.replaceAll("powered.*?shrek.wang</a>", ""); text = text.replaceAll("powered.*?shrek.wang</a>", "");
response.getWriter().write(text); response.getWriter().write(text);
} }
@Override @Override
public void destroy() public void destroy()
{ {
} }
}; };
FilterRegistrationBean registrationBean = new FilterRegistrationBean(); FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter); registrationBean.setFilter(filter);
registrationBean.addUrlPatterns(commonJsPattern); registrationBean.addUrlPatterns(commonJsPattern);
return registrationBean; return registrationBean;
} }
} }

View File

@ -1,69 +1,69 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException; import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.parser.ParserConfig;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import java.nio.charset.Charset; import java.nio.charset.Charset;
/** /**
* Redis使用FastJson序列化 * Redis使用FastJson序列化
* *
* @author ruoyi * @author ruoyi
*/ */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{ {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper(); private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz; private Class<T> clazz;
static static
{ {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true); ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
} }
public FastJson2JsonRedisSerializer(Class<T> clazz) public FastJson2JsonRedisSerializer(Class<T> clazz)
{ {
super(); super();
this.clazz = clazz; this.clazz = clazz;
} }
public byte[] serialize(T t) throws SerializationException public byte[] serialize(T t) throws SerializationException
{ {
if (t == null) if (t == null)
{ {
return new byte[0]; return new byte[0];
} }
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
} }
public T deserialize(byte[] bytes) throws SerializationException public T deserialize(byte[] bytes) throws SerializationException
{ {
if (bytes == null || bytes.length <= 0) if (bytes == null || bytes.length <= 0)
{ {
return null; return null;
} }
String str = new String(bytes, DEFAULT_CHARSET); String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz); return JSON.parseObject(str, clazz);
} }
public void setObjectMapper(ObjectMapper objectMapper) public void setObjectMapper(ObjectMapper objectMapper)
{ {
Assert.notNull(objectMapper, "'objectMapper' must not be null"); Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper; this.objectMapper = objectMapper;
} }
protected JavaType getJavaType(Class<?> clazz) protected JavaType getJavaType(Class<?> clazz)
{ {
return TypeFactory.defaultInstance().constructType(clazz); return TypeFactory.defaultInstance().constructType(clazz);
} }
} }

View File

@ -1,60 +1,60 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.ruoyi.common.filter.RepeatableFilter; import com.ruoyi.common.filter.RepeatableFilter;
import com.ruoyi.common.filter.XssFilter; import com.ruoyi.common.filter.XssFilter;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* Filter配置 * Filter配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
public class FilterConfig public class FilterConfig
{ {
@Value("${xss.enabled}") @Value("${xss.enabled}")
private String enabled; private String enabled;
@Value("${xss.excludes}") @Value("${xss.excludes}")
private String excludes; private String excludes;
@Value("${xss.urlPatterns}") @Value("${xss.urlPatterns}")
private String urlPatterns; private String urlPatterns;
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Bean @Bean
public FilterRegistrationBean xssFilterRegistration() public FilterRegistrationBean xssFilterRegistration()
{ {
FilterRegistrationBean registration = new FilterRegistrationBean(); FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST); registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new XssFilter()); registration.setFilter(new XssFilter());
registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); registration.addUrlPatterns(StringUtils.split(urlPatterns, ","));
registration.setName("xssFilter"); registration.setName("xssFilter");
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
Map<String, String> initParameters = new HashMap<String, String>(); Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("excludes", excludes); initParameters.put("excludes", excludes);
initParameters.put("enabled", enabled); initParameters.put("enabled", enabled);
registration.setInitParameters(initParameters); registration.setInitParameters(initParameters);
return registration; return registration;
} }
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
@Bean @Bean
public FilterRegistrationBean someFilterRegistration() public FilterRegistrationBean someFilterRegistration()
{ {
FilterRegistrationBean registration = new FilterRegistrationBean(); FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new RepeatableFilter()); registration.setFilter(new RepeatableFilter());
registration.addUrlPatterns("/*"); registration.addUrlPatterns("/*");
registration.setName("repeatableFilter"); registration.setName("repeatableFilter");
registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE); registration.setOrder(FilterRegistrationBean.LOWEST_PRECEDENCE);
return registration; return registration;
} }
} }

View File

@ -1,66 +1,66 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* 读取代码生成相关配置 * 读取代码生成相关配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
@ConfigurationProperties(prefix = "gen") @ConfigurationProperties(prefix = "gen")
public class GenConfig public class GenConfig
{ {
/** 作者 */ /** 作者 */
public static String author; public static String author;
/** 生成包路径 */ /** 生成包路径 */
public static String packageName; public static String packageName;
/** 自动去除表前缀默认是true */ /** 自动去除表前缀默认是true */
public static boolean autoRemovePre; public static boolean autoRemovePre;
/** 表前缀(类名不会包含表前缀) */ /** 表前缀(类名不会包含表前缀) */
public static String tablePrefix; public static String tablePrefix;
public static String getAuthor() public static String getAuthor()
{ {
return author; return author;
} }
public void setAuthor(String author) public void setAuthor(String author)
{ {
GenConfig.author = author; GenConfig.author = author;
} }
public static String getPackageName() public static String getPackageName()
{ {
return packageName; return packageName;
} }
public void setPackageName(String packageName) public void setPackageName(String packageName)
{ {
GenConfig.packageName = packageName; GenConfig.packageName = packageName;
} }
public static boolean getAutoRemovePre() public static boolean getAutoRemovePre()
{ {
return autoRemovePre; return autoRemovePre;
} }
public void setAutoRemovePre(boolean autoRemovePre) public void setAutoRemovePre(boolean autoRemovePre)
{ {
GenConfig.autoRemovePre = autoRemovePre; GenConfig.autoRemovePre = autoRemovePre;
} }
public static String getTablePrefix() public static String getTablePrefix()
{ {
return tablePrefix; return tablePrefix;
} }
public void setTablePrefix(String tablePrefix) public void setTablePrefix(String tablePrefix)
{ {
GenConfig.tablePrefix = tablePrefix; GenConfig.tablePrefix = tablePrefix;
} }
} }

View File

@ -1,108 +1,108 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.apache.ibatis.io.VFS; import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
* Mybatis支持*匹配扫描包 * Mybatis支持*匹配扫描包
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
public class MyBatisConfig public class MyBatisConfig
{ {
@Autowired @Autowired
private Environment env; private Environment env;
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class"; static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
public static String setTypeAliasesPackage(String typeAliasesPackage) public static String setTypeAliasesPackage(String typeAliasesPackage)
{ {
ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver(); ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver); MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
List<String> allResult = new ArrayList<String>(); List<String> allResult = new ArrayList<String>();
try try
{ {
for (String aliasesPackage : typeAliasesPackage.split(",")) for (String aliasesPackage : typeAliasesPackage.split(","))
{ {
List<String> result = new ArrayList<String>(); List<String> result = new ArrayList<String>();
aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
+ ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN; + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
Resource[] resources = resolver.getResources(aliasesPackage); Resource[] resources = resolver.getResources(aliasesPackage);
if (resources != null && resources.length > 0) if (resources != null && resources.length > 0)
{ {
MetadataReader metadataReader = null; MetadataReader metadataReader = null;
for (Resource resource : resources) for (Resource resource : resources)
{ {
if (resource.isReadable()) if (resource.isReadable())
{ {
metadataReader = metadataReaderFactory.getMetadataReader(resource); metadataReader = metadataReaderFactory.getMetadataReader(resource);
try try
{ {
result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName()); result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
} }
catch (ClassNotFoundException e) catch (ClassNotFoundException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
if (result.size() > 0) if (result.size() > 0)
{ {
HashSet<String> hashResult = new HashSet<String>(result); HashSet<String> hashResult = new HashSet<String>(result);
allResult.addAll(hashResult); allResult.addAll(hashResult);
} }
} }
if (allResult.size() > 0) if (allResult.size() > 0)
{ {
typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0])); typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
} }
else else
{ {
throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包"); throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
} }
} }
catch (IOException e) catch (IOException e)
{ {
e.printStackTrace(); e.printStackTrace();
} }
return typeAliasesPackage; return typeAliasesPackage;
} }
@Bean @Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{ {
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
String mapperLocations = env.getProperty("mybatis.mapperLocations"); String mapperLocations = env.getProperty("mybatis.mapperLocations");
String configLocation = env.getProperty("mybatis.configLocation"); String configLocation = env.getProperty("mybatis.configLocation");
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class); VFS.addImplClass(SpringBootVFS.class);
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource); sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage(typeAliasesPackage); sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations)); sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject(); return sessionFactory.getObject();
} }
} }

View File

@ -1,43 +1,43 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
/** /**
* redis配置 * redis配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
@EnableCaching @EnableCaching
public class RedisConfig extends CachingConfigurerSupport public class RedisConfig extends CachingConfigurerSupport
{ {
@Bean @Bean
@SuppressWarnings(value = { "unchecked", "rawtypes" }) @SuppressWarnings(value = { "unchecked", "rawtypes" })
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
{ {
RedisTemplate<Object, Object> template = new RedisTemplate<>(); RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory); template.setConnectionFactory(connectionFactory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(mapper); serializer.setObjectMapper(mapper);
template.setValueSerializer(serializer); template.setValueSerializer(serializer);
// 使用StringRedisSerializer来序列化和反序列化redis的key值 // 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer()); template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet(); template.afterPropertiesSet();
return template; return template;
} }
} }

View File

@ -1,41 +1,41 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor;
/** /**
* 通用配置 * 通用配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
public class ResourcesConfig implements WebMvcConfigurer public class ResourcesConfig implements WebMvcConfigurer
{ {
@Autowired @Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor; private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) public void addResourceHandlers(ResourceHandlerRegistry registry)
{ {
/** 本地文件上传路径 */ /** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
/** swagger配置 */ /** swagger配置 */
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
} }
/** /**
* 自定义拦截规则 * 自定义拦截规则
*/ */
@Override @Override
public void addInterceptors(InterceptorRegistry registry) public void addInterceptors(InterceptorRegistry registry)
{ {
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**"); registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
} }
} }

View File

@ -1,116 +1,116 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* 读取项目相关配置 * 读取项目相关配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
@ConfigurationProperties(prefix = "ruoyi") @ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig public class RuoYiConfig
{ {
/** 项目名称 */ /** 项目名称 */
private String name; private String name;
/** 版本 */ /** 版本 */
private String version; private String version;
/** 版权年份 */ /** 版权年份 */
private String copyrightYear; private String copyrightYear;
/** 实例演示开关 */ /** 实例演示开关 */
private boolean demoEnabled; private boolean demoEnabled;
/** 上传路径 */ /** 上传路径 */
private static String profile; private static String profile;
/** 获取地址开关 */ /** 获取地址开关 */
private static boolean addressEnabled; private static boolean addressEnabled;
public String getName() public String getName()
{ {
return name; return name;
} }
public void setName(String name) public void setName(String name)
{ {
this.name = name; this.name = name;
} }
public String getVersion() public String getVersion()
{ {
return version; return version;
} }
public void setVersion(String version) public void setVersion(String version)
{ {
this.version = version; this.version = version;
} }
public String getCopyrightYear() public String getCopyrightYear()
{ {
return copyrightYear; return copyrightYear;
} }
public void setCopyrightYear(String copyrightYear) public void setCopyrightYear(String copyrightYear)
{ {
this.copyrightYear = copyrightYear; this.copyrightYear = copyrightYear;
} }
public boolean isDemoEnabled() public boolean isDemoEnabled()
{ {
return demoEnabled; return demoEnabled;
} }
public void setDemoEnabled(boolean demoEnabled) public void setDemoEnabled(boolean demoEnabled)
{ {
this.demoEnabled = demoEnabled; this.demoEnabled = demoEnabled;
} }
public static String getProfile() public static String getProfile()
{ {
return profile; return profile;
} }
public void setProfile(String profile) public void setProfile(String profile)
{ {
RuoYiConfig.profile = profile; RuoYiConfig.profile = profile;
} }
public static boolean isAddressEnabled() public static boolean isAddressEnabled()
{ {
return addressEnabled; return addressEnabled;
} }
public void setAddressEnabled(boolean addressEnabled) public void setAddressEnabled(boolean addressEnabled)
{ {
RuoYiConfig.addressEnabled = addressEnabled; RuoYiConfig.addressEnabled = addressEnabled;
} }
/** /**
* 获取头像上传路径 * 获取头像上传路径
*/ */
public static String getAvatarPath() public static String getAvatarPath()
{ {
return getProfile() + "/avatar"; return getProfile() + "/avatar";
} }
/** /**
* 获取下载路径 * 获取下载路径
*/ */
public static String getDownloadPath() public static String getDownloadPath()
{ {
return getProfile() + "/download/"; return getProfile() + "/download/";
} }
/** /**
* 获取上传路径 * 获取上传路径
*/ */
public static String getUploadPath() public static String getUploadPath()
{ {
return getProfile() + "/upload"; return getProfile() + "/upload";
} }
} }

View File

@ -1,135 +1,135 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter;
import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl;
import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;
/** /**
* spring security配置 * spring security配置
* *
* @author ruoyi * @author ruoyi
*/ */
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter public class SecurityConfig extends WebSecurityConfigurerAdapter
{ {
/** /**
* 自定义用户认证逻辑 * 自定义用户认证逻辑
*/ */
@Autowired @Autowired
private UserDetailsService userDetailsService; private UserDetailsService userDetailsService;
/** /**
* 认证失败处理类 * 认证失败处理类
*/ */
@Autowired @Autowired
private AuthenticationEntryPointImpl unauthorizedHandler; private AuthenticationEntryPointImpl unauthorizedHandler;
/** /**
* 退出处理类 * 退出处理类
*/ */
@Autowired @Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler; private LogoutSuccessHandlerImpl logoutSuccessHandler;
/** /**
* token认证过滤器 * token认证过滤器
*/ */
@Autowired @Autowired
private JwtAuthenticationTokenFilter authenticationTokenFilter; private JwtAuthenticationTokenFilter authenticationTokenFilter;
/** /**
* 解决 无法直接注入 AuthenticationManager * 解决 无法直接注入 AuthenticationManager
* *
* @return * @return
* @throws Exception * @throws Exception
*/ */
@Bean @Bean
@Override @Override
public AuthenticationManager authenticationManagerBean() throws Exception public AuthenticationManager authenticationManagerBean() throws Exception
{ {
return super.authenticationManagerBean(); return super.authenticationManagerBean();
} }
/** /**
* anyRequest | 匹配所有请求路径 * anyRequest | 匹配所有请求路径
* access | SpringEl表达式结果为true时可以访问 * access | SpringEl表达式结果为true时可以访问
* anonymous | 匿名可以访问 * anonymous | 匿名可以访问
* denyAll | 用户不能访问 * denyAll | 用户不能访问
* fullyAuthenticated | 用户完全认证可以访问非remember-me下自动登录 * fullyAuthenticated | 用户完全认证可以访问非remember-me下自动登录
* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问 * hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问 * hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问 * hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
* hasIpAddress | 如果有参数参数表示IP地址如果用户IP和参数匹配则可以访问 * hasIpAddress | 如果有参数参数表示IP地址如果用户IP和参数匹配则可以访问
* hasRole | 如果有参数,参数表示角色,则其角色可以访问 * hasRole | 如果有参数,参数表示角色,则其角色可以访问
* permitAll | 用户可以任意访问 * permitAll | 用户可以任意访问
* rememberMe | 允许通过remember-me登录的用户访问 * rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问 * authenticated | 用户登录后可访问
*/ */
@Override @Override
protected void configure(HttpSecurity httpSecurity) throws Exception protected void configure(HttpSecurity httpSecurity) throws Exception
{ {
httpSecurity httpSecurity
// CRSF禁用因为不使用session // CRSF禁用因为不使用session
.csrf().disable() .csrf().disable()
// 认证失败处理类 // 认证失败处理类
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 基于token所以不需要session // 基于token所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求 // 过滤请求
.authorizeRequests() .authorizeRequests()
// 对于登录login 验证码captchaImage 允许匿名访问 // 对于登录login 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/captchaImage").anonymous() .antMatchers("/login", "/captchaImage").anonymous()
.antMatchers( .antMatchers(
HttpMethod.GET, HttpMethod.GET,
"/*.html", "/*.html",
"/**/*.html", "/**/*.html",
"/**/*.css", "/**/*.css",
"/**/*.js" "/**/*.js"
).permitAll() ).permitAll()
.antMatchers("/profile/**").anonymous() .antMatchers("/profile/**").anonymous()
.antMatchers("/common/download**").anonymous() .antMatchers("/common/download**").anonymous()
.antMatchers("/common/download/resource**").anonymous() .antMatchers("/common/download/resource**").anonymous()
.antMatchers("/swagger-ui.html").anonymous() .antMatchers("/swagger-ui.html").anonymous()
.antMatchers("/swagger-resources/**").anonymous() .antMatchers("/swagger-resources/**").anonymous()
.antMatchers("/webjars/**").anonymous() .antMatchers("/webjars/**").anonymous()
.antMatchers("/*/api-docs").anonymous() .antMatchers("/*/api-docs").anonymous()
.antMatchers("/druid/**").anonymous() .antMatchers("/druid/**").anonymous()
// 除上面外的所有请求全部需要鉴权认证 // 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated() .anyRequest().authenticated()
.and() .and()
.headers().frameOptions().disable(); .headers().frameOptions().disable();
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加JWT filter // 添加JWT filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
} }
/** /**
* 强散列哈希加密实现 * 强散列哈希加密实现
*/ */
@Bean @Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() public BCryptPasswordEncoder bCryptPasswordEncoder()
{ {
return new BCryptPasswordEncoder(); return new BCryptPasswordEncoder();
} }
/** /**
* 身份认证接口 * 身份认证接口
*/ */
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception protected void configure(AuthenticationManagerBuilder auth) throws Exception
{ {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
} }
} }

View File

@ -1,32 +1,32 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
/** /**
* 服务相关配置 * 服务相关配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class ServerConfig public class ServerConfig
{ {
/** /**
* 获取完整的请求路径,包括:域名,端口,上下文访问路径 * 获取完整的请求路径,包括:域名,端口,上下文访问路径
* *
* @return 服务地址 * @return 服务地址
*/ */
public String getUrl() public String getUrl()
{ {
HttpServletRequest request = ServletUtils.getRequest(); HttpServletRequest request = ServletUtils.getRequest();
return getDomain(request); return getDomain(request);
} }
public static String getDomain(HttpServletRequest request) public static String getDomain(HttpServletRequest request)
{ {
StringBuffer url = request.getRequestURL(); StringBuffer url = request.getRequestURL();
String contextPath = request.getServletContext().getContextPath(); String contextPath = request.getServletContext().getContextPath();
return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString(); return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
} }
} }

View File

@ -1,113 +1,113 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey; import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope; import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact; import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference; import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
/** /**
* Swagger2的接口配置 * Swagger2的接口配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
public class SwaggerConfig public class SwaggerConfig
{ {
/** 系统基础配置 */ /** 系统基础配置 */
@Autowired @Autowired
private RuoYiConfig ruoyiConfig; private RuoYiConfig ruoyiConfig;
/** /**
* 创建API * 创建API
*/ */
@Bean @Bean
public Docket createRestApi() public Docket createRestApi()
{ {
return new Docket(DocumentationType.SWAGGER_2) return new Docket(DocumentationType.SWAGGER_2)
.pathMapping("/dev-api") .pathMapping("/dev-api")
// 用来创建该API的基本信息展示在文档的页面中自定义展示的信息 // 用来创建该API的基本信息展示在文档的页面中自定义展示的信息
.apiInfo(apiInfo()) .apiInfo(apiInfo())
// 设置哪些接口暴露给Swagger展示 // 设置哪些接口暴露给Swagger展示
.select() .select()
// 扫描所有有注解的api用这种方式更灵活 // 扫描所有有注解的api用这种方式更灵活
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 扫描指定包中的swagger注解 // 扫描指定包中的swagger注解
//.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
// 扫描所有 .apis(RequestHandlerSelectors.any()) // 扫描所有 .apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any()) .paths(PathSelectors.any())
.build() .build()
/* 设置安全模式swagger可以设置访问token */ /* 设置安全模式swagger可以设置访问token */
.securitySchemes(securitySchemes()) .securitySchemes(securitySchemes())
.securityContexts(securityContexts()); .securityContexts(securityContexts());
} }
/** /**
* 安全模式这里指定token通过Authorization头请求头传递 * 安全模式这里指定token通过Authorization头请求头传递
*/ */
private List<ApiKey> securitySchemes() private List<ApiKey> securitySchemes()
{ {
List<ApiKey> apiKeyList = new ArrayList<ApiKey>(); List<ApiKey> apiKeyList = new ArrayList<ApiKey>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); apiKeyList.add(new ApiKey("Authorization", "Authorization", "header"));
return apiKeyList; return apiKeyList;
} }
/** /**
* 安全上下文 * 安全上下文
*/ */
private List<SecurityContext> securityContexts() private List<SecurityContext> securityContexts()
{ {
List<SecurityContext> securityContexts = new ArrayList<>(); List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add( securityContexts.add(
SecurityContext.builder() SecurityContext.builder()
.securityReferences(defaultAuth()) .securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$")) .forPaths(PathSelectors.regex("^(?!auth).*$"))
.build()); .build());
return securityContexts; return securityContexts;
} }
/** /**
* 默认的安全上引用 * 默认的安全上引用
*/ */
private List<SecurityReference> defaultAuth() private List<SecurityReference> defaultAuth()
{ {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope; authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>(); List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences; return securityReferences;
} }
/** /**
* 添加摘要信息 * 添加摘要信息
*/ */
private ApiInfo apiInfo() private ApiInfo apiInfo()
{ {
// 用ApiInfoBuilder进行定制 // 用ApiInfoBuilder进行定制
return new ApiInfoBuilder() return new ApiInfoBuilder()
// 设置标题 // 设置标题
.title("标题若依管理系统_接口文档") .title("标题若依管理系统_接口文档")
// 描述 // 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息 // 作者信息
.contact(new Contact(ruoyiConfig.getName(), null, null)) .contact(new Contact(ruoyiConfig.getName(), null, null))
// 版本 // 版本
.version("版本号:" + ruoyiConfig.getVersion()) .version("版本号:" + ruoyiConfig.getVersion())
.build(); .build();
} }
} }

View File

@ -1,62 +1,62 @@
package com.ruoyi.framework.config; package com.ruoyi.framework.config;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import com.ruoyi.common.utils.Threads; import com.ruoyi.common.utils.Threads;
/** /**
* 线程池配置 * 线程池配置
* *
* @author ruoyi * @author ruoyi
**/ **/
@Configuration @Configuration
public class ThreadPoolConfig public class ThreadPoolConfig
{ {
// 核心线程池大小 // 核心线程池大小
private int corePoolSize = 50; private int corePoolSize = 50;
// 最大可创建的线程数 // 最大可创建的线程数
private int maxPoolSize = 200; private int maxPoolSize = 200;
// 队列最大长度 // 队列最大长度
private int queueCapacity = 1000; private int queueCapacity = 1000;
// 线程池维护线程所允许的空闲时间 // 线程池维护线程所允许的空闲时间
private int keepAliveSeconds = 300; private int keepAliveSeconds = 300;
@Bean(name = "threadPoolTaskExecutor") @Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() public ThreadPoolTaskExecutor threadPoolTaskExecutor()
{ {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize); executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize); executor.setCorePoolSize(corePoolSize);
executor.setQueueCapacity(queueCapacity); executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds); executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程池对拒绝任务(无线程可用)的处理策略 // 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor; return executor;
} }
/** /**
* 执行周期性或定时任务 * 执行周期性或定时任务
*/ */
@Bean(name = "scheduledExecutorService") @Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService() protected ScheduledExecutorService scheduledExecutorService()
{ {
return new ScheduledThreadPoolExecutor(corePoolSize, return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
{ {
@Override @Override
protected void afterExecute(Runnable r, Throwable t) protected void afterExecute(Runnable r, Throwable t)
{ {
super.afterExecute(r, t); super.afterExecute(r, t);
Threads.printException(r, t); Threads.printException(r, t);
} }
}; };
} }
} }

View File

@ -1,77 +1,77 @@
package com.ruoyi.framework.config.properties; package com.ruoyi.framework.config.properties;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSource;
/** /**
* druid 配置属性 * druid 配置属性
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
public class DruidProperties public class DruidProperties
{ {
@Value("${spring.datasource.druid.initialSize}") @Value("${spring.datasource.druid.initialSize}")
private int initialSize; private int initialSize;
@Value("${spring.datasource.druid.minIdle}") @Value("${spring.datasource.druid.minIdle}")
private int minIdle; private int minIdle;
@Value("${spring.datasource.druid.maxActive}") @Value("${spring.datasource.druid.maxActive}")
private int maxActive; private int maxActive;
@Value("${spring.datasource.druid.maxWait}") @Value("${spring.datasource.druid.maxWait}")
private int maxWait; private int maxWait;
@Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}") @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis; private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.druid.minEvictableIdleTimeMillis}") @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis; private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}") @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
private int maxEvictableIdleTimeMillis; private int maxEvictableIdleTimeMillis;
@Value("${spring.datasource.druid.validationQuery}") @Value("${spring.datasource.druid.validationQuery}")
private String validationQuery; private String validationQuery;
@Value("${spring.datasource.druid.testWhileIdle}") @Value("${spring.datasource.druid.testWhileIdle}")
private boolean testWhileIdle; private boolean testWhileIdle;
@Value("${spring.datasource.druid.testOnBorrow}") @Value("${spring.datasource.druid.testOnBorrow}")
private boolean testOnBorrow; private boolean testOnBorrow;
@Value("${spring.datasource.druid.testOnReturn}") @Value("${spring.datasource.druid.testOnReturn}")
private boolean testOnReturn; private boolean testOnReturn;
public DruidDataSource dataSource(DruidDataSource datasource) public DruidDataSource dataSource(DruidDataSource datasource)
{ {
/** 配置初始化大小、最小、最大 */ /** 配置初始化大小、最小、最大 */
datasource.setInitialSize(initialSize); datasource.setInitialSize(initialSize);
datasource.setMaxActive(maxActive); datasource.setMaxActive(maxActive);
datasource.setMinIdle(minIdle); datasource.setMinIdle(minIdle);
/** 配置获取连接等待超时的时间 */ /** 配置获取连接等待超时的时间 */
datasource.setMaxWait(maxWait); datasource.setMaxWait(maxWait);
/** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
/** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
/** /**
* 用来检测连接是否有效的sql要求是一个查询语句常用select 'x'。如果validationQuery为nulltestOnBorrow、testOnReturn、testWhileIdle都不会起作用。 * 用来检测连接是否有效的sql要求是一个查询语句常用select 'x'。如果validationQuery为nulltestOnBorrow、testOnReturn、testWhileIdle都不会起作用。
*/ */
datasource.setValidationQuery(validationQuery); datasource.setValidationQuery(validationQuery);
/** 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。 */ /** 建议配置为true不影响性能并且保证安全性。申请连接的时候检测如果空闲时间大于timeBetweenEvictionRunsMillis执行validationQuery检测连接是否有效。 */
datasource.setTestWhileIdle(testWhileIdle); datasource.setTestWhileIdle(testWhileIdle);
/** 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。 */ /** 申请连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。 */
datasource.setTestOnBorrow(testOnBorrow); datasource.setTestOnBorrow(testOnBorrow);
/** 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。 */ /** 归还连接时执行validationQuery检测连接是否有效做了这个配置会降低性能。 */
datasource.setTestOnReturn(testOnReturn); datasource.setTestOnReturn(testOnReturn);
return datasource; return datasource;
} }
} }

View File

@ -1,26 +1,26 @@
package com.ruoyi.framework.datasource; package com.ruoyi.framework.datasource;
import java.util.Map; import java.util.Map;
import javax.sql.DataSource; import javax.sql.DataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/** /**
* 动态数据源 * 动态数据源
* *
* @author ruoyi * @author ruoyi
*/ */
public class DynamicDataSource extends AbstractRoutingDataSource public class DynamicDataSource extends AbstractRoutingDataSource
{ {
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
{ {
super.setDefaultTargetDataSource(defaultTargetDataSource); super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources); super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet(); super.afterPropertiesSet();
} }
@Override @Override
protected Object determineCurrentLookupKey() protected Object determineCurrentLookupKey()
{ {
return DynamicDataSourceContextHolder.getDataSourceType(); return DynamicDataSourceContextHolder.getDataSourceType();
} }
} }

View File

@ -1,45 +1,45 @@
package com.ruoyi.framework.datasource; package com.ruoyi.framework.datasource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* 数据源切换处理 * 数据源切换处理
* *
* @author ruoyi * @author ruoyi
*/ */
public class DynamicDataSourceContextHolder public class DynamicDataSourceContextHolder
{ {
public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class); public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
/** /**
* 使用ThreadLocal维护变量ThreadLocal为每个使用该变量的线程提供独立的变量副本 * 使用ThreadLocal维护变量ThreadLocal为每个使用该变量的线程提供独立的变量副本
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
*/ */
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>(); private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
/** /**
* 设置数据源的变量 * 设置数据源的变量
*/ */
public static void setDataSourceType(String dsType) public static void setDataSourceType(String dsType)
{ {
log.info("切换到{}数据源", dsType); log.info("切换到{}数据源", dsType);
CONTEXT_HOLDER.set(dsType); CONTEXT_HOLDER.set(dsType);
} }
/** /**
* 获得数据源的变量 * 获得数据源的变量
*/ */
public static String getDataSourceType() public static String getDataSourceType()
{ {
return CONTEXT_HOLDER.get(); return CONTEXT_HOLDER.get();
} }
/** /**
* 清空数据源变量 * 清空数据源变量
*/ */
public static void clearDataSourceType() public static void clearDataSourceType()
{ {
CONTEXT_HOLDER.remove(); CONTEXT_HOLDER.remove();
} }
} }

View File

@ -1,55 +1,55 @@
package com.ruoyi.framework.manager; package com.ruoyi.framework.manager;
import java.util.TimerTask; import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.ruoyi.common.utils.Threads; import com.ruoyi.common.utils.Threads;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
/** /**
* 异步任务管理器 * 异步任务管理器
* *
* @author ruoyi * @author ruoyi
*/ */
public class AsyncManager public class AsyncManager
{ {
/** /**
* 操作延迟10毫秒 * 操作延迟10毫秒
*/ */
private final int OPERATE_DELAY_TIME = 10; private final int OPERATE_DELAY_TIME = 10;
/** /**
* 异步操作任务调度线程池 * 异步操作任务调度线程池
*/ */
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService"); private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
/** /**
* 单例模式 * 单例模式
*/ */
private AsyncManager(){} private AsyncManager(){}
private static AsyncManager me = new AsyncManager(); private static AsyncManager me = new AsyncManager();
public static AsyncManager me() public static AsyncManager me()
{ {
return me; return me;
} }
/** /**
* 执行任务 * 执行任务
* *
* @param task 任务 * @param task 任务
*/ */
public void execute(TimerTask task) public void execute(TimerTask task)
{ {
executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS); executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
} }
/** /**
* 停止任务线程池 * 停止任务线程池
*/ */
public void shutdown() public void shutdown()
{ {
Threads.shutdownAndAwaitTermination(executor); Threads.shutdownAndAwaitTermination(executor);
} }
} }

View File

@ -1,39 +1,39 @@
package com.ruoyi.framework.manager; package com.ruoyi.framework.manager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
/** /**
* 确保应用退出时能关闭后台线程 * 确保应用退出时能关闭后台线程
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class ShutdownManager public class ShutdownManager
{ {
private static final Logger logger = LoggerFactory.getLogger("sys-user"); private static final Logger logger = LoggerFactory.getLogger("sys-user");
@PreDestroy @PreDestroy
public void destroy() public void destroy()
{ {
shutdownAsyncManager(); shutdownAsyncManager();
} }
/** /**
* 停止异步执行任务 * 停止异步执行任务
*/ */
private void shutdownAsyncManager() private void shutdownAsyncManager()
{ {
try try
{ {
logger.info("====关闭后台任务任务线程池===="); logger.info("====关闭后台任务任务线程池====");
AsyncManager.me().shutdown(); AsyncManager.me().shutdown();
} }
catch (Exception e) catch (Exception e)
{ {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
} }
} }
} }

View File

@ -1,101 +1,101 @@
package com.ruoyi.framework.manager.factory; package com.ruoyi.framework.manager.factory;
import java.util.TimerTask; import java.util.TimerTask;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.LogUtils; import com.ruoyi.common.utils.LogUtils;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.AddressUtils; import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.project.monitor.domain.SysLogininfor; import com.ruoyi.project.monitor.domain.SysLogininfor;
import com.ruoyi.project.monitor.domain.SysOperLog; import com.ruoyi.project.monitor.domain.SysOperLog;
import com.ruoyi.project.monitor.service.ISysLogininforService; import com.ruoyi.project.monitor.service.ISysLogininforService;
import com.ruoyi.project.monitor.service.ISysOperLogService; import com.ruoyi.project.monitor.service.ISysOperLogService;
import eu.bitwalker.useragentutils.UserAgent; import eu.bitwalker.useragentutils.UserAgent;
/** /**
* 异步工厂(产生任务用) * 异步工厂(产生任务用)
* *
* @author ruoyi * @author ruoyi
*/ */
public class AsyncFactory public class AsyncFactory
{ {
private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user"); private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
/** /**
* 记录登陆信息 * 记录登陆信息
* *
* @param username 用户名 * @param username 用户名
* @param status 状态 * @param status 状态
* @param message 消息 * @param message 消息
* @param args 列表 * @param args 列表
* @return 任务task * @return 任务task
*/ */
public static TimerTask recordLogininfor(final String username, final String status, final String message, public static TimerTask recordLogininfor(final String username, final String status, final String message,
final Object... args) final Object... args)
{ {
final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
final String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
return new TimerTask() return new TimerTask()
{ {
@Override @Override
public void run() public void run()
{ {
String address = AddressUtils.getRealAddressByIP(ip); String address = AddressUtils.getRealAddressByIP(ip);
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
s.append(LogUtils.getBlock(ip)); s.append(LogUtils.getBlock(ip));
s.append(address); s.append(address);
s.append(LogUtils.getBlock(username)); s.append(LogUtils.getBlock(username));
s.append(LogUtils.getBlock(status)); s.append(LogUtils.getBlock(status));
s.append(LogUtils.getBlock(message)); s.append(LogUtils.getBlock(message));
// 打印信息到日志 // 打印信息到日志
sys_user_logger.info(s.toString(), args); sys_user_logger.info(s.toString(), args);
// 获取客户端操作系统 // 获取客户端操作系统
String os = userAgent.getOperatingSystem().getName(); String os = userAgent.getOperatingSystem().getName();
// 获取客户端浏览器 // 获取客户端浏览器
String browser = userAgent.getBrowser().getName(); String browser = userAgent.getBrowser().getName();
// 封装对象 // 封装对象
SysLogininfor logininfor = new SysLogininfor(); SysLogininfor logininfor = new SysLogininfor();
logininfor.setUserName(username); logininfor.setUserName(username);
logininfor.setIpaddr(ip); logininfor.setIpaddr(ip);
logininfor.setLoginLocation(address); logininfor.setLoginLocation(address);
logininfor.setBrowser(browser); logininfor.setBrowser(browser);
logininfor.setOs(os); logininfor.setOs(os);
logininfor.setMsg(message); logininfor.setMsg(message);
// 日志状态 // 日志状态
if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status))
{ {
logininfor.setStatus(Constants.SUCCESS); logininfor.setStatus(Constants.SUCCESS);
} }
else if (Constants.LOGIN_FAIL.equals(status)) else if (Constants.LOGIN_FAIL.equals(status))
{ {
logininfor.setStatus(Constants.FAIL); logininfor.setStatus(Constants.FAIL);
} }
// 插入数据 // 插入数据
SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor); SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
} }
}; };
} }
/** /**
* 操作日志记录 * 操作日志记录
* *
* @param operLog 操作日志信息 * @param operLog 操作日志信息
* @return 任务task * @return 任务task
*/ */
public static TimerTask recordOper(final SysOperLog operLog) public static TimerTask recordOper(final SysOperLog operLog)
{ {
return new TimerTask() return new TimerTask()
{ {
@Override @Override
public void run() public void run()
{ {
// 远程查询操作地点 // 远程查询操作地点
operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp())); operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog); SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
} }
}; };
} }
} }

View File

@ -1,207 +1,207 @@
package com.ruoyi.framework.redis; package com.ruoyi.framework.redis;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* spring redis 工具类 * spring redis 工具类
* *
* @author ruoyi * @author ruoyi
**/ **/
@SuppressWarnings(value = { "unchecked", "rawtypes" }) @SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component @Component
public class RedisCache public class RedisCache
{ {
@Autowired @Autowired
public RedisTemplate redisTemplate; public RedisTemplate redisTemplate;
/** /**
* 缓存基本的对象Integer、String、实体类等 * 缓存基本的对象Integer、String、实体类等
* *
* @param key 缓存的键值 * @param key 缓存的键值
* @param value 缓存的值 * @param value 缓存的值
* @return 缓存的对象 * @return 缓存的对象
*/ */
public <T> ValueOperations<String, T> setCacheObject(String key, T value) public <T> ValueOperations<String, T> setCacheObject(String key, T value)
{ {
ValueOperations<String, T> operation = redisTemplate.opsForValue(); ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key, value); operation.set(key, value);
return operation; return operation;
} }
/** /**
* 缓存基本的对象Integer、String、实体类等 * 缓存基本的对象Integer、String、实体类等
* *
* @param key 缓存的键值 * @param key 缓存的键值
* @param value 缓存的值 * @param value 缓存的值
* @param timeout 时间 * @param timeout 时间
* @param timeUnit 时间颗粒度 * @param timeUnit 时间颗粒度
* @return 缓存的对象 * @return 缓存的对象
*/ */
public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) public <T> ValueOperations<String, T> setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit)
{ {
ValueOperations<String, T> operation = redisTemplate.opsForValue(); ValueOperations<String, T> operation = redisTemplate.opsForValue();
operation.set(key, value, timeout, timeUnit); operation.set(key, value, timeout, timeUnit);
return operation; return operation;
} }
/** /**
* 获得缓存的基本对象。 * 获得缓存的基本对象。
* *
* @param key 缓存键值 * @param key 缓存键值
* @return 缓存键值对应的数据 * @return 缓存键值对应的数据
*/ */
public <T> T getCacheObject(String key) public <T> T getCacheObject(String key)
{ {
ValueOperations<String, T> operation = redisTemplate.opsForValue(); ValueOperations<String, T> operation = redisTemplate.opsForValue();
return operation.get(key); return operation.get(key);
} }
/** /**
* 删除单个对象 * 删除单个对象
* *
* @param key * @param key
*/ */
public void deleteObject(String key) public void deleteObject(String key)
{ {
redisTemplate.delete(key); redisTemplate.delete(key);
} }
/** /**
* 删除集合对象 * 删除集合对象
* *
* @param collection * @param collection
*/ */
public void deleteObject(Collection collection) public void deleteObject(Collection collection)
{ {
redisTemplate.delete(collection); redisTemplate.delete(collection);
} }
/** /**
* 缓存List数据 * 缓存List数据
* *
* @param key 缓存的键值 * @param key 缓存的键值
* @param dataList 待缓存的List数据 * @param dataList 待缓存的List数据
* @return 缓存的对象 * @return 缓存的对象
*/ */
public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList) public <T> ListOperations<String, T> setCacheList(String key, List<T> dataList)
{ {
ListOperations listOperation = redisTemplate.opsForList(); ListOperations listOperation = redisTemplate.opsForList();
if (null != dataList) if (null != dataList)
{ {
int size = dataList.size(); int size = dataList.size();
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
listOperation.leftPush(key, dataList.get(i)); listOperation.leftPush(key, dataList.get(i));
} }
} }
return listOperation; return listOperation;
} }
/** /**
* 获得缓存的list对象 * 获得缓存的list对象
* *
* @param key 缓存的键值 * @param key 缓存的键值
* @return 缓存键值对应的数据 * @return 缓存键值对应的数据
*/ */
public <T> List<T> getCacheList(String key) public <T> List<T> getCacheList(String key)
{ {
List<T> dataList = new ArrayList<T>(); List<T> dataList = new ArrayList<T>();
ListOperations<String, T> listOperation = redisTemplate.opsForList(); ListOperations<String, T> listOperation = redisTemplate.opsForList();
Long size = listOperation.size(key); Long size = listOperation.size(key);
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
dataList.add(listOperation.index(key, i)); dataList.add(listOperation.index(key, i));
} }
return dataList; return dataList;
} }
/** /**
* 缓存Set * 缓存Set
* *
* @param key 缓存键值 * @param key 缓存键值
* @param dataSet 缓存的数据 * @param dataSet 缓存的数据
* @return 缓存数据的对象 * @return 缓存数据的对象
*/ */
public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet) public <T> BoundSetOperations<String, T> setCacheSet(String key, Set<T> dataSet)
{ {
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key); BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
Iterator<T> it = dataSet.iterator(); Iterator<T> it = dataSet.iterator();
while (it.hasNext()) while (it.hasNext())
{ {
setOperation.add(it.next()); setOperation.add(it.next());
} }
return setOperation; return setOperation;
} }
/** /**
* 获得缓存的set * 获得缓存的set
* *
* @param key * @param key
* @return * @return
*/ */
public <T> Set<T> getCacheSet(String key) public <T> Set<T> getCacheSet(String key)
{ {
Set<T> dataSet = new HashSet<T>(); Set<T> dataSet = new HashSet<T>();
BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key); BoundSetOperations<String, T> operation = redisTemplate.boundSetOps(key);
dataSet = operation.members(); dataSet = operation.members();
return dataSet; return dataSet;
} }
/** /**
* 缓存Map * 缓存Map
* *
* @param key * @param key
* @param dataMap * @param dataMap
* @return * @return
*/ */
public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap) public <T> HashOperations<String, String, T> setCacheMap(String key, Map<String, T> dataMap)
{ {
HashOperations hashOperations = redisTemplate.opsForHash(); HashOperations hashOperations = redisTemplate.opsForHash();
if (null != dataMap) if (null != dataMap)
{ {
for (Map.Entry<String, T> entry : dataMap.entrySet()) for (Map.Entry<String, T> entry : dataMap.entrySet())
{ {
hashOperations.put(key, entry.getKey(), entry.getValue()); hashOperations.put(key, entry.getKey(), entry.getValue());
} }
} }
return hashOperations; return hashOperations;
} }
/** /**
* 获得缓存的Map * 获得缓存的Map
* *
* @param key * @param key
* @return * @return
*/ */
public <T> Map<String, T> getCacheMap(String key) public <T> Map<String, T> getCacheMap(String key)
{ {
Map<String, T> map = redisTemplate.opsForHash().entries(key); Map<String, T> map = redisTemplate.opsForHash().entries(key);
return map; return map;
} }
/** /**
* 获得缓存的基本对象列表 * 获得缓存的基本对象列表
* *
* @param pattern 字符串前缀 * @param pattern 字符串前缀
* @return 对象列表 * @return 对象列表
*/ */
public Collection<String> keys(String pattern) public Collection<String> keys(String pattern)
{ {
return redisTemplate.keys(pattern); return redisTemplate.keys(pattern);
} }
} }

View File

@ -1,228 +1,228 @@
package com.ruoyi.framework.security; package com.ruoyi.framework.security;
import java.util.Collection; import java.util.Collection;
import java.util.Set; import java.util.Set;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.domain.SysUser;
/** /**
* 登录用户身份权限 * 登录用户身份权限
* *
* @author ruoyi * @author ruoyi
*/ */
public class LoginUser implements UserDetails public class LoginUser implements UserDetails
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 用户唯一标识 * 用户唯一标识
*/ */
private String token; private String token;
/** /**
* 登陆时间 * 登陆时间
*/ */
private Long loginTime; private Long loginTime;
/** /**
* 过期时间 * 过期时间
*/ */
private Long expireTime; private Long expireTime;
/** /**
* 登录IP地址 * 登录IP地址
*/ */
private String ipaddr; private String ipaddr;
/** /**
* 登录地点 * 登录地点
*/ */
private String loginLocation; private String loginLocation;
/** /**
* 浏览器类型 * 浏览器类型
*/ */
private String browser; private String browser;
/** /**
* 操作系统 * 操作系统
*/ */
private String os; private String os;
/** /**
* 权限列表 * 权限列表
*/ */
private Set<String> permissions; private Set<String> permissions;
/** /**
* 用户信息 * 用户信息
*/ */
private SysUser user; private SysUser user;
public String getToken() public String getToken()
{ {
return token; return token;
} }
public void setToken(String token) public void setToken(String token)
{ {
this.token = token; this.token = token;
} }
public LoginUser() public LoginUser()
{ {
} }
public LoginUser(SysUser user, Set<String> permissions) public LoginUser(SysUser user, Set<String> permissions)
{ {
this.user = user; this.user = user;
this.permissions = permissions; this.permissions = permissions;
} }
@JsonIgnore @JsonIgnore
@Override @Override
public String getPassword() public String getPassword()
{ {
return user.getPassword(); return user.getPassword();
} }
@Override @Override
public String getUsername() public String getUsername()
{ {
return user.getUserName(); return user.getUserName();
} }
/** /**
* 账户是否未过期,过期无法验证 * 账户是否未过期,过期无法验证
*/ */
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isAccountNonExpired() public boolean isAccountNonExpired()
{ {
return true; return true;
} }
/** /**
* 指定用户是否解锁,锁定的用户无法进行身份验证 * 指定用户是否解锁,锁定的用户无法进行身份验证
* *
* @return * @return
*/ */
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isAccountNonLocked() public boolean isAccountNonLocked()
{ {
return true; return true;
} }
/** /**
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
* *
* @return * @return
*/ */
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isCredentialsNonExpired() public boolean isCredentialsNonExpired()
{ {
return true; return true;
} }
/** /**
* 是否可用 ,禁用的用户不能身份验证 * 是否可用 ,禁用的用户不能身份验证
* *
* @return * @return
*/ */
@JsonIgnore @JsonIgnore
@Override @Override
public boolean isEnabled() public boolean isEnabled()
{ {
return true; return true;
} }
public Long getLoginTime() public Long getLoginTime()
{ {
return loginTime; return loginTime;
} }
public void setLoginTime(Long loginTime) public void setLoginTime(Long loginTime)
{ {
this.loginTime = loginTime; this.loginTime = loginTime;
} }
public String getIpaddr() public String getIpaddr()
{ {
return ipaddr; return ipaddr;
} }
public void setIpaddr(String ipaddr) public void setIpaddr(String ipaddr)
{ {
this.ipaddr = ipaddr; this.ipaddr = ipaddr;
} }
public String getLoginLocation() public String getLoginLocation()
{ {
return loginLocation; return loginLocation;
} }
public void setLoginLocation(String loginLocation) public void setLoginLocation(String loginLocation)
{ {
this.loginLocation = loginLocation; this.loginLocation = loginLocation;
} }
public String getBrowser() public String getBrowser()
{ {
return browser; return browser;
} }
public void setBrowser(String browser) public void setBrowser(String browser)
{ {
this.browser = browser; this.browser = browser;
} }
public String getOs() public String getOs()
{ {
return os; return os;
} }
public void setOs(String os) public void setOs(String os)
{ {
this.os = os; this.os = os;
} }
public Long getExpireTime() public Long getExpireTime()
{ {
return expireTime; return expireTime;
} }
public void setExpireTime(Long expireTime) public void setExpireTime(Long expireTime)
{ {
this.expireTime = expireTime; this.expireTime = expireTime;
} }
public Set<String> getPermissions() public Set<String> getPermissions()
{ {
return permissions; return permissions;
} }
public void setPermissions(Set<String> permissions) public void setPermissions(Set<String> permissions)
{ {
this.permissions = permissions; this.permissions = permissions;
} }
public SysUser getUser() public SysUser getUser()
{ {
return user; return user;
} }
public void setUser(SysUser user) public void setUser(SysUser user)
{ {
this.user = user; this.user = user;
} }
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() public Collection<? extends GrantedAuthority> getAuthorities()
{ {
return null; return null;
} }
} }

View File

@ -1,44 +1,44 @@
package com.ruoyi.framework.security.filter; package com.ruoyi.framework.security.filter;
import java.io.IOException; import java.io.IOException;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.security.service.TokenService; import com.ruoyi.framework.security.service.TokenService;
/** /**
* token过滤器 验证token有效性 * token过滤器 验证token有效性
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{ {
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
@Override @Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException throws ServletException, IOException
{ {
LoginUser loginUser = tokenService.getLoginUser(request); LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
{ {
tokenService.verifyToken(loginUser); tokenService.verifyToken(loginUser);
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken); SecurityContextHolder.getContext().setAuthentication(authenticationToken);
} }
chain.doFilter(request, response); chain.doFilter(request, response);
} }
} }

View File

@ -1,34 +1,34 @@
package com.ruoyi.framework.security.handle; package com.ruoyi.framework.security.handle;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.framework.web.domain.AjaxResult;
/** /**
* 认证失败处理类 返回未授权 * 认证失败处理类 返回未授权
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable
{ {
private static final long serialVersionUID = -8970718410437077606L; private static final long serialVersionUID = -8970718410437077606L;
@Override @Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException throws IOException
{ {
int code = HttpStatus.UNAUTHORIZED; int code = HttpStatus.UNAUTHORIZED;
String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
} }
} }

View File

@ -1,53 +1,53 @@
package com.ruoyi.framework.security.handle; package com.ruoyi.framework.security.handle;
import java.io.IOException; import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.security.service.TokenService; import com.ruoyi.framework.security.service.TokenService;
import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.framework.web.domain.AjaxResult;
/** /**
* 自定义退出处理类 返回成功 * 自定义退出处理类 返回成功
* *
* @author ruoyi * @author ruoyi
*/ */
@Configuration @Configuration
public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
{ {
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
/** /**
* 退出处理 * 退出处理
* *
* @return * @return
*/ */
@Override @Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException throws IOException, ServletException
{ {
LoginUser loginUser = tokenService.getLoginUser(request); LoginUser loginUser = tokenService.getLoginUser(request);
if (StringUtils.isNotNull(loginUser)) if (StringUtils.isNotNull(loginUser))
{ {
String userName = loginUser.getUsername(); String userName = loginUser.getUsername();
// 删除用户缓存记录 // 删除用户缓存记录
tokenService.delLoginUser(loginUser.getToken()); tokenService.delLoginUser(loginUser.getToken());
// 记录用户退出日志 // 记录用户退出日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功"));
} }
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功"))); ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
} }
} }

View File

@ -1,169 +1,169 @@
package com.ruoyi.framework.security.service; package com.ruoyi.framework.security.service;
import java.util.Set; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.project.system.domain.SysRole; import com.ruoyi.project.system.domain.SysRole;
/** /**
* RuoYi首创 自定义权限实现ss取自SpringSecurity首字母 * RuoYi首创 自定义权限实现ss取自SpringSecurity首字母
* *
* @author ruoyi * @author ruoyi
*/ */
@Service("ss") @Service("ss")
public class PermissionService public class PermissionService
{ {
/** 所有权限标识 */ /** 所有权限标识 */
private static final String ALL_PERMISSION = "*:*:*"; private static final String ALL_PERMISSION = "*:*:*";
/** 管理员角色权限标识 */ /** 管理员角色权限标识 */
private static final String SUPER_ADMIN = "admin"; private static final String SUPER_ADMIN = "admin";
private static final String ROLE_DELIMETER = ","; private static final String ROLE_DELIMETER = ",";
private static final String PERMISSION_DELIMETER = ","; private static final String PERMISSION_DELIMETER = ",";
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
/** /**
* 验证用户是否具备某权限 * 验证用户是否具备某权限
* *
* @param permission 权限字符串 * @param permission 权限字符串
* @return 用户是否具备某权限 * @return 用户是否具备某权限
*/ */
public boolean hasPermi(String permission) public boolean hasPermi(String permission)
{ {
if (StringUtils.isEmpty(permission)) if (StringUtils.isEmpty(permission))
{ {
return false; return false;
} }
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
{ {
return false; return false;
} }
return hasPermissions(loginUser.getPermissions(), permission); return hasPermissions(loginUser.getPermissions(), permission);
} }
/** /**
* 验证用户是否不具备某权限,与 hasPermi逻辑相反 * 验证用户是否不具备某权限,与 hasPermi逻辑相反
* *
* @param permission 权限字符串 * @param permission 权限字符串
* @return 用户是否不具备某权限 * @return 用户是否不具备某权限
*/ */
public boolean lacksPermi(String permission) public boolean lacksPermi(String permission)
{ {
return hasPermi(permission) != true; return hasPermi(permission) != true;
} }
/** /**
* 验证用户是否具有以下任意一个权限 * 验证用户是否具有以下任意一个权限
* *
* @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表 * @param permissions 以 PERMISSION_NAMES_DELIMETER 为分隔符的权限列表
* @return 用户是否具有以下任意一个权限 * @return 用户是否具有以下任意一个权限
*/ */
public boolean hasAnyPermi(String permissions) public boolean hasAnyPermi(String permissions)
{ {
if (StringUtils.isEmpty(permissions)) if (StringUtils.isEmpty(permissions))
{ {
return false; return false;
} }
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions()))
{ {
return false; return false;
} }
Set<String> authorities = loginUser.getPermissions(); Set<String> authorities = loginUser.getPermissions();
for (String permission : permissions.split(PERMISSION_DELIMETER)) for (String permission : permissions.split(PERMISSION_DELIMETER))
{ {
if (permission != null && hasPermissions(authorities, permission)) if (permission != null && hasPermissions(authorities, permission))
{ {
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* 判断用户是否拥有某个角色 * 判断用户是否拥有某个角色
* *
* @param role 角色字符串 * @param role 角色字符串
* @return 用户是否具备某角色 * @return 用户是否具备某角色
*/ */
public boolean hasRole(String role) public boolean hasRole(String role)
{ {
if (StringUtils.isEmpty(role)) if (StringUtils.isEmpty(role))
{ {
return false; return false;
} }
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
{ {
return false; return false;
} }
for (SysRole sysRole : loginUser.getUser().getRoles()) for (SysRole sysRole : loginUser.getUser().getRoles())
{ {
String roleKey = sysRole.getRoleKey(); String roleKey = sysRole.getRoleKey();
if (SUPER_ADMIN.contains(roleKey) || roleKey.contains(StringUtils.trim(role))) if (SUPER_ADMIN.contains(roleKey) || roleKey.contains(StringUtils.trim(role)))
{ {
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* 验证用户是否不具备某角色,与 isRole逻辑相反。 * 验证用户是否不具备某角色,与 isRole逻辑相反。
* *
* @param role 角色名称 * @param role 角色名称
* @return 用户是否不具备某角色 * @return 用户是否不具备某角色
*/ */
public boolean lacksRole(String role) public boolean lacksRole(String role)
{ {
return hasRole(role) != true; return hasRole(role) != true;
} }
/** /**
* 验证用户是否具有以下任意一个角色 * 验证用户是否具有以下任意一个角色
* *
* @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表 * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
* @return 用户是否具有以下任意一个角色 * @return 用户是否具有以下任意一个角色
*/ */
public boolean hasAnyRoles(String roles) public boolean hasAnyRoles(String roles)
{ {
if (StringUtils.isEmpty(roles)) if (StringUtils.isEmpty(roles))
{ {
return false; return false;
} }
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles())) if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getUser().getRoles()))
{ {
return false; return false;
} }
for (String role : roles.split(ROLE_DELIMETER)) for (String role : roles.split(ROLE_DELIMETER))
{ {
if (hasRole(role)) if (hasRole(role))
{ {
return true; return true;
} }
} }
return false; return false;
} }
/** /**
* 判断是否包含权限 * 判断是否包含权限
* *
* @param permissions 权限列表 * @param permissions 权限列表
* @param permission 权限字符串 * @param permission 权限字符串
* @return 用户是否具备某权限 * @return 用户是否具备某权限
*/ */
private boolean hasPermissions(Set<String> permissions, String permission) private boolean hasPermissions(Set<String> permissions, String permission)
{ {
return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission)); return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
} }
} }

View File

@ -1,88 +1,88 @@
package com.ruoyi.framework.security.service; package com.ruoyi.framework.security.service;
import javax.annotation.Resource; import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.CustomException; import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.exception.user.CaptchaException; import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException; import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.redis.RedisCache; import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
/** /**
* 登录校验方法 * 登录校验方法
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class SysLoginService public class SysLoginService
{ {
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
@Resource @Resource
private AuthenticationManager authenticationManager; private AuthenticationManager authenticationManager;
@Autowired @Autowired
private RedisCache redisCache; private RedisCache redisCache;
/** /**
* 登录验证 * 登录验证
* *
* @param username 用户名 * @param username 用户名
* @param password 密码 * @param password 密码
* @param captcha 验证码 * @param captcha 验证码
* @param uuid 唯一标识 * @param uuid 唯一标识
* @return 结果 * @return 结果
*/ */
public String login(String username, String password, String code, String uuid) public String login(String username, String password, String code, String uuid)
{ {
String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
String captcha = redisCache.getCacheObject(verifyKey); String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey); redisCache.deleteObject(verifyKey);
if (captcha == null) if (captcha == null)
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException(); throw new CaptchaExpireException();
} }
if (!code.equalsIgnoreCase(captcha)) if (!code.equalsIgnoreCase(captcha))
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
throw new CaptchaException(); throw new CaptchaException();
} }
// 用户验证 // 用户验证
Authentication authentication = null; Authentication authentication = null;
try try
{ {
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
authentication = authenticationManager authentication = authenticationManager
.authenticate(new UsernamePasswordAuthenticationToken(username, password)); .authenticate(new UsernamePasswordAuthenticationToken(username, password));
} }
catch (Exception e) catch (Exception e)
{ {
if (e instanceof BadCredentialsException) if (e instanceof BadCredentialsException)
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
throw new UserPasswordNotMatchException(); throw new UserPasswordNotMatchException();
} }
else else
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage())); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
throw new CustomException(e.getMessage()); throw new CustomException(e.getMessage());
} }
} }
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) authentication.getPrincipal(); LoginUser loginUser = (LoginUser) authentication.getPrincipal();
// 生成token // 生成token
return tokenService.createToken(loginUser); return tokenService.createToken(loginUser);
} }
} }

View File

@ -1,66 +1,66 @@
package com.ruoyi.framework.security.service; package com.ruoyi.framework.security.service;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysMenuService; import com.ruoyi.project.system.service.ISysMenuService;
import com.ruoyi.project.system.service.ISysRoleService; import com.ruoyi.project.system.service.ISysRoleService;
/** /**
* 用户权限处理 * 用户权限处理
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class SysPermissionService public class SysPermissionService
{ {
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired @Autowired
private ISysMenuService menuService; private ISysMenuService menuService;
/** /**
* 获取角色数据权限 * 获取角色数据权限
* *
* @param user 用户信息 * @param user 用户信息
* @return 角色权限信息 * @return 角色权限信息
*/ */
public Set<String> getRolePermission(SysUser user) public Set<String> getRolePermission(SysUser user)
{ {
Set<String> roles = new HashSet<String>(); Set<String> roles = new HashSet<String>();
// 管理员拥有所有权限 // 管理员拥有所有权限
if (user.isAdmin()) if (user.isAdmin())
{ {
roles.add("admin"); roles.add("admin");
} }
else else
{ {
roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId())); roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
} }
return roles; return roles;
} }
/** /**
* 获取菜单数据权限 * 获取菜单数据权限
* *
* @param user 用户信息 * @param user 用户信息
* @return 菜单权限信息 * @return 菜单权限信息
*/ */
public Set<String> getMenuPermission(SysUser user) public Set<String> getMenuPermission(SysUser user)
{ {
Set<String> perms = new HashSet<String>(); Set<String> perms = new HashSet<String>();
// 管理员拥有所有权限 // 管理员拥有所有权限
if (user.isAdmin()) if (user.isAdmin())
{ {
perms.add("*:*:*"); perms.add("*:*:*");
} }
else else
{ {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
} }
return perms; return perms;
} }
} }

View File

@ -1,219 +1,219 @@
package com.ruoyi.framework.security.service; package com.ruoyi.framework.security.service;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.IdUtils; import com.ruoyi.common.utils.IdUtils;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.AddressUtils; import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.redis.RedisCache; import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import eu.bitwalker.useragentutils.UserAgent; import eu.bitwalker.useragentutils.UserAgent;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts; import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureAlgorithm;
/** /**
* token验证处理 * token验证处理
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public class TokenService public class TokenService
{ {
// 令牌自定义标识 // 令牌自定义标识
@Value("${token.header}") @Value("${token.header}")
private String header; private String header;
// 令牌秘钥 // 令牌秘钥
@Value("${token.secret}") @Value("${token.secret}")
private String secret; private String secret;
// 令牌有效期默认30分钟 // 令牌有效期默认30分钟
@Value("${token.expireTime}") @Value("${token.expireTime}")
private int expireTime; private int expireTime;
protected static final long MILLIS_SECOND = 1000; protected static final long MILLIS_SECOND = 1000;
protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;
private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L; private static final Long MILLIS_MINUTE_TEN = 20 * 60 * 1000L;
@Autowired @Autowired
private RedisCache redisCache; private RedisCache redisCache;
/** /**
* 获取用户身份信息 * 获取用户身份信息
* *
* @return 用户信息 * @return 用户信息
*/ */
public LoginUser getLoginUser(HttpServletRequest request) public LoginUser getLoginUser(HttpServletRequest request)
{ {
// 获取请求携带的令牌 // 获取请求携带的令牌
String token = getToken(request); String token = getToken(request);
if (StringUtils.isNotEmpty(token)) if (StringUtils.isNotEmpty(token))
{ {
Claims claims = parseToken(token); Claims claims = parseToken(token);
// 解析对应的权限以及用户信息 // 解析对应的权限以及用户信息
String uuid = (String) claims.get(Constants.LOGIN_USER_KEY); String uuid = (String) claims.get(Constants.LOGIN_USER_KEY);
String userKey = getTokenKey(uuid); String userKey = getTokenKey(uuid);
LoginUser user = redisCache.getCacheObject(userKey); LoginUser user = redisCache.getCacheObject(userKey);
return user; return user;
} }
return null; return null;
} }
/** /**
* 设置用户身份信息 * 设置用户身份信息
*/ */
public void setLoginUser(LoginUser loginUser) public void setLoginUser(LoginUser loginUser)
{ {
if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken()))
{ {
refreshToken(loginUser); refreshToken(loginUser);
} }
} }
/** /**
* 删除用户身份信息 * 删除用户身份信息
*/ */
public void delLoginUser(String token) public void delLoginUser(String token)
{ {
if (StringUtils.isNotEmpty(token)) if (StringUtils.isNotEmpty(token))
{ {
String userKey = getTokenKey(token); String userKey = getTokenKey(token);
redisCache.deleteObject(userKey); redisCache.deleteObject(userKey);
} }
} }
/** /**
* 创建令牌 * 创建令牌
* *
* @param loginUser 用户信息 * @param loginUser 用户信息
* @return 令牌 * @return 令牌
*/ */
public String createToken(LoginUser loginUser) public String createToken(LoginUser loginUser)
{ {
String token = IdUtils.fastUUID(); String token = IdUtils.fastUUID();
loginUser.setToken(token); loginUser.setToken(token);
setUserAgent(loginUser); setUserAgent(loginUser);
refreshToken(loginUser); refreshToken(loginUser);
Map<String, Object> claims = new HashMap<>(); Map<String, Object> claims = new HashMap<>();
claims.put(Constants.LOGIN_USER_KEY, token); claims.put(Constants.LOGIN_USER_KEY, token);
return createToken(claims); return createToken(claims);
} }
/** /**
* 验证令牌有效期相差不足20分钟自动刷新缓存 * 验证令牌有效期相差不足20分钟自动刷新缓存
* *
* @param token 令牌 * @param token 令牌
* @return 令牌 * @return 令牌
*/ */
public void verifyToken(LoginUser loginUser) public void verifyToken(LoginUser loginUser)
{ {
long expireTime = loginUser.getExpireTime(); long expireTime = loginUser.getExpireTime();
long currentTime = System.currentTimeMillis(); long currentTime = System.currentTimeMillis();
if (expireTime - currentTime <= MILLIS_MINUTE_TEN) if (expireTime - currentTime <= MILLIS_MINUTE_TEN)
{ {
refreshToken(loginUser); refreshToken(loginUser);
} }
} }
/** /**
* 刷新令牌有效期 * 刷新令牌有效期
* *
* @param loginUser 登录信息 * @param loginUser 登录信息
*/ */
public void refreshToken(LoginUser loginUser) public void refreshToken(LoginUser loginUser)
{ {
loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
// 根据uuid将loginUser缓存 // 根据uuid将loginUser缓存
String userKey = getTokenKey(loginUser.getToken()); String userKey = getTokenKey(loginUser.getToken());
redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES);
} }
/** /**
* 设置用户代理信息 * 设置用户代理信息
* *
* @param loginUser 登录信息 * @param loginUser 登录信息
*/ */
public void setUserAgent(LoginUser loginUser) public void setUserAgent(LoginUser loginUser)
{ {
UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
loginUser.setIpaddr(ip); loginUser.setIpaddr(ip);
loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip));
loginUser.setBrowser(userAgent.getBrowser().getName()); loginUser.setBrowser(userAgent.getBrowser().getName());
loginUser.setOs(userAgent.getOperatingSystem().getName()); loginUser.setOs(userAgent.getOperatingSystem().getName());
} }
/** /**
* 从数据声明生成令牌 * 从数据声明生成令牌
* *
* @param claims 数据声明 * @param claims 数据声明
* @return 令牌 * @return 令牌
*/ */
private String createToken(Map<String, Object> claims) private String createToken(Map<String, Object> claims)
{ {
String token = Jwts.builder() String token = Jwts.builder()
.setClaims(claims) .setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret).compact(); .signWith(SignatureAlgorithm.HS512, secret).compact();
return token; return token;
} }
/** /**
* 从令牌中获取数据声明 * 从令牌中获取数据声明
* *
* @param token 令牌 * @param token 令牌
* @return 数据声明 * @return 数据声明
*/ */
private Claims parseToken(String token) private Claims parseToken(String token)
{ {
return Jwts.parser() return Jwts.parser()
.setSigningKey(secret) .setSigningKey(secret)
.parseClaimsJws(token) .parseClaimsJws(token)
.getBody(); .getBody();
} }
/** /**
* 从令牌中获取用户名 * 从令牌中获取用户名
* *
* @param token 令牌 * @param token 令牌
* @return 用户名 * @return 用户名
*/ */
public String getUsernameFromToken(String token) public String getUsernameFromToken(String token)
{ {
Claims claims = parseToken(token); Claims claims = parseToken(token);
return claims.getSubject(); return claims.getSubject();
} }
/** /**
* 获取请求token * 获取请求token
* *
* @param request * @param request
* @return token * @return token
*/ */
private String getToken(HttpServletRequest request) private String getToken(HttpServletRequest request)
{ {
String token = request.getHeader(header); String token = request.getHeader(header);
if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX))
{ {
token = token.replace(Constants.TOKEN_PREFIX, ""); token = token.replace(Constants.TOKEN_PREFIX, "");
} }
return token; return token;
} }
private String getTokenKey(String uuid) private String getTokenKey(String uuid)
{ {
return Constants.LOGIN_TOKEN_KEY + uuid; return Constants.LOGIN_TOKEN_KEY + uuid;
} }
} }

View File

@ -1,60 +1,60 @@
package com.ruoyi.framework.security.service; package com.ruoyi.framework.security.service;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.common.enums.UserStatus; import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.BaseException; import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.security.LoginUser; import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysUserService; import com.ruoyi.project.system.service.ISysUserService;
/** /**
* 用户验证处理 * 用户验证处理
* *
* @author ruoyi * @author ruoyi
*/ */
@Service @Service
public class UserDetailsServiceImpl implements UserDetailsService public class UserDetailsServiceImpl implements UserDetailsService
{ {
private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class); private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired @Autowired
private SysPermissionService permissionService; private SysPermissionService permissionService;
@Override @Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{ {
SysUser user = userService.selectUserByUserName(username); SysUser user = userService.selectUserByUserName(username);
if (StringUtils.isNull(user)) if (StringUtils.isNull(user))
{ {
log.info("登录用户:{} 不存在.", username); log.info("登录用户:{} 不存在.", username);
throw new UsernameNotFoundException("登录用户:" + username + " 不存在"); throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
} }
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{ {
log.info("登录用户:{} 已被删除.", username); log.info("登录用户:{} 已被删除.", username);
throw new BaseException("对不起,您的账号:" + username + " 已被删除"); throw new BaseException("对不起,您的账号:" + username + " 已被删除");
} }
else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{ {
log.info("登录用户:{} 已被停用.", username); log.info("登录用户:{} 已被停用.", username);
throw new BaseException("对不起,您的账号:" + username + " 已停用"); throw new BaseException("对不起,您的账号:" + username + " 已停用");
} }
return createLoginUser(user); return createLoginUser(user);
} }
public UserDetails createLoginUser(SysUser user) public UserDetails createLoginUser(SysUser user)
{ {
return new LoginUser(user, permissionService.getMenuPermission(user)); return new LoginUser(user, permissionService.getMenuPermission(user));
} }
} }

View File

@ -1,85 +1,85 @@
package com.ruoyi.framework.web.controller; package com.ruoyi.framework.web.controller;
import java.beans.PropertyEditorSupport; import java.beans.PropertyEditorSupport;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.InitBinder;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil; import com.ruoyi.common.utils.sql.SqlUtil;
import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.PageDomain; import com.ruoyi.framework.web.page.PageDomain;
import com.ruoyi.framework.web.page.TableDataInfo; import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.framework.web.page.TableSupport; import com.ruoyi.framework.web.page.TableSupport;
/** /**
* web层通用数据处理 * web层通用数据处理
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseController public class BaseController
{ {
protected final Logger logger = LoggerFactory.getLogger(BaseController.class); protected final Logger logger = LoggerFactory.getLogger(BaseController.class);
/** /**
* 将前台传递过来的日期格式的字符串自动转化为Date类型 * 将前台传递过来的日期格式的字符串自动转化为Date类型
*/ */
@InitBinder @InitBinder
public void initBinder(WebDataBinder binder) public void initBinder(WebDataBinder binder)
{ {
// Date 类型转换 // Date 类型转换
binder.registerCustomEditor(Date.class, new PropertyEditorSupport() binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
{ {
@Override @Override
public void setAsText(String text) public void setAsText(String text)
{ {
setValue(DateUtils.parseDate(text)); setValue(DateUtils.parseDate(text));
} }
}); });
} }
/** /**
* 设置请求分页数据 * 设置请求分页数据
*/ */
protected void startPage() protected void startPage()
{ {
PageDomain pageDomain = TableSupport.buildPageRequest(); PageDomain pageDomain = TableSupport.buildPageRequest();
Integer pageNum = pageDomain.getPageNum(); Integer pageNum = pageDomain.getPageNum();
Integer pageSize = pageDomain.getPageSize(); Integer pageSize = pageDomain.getPageSize();
if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize))
{ {
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.startPage(pageNum, pageSize, orderBy); PageHelper.startPage(pageNum, pageSize, orderBy);
} }
} }
/** /**
* 响应请求分页数据 * 响应请求分页数据
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
protected TableDataInfo getDataTable(List<?> list) protected TableDataInfo getDataTable(List<?> list)
{ {
TableDataInfo rspData = new TableDataInfo(); TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS); rspData.setCode(HttpStatus.SUCCESS);
rspData.setRows(list); rspData.setRows(list);
rspData.setTotal(new PageInfo(list).getTotal()); rspData.setTotal(new PageInfo(list).getTotal());
return rspData; return rspData;
} }
/** /**
* 响应返回结果 * 响应返回结果
* *
* @param rows 影响行数 * @param rows 影响行数
* @return 操作结果 * @return 操作结果
*/ */
protected AjaxResult toAjax(int rows) protected AjaxResult toAjax(int rows)
{ {
return rows > 0 ? AjaxResult.success() : AjaxResult.error(); return rows > 0 ? AjaxResult.success() : AjaxResult.error();
} }
} }

View File

@ -1,148 +1,148 @@
package com.ruoyi.framework.web.domain; package com.ruoyi.framework.web.domain;
import java.util.HashMap; import java.util.HashMap;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 操作消息提醒 * 操作消息提醒
* *
* @author ruoyi * @author ruoyi
*/ */
public class AjaxResult extends HashMap<String, Object> public class AjaxResult extends HashMap<String, Object>
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 状态码 */ /** 状态码 */
public static final String CODE_TAG = "code"; public static final String CODE_TAG = "code";
/** 返回内容 */ /** 返回内容 */
public static final String MSG_TAG = "msg"; public static final String MSG_TAG = "msg";
/** 数据对象 */ /** 数据对象 */
public static final String DATA_TAG = "data"; public static final String DATA_TAG = "data";
/** /**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/ */
public AjaxResult() public AjaxResult()
{ {
} }
/** /**
* 初始化一个新创建的 AjaxResult 对象 * 初始化一个新创建的 AjaxResult 对象
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
*/ */
public AjaxResult(int code, String msg) public AjaxResult(int code, String msg)
{ {
super.put(CODE_TAG, code); super.put(CODE_TAG, code);
super.put(MSG_TAG, msg); super.put(MSG_TAG, msg);
} }
/** /**
* 初始化一个新创建的 AjaxResult 对象 * 初始化一个新创建的 AjaxResult 对象
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
*/ */
public AjaxResult(int code, String msg, Object data) public AjaxResult(int code, String msg, Object data)
{ {
super.put(CODE_TAG, code); super.put(CODE_TAG, code);
super.put(MSG_TAG, msg); super.put(MSG_TAG, msg);
if (StringUtils.isNotNull(data)) if (StringUtils.isNotNull(data))
{ {
super.put(DATA_TAG, data); super.put(DATA_TAG, data);
} }
} }
/** /**
* 返回成功消息 * 返回成功消息
* *
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success() public static AjaxResult success()
{ {
return AjaxResult.success("操作成功"); return AjaxResult.success("操作成功");
} }
/** /**
* 返回成功数据 * 返回成功数据
* *
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success(Object data) public static AjaxResult success(Object data)
{ {
return AjaxResult.success("操作成功", data); return AjaxResult.success("操作成功", data);
} }
/** /**
* 返回成功消息 * 返回成功消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success(String msg) public static AjaxResult success(String msg)
{ {
return AjaxResult.success(msg, null); return AjaxResult.success(msg, null);
} }
/** /**
* 返回成功消息 * 返回成功消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success(String msg, Object data) public static AjaxResult success(String msg, Object data)
{ {
return new AjaxResult(HttpStatus.SUCCESS, msg, data); return new AjaxResult(HttpStatus.SUCCESS, msg, data);
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @return * @return
*/ */
public static AjaxResult error() public static AjaxResult error()
{ {
return AjaxResult.error("操作失败"); return AjaxResult.error("操作失败");
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @return 警告消息 * @return 警告消息
*/ */
public static AjaxResult error(String msg) public static AjaxResult error(String msg)
{ {
return AjaxResult.error(msg, null); return AjaxResult.error(msg, null);
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
* @return 警告消息 * @return 警告消息
*/ */
public static AjaxResult error(String msg, Object data) public static AjaxResult error(String msg, Object data)
{ {
return new AjaxResult(HttpStatus.ERROR, msg, data); return new AjaxResult(HttpStatus.ERROR, msg, data);
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
* @return 警告消息 * @return 警告消息
*/ */
public static AjaxResult error(int code, String msg) public static AjaxResult error(int code, String msg)
{ {
return new AjaxResult(code, msg, null); return new AjaxResult(code, msg, null);
} }
} }

View File

@ -1,156 +1,156 @@
package com.ruoyi.framework.web.domain; package com.ruoyi.framework.web.domain;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
/** /**
* Entity基类 * Entity基类
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseEntity implements Serializable public class BaseEntity implements Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 搜索值 */ /** 搜索值 */
private String searchValue; private String searchValue;
/** 创建者 */ /** 创建者 */
private String createBy; private String createBy;
/** 创建时间 */ /** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; private Date createTime;
/** 更新者 */ /** 更新者 */
private String updateBy; private String updateBy;
/** 更新时间 */ /** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime; private Date updateTime;
/** 备注 */ /** 备注 */
private String remark; private String remark;
/** 数据权限 */ /** 数据权限 */
private String dataScope; private String dataScope;
/** 开始时间 */ /** 开始时间 */
@JsonIgnore @JsonIgnore
private String beginTime; private String beginTime;
/** 结束时间 */ /** 结束时间 */
@JsonIgnore @JsonIgnore
private String endTime; private String endTime;
/** 请求参数 */ /** 请求参数 */
private Map<String, Object> params; private Map<String, Object> params;
public String getSearchValue() public String getSearchValue()
{ {
return searchValue; return searchValue;
} }
public void setSearchValue(String searchValue) public void setSearchValue(String searchValue)
{ {
this.searchValue = searchValue; this.searchValue = searchValue;
} }
public String getCreateBy() public String getCreateBy()
{ {
return createBy; return createBy;
} }
public void setCreateBy(String createBy) public void setCreateBy(String createBy)
{ {
this.createBy = createBy; this.createBy = createBy;
} }
public Date getCreateTime() public Date getCreateTime()
{ {
return createTime; return createTime;
} }
public void setCreateTime(Date createTime) public void setCreateTime(Date createTime)
{ {
this.createTime = createTime; this.createTime = createTime;
} }
public String getUpdateBy() public String getUpdateBy()
{ {
return updateBy; return updateBy;
} }
public void setUpdateBy(String updateBy) public void setUpdateBy(String updateBy)
{ {
this.updateBy = updateBy; this.updateBy = updateBy;
} }
public Date getUpdateTime() public Date getUpdateTime()
{ {
return updateTime; return updateTime;
} }
public void setUpdateTime(Date updateTime) public void setUpdateTime(Date updateTime)
{ {
this.updateTime = updateTime; this.updateTime = updateTime;
} }
public String getRemark() public String getRemark()
{ {
return remark; return remark;
} }
public void setRemark(String remark) public void setRemark(String remark)
{ {
this.remark = remark; this.remark = remark;
} }
public String getDataScope() public String getDataScope()
{ {
return dataScope; return dataScope;
} }
public void setDataScope(String dataScope) public void setDataScope(String dataScope)
{ {
this.dataScope = dataScope; this.dataScope = dataScope;
} }
public String getBeginTime() public String getBeginTime()
{ {
return beginTime; return beginTime;
} }
public void setBeginTime(String beginTime) public void setBeginTime(String beginTime)
{ {
this.beginTime = beginTime; this.beginTime = beginTime;
} }
public String getEndTime() public String getEndTime()
{ {
return endTime; return endTime;
} }
public void setEndTime(String endTime) public void setEndTime(String endTime)
{ {
this.endTime = endTime; this.endTime = endTime;
} }
public Map<String, Object> getParams() public Map<String, Object> getParams()
{ {
if (params == null) if (params == null)
{ {
params = new HashMap<>(); params = new HashMap<>();
} }
return params; return params;
} }
public void setParams(Map<String, Object> params) public void setParams(Map<String, Object> params)
{ {
this.params = params; this.params = params;
} }
} }

View File

@ -1,240 +1,240 @@
package com.ruoyi.framework.web.domain; package com.ruoyi.framework.web.domain;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import com.ruoyi.common.utils.Arith; import com.ruoyi.common.utils.Arith;
import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.framework.web.domain.server.Cpu; import com.ruoyi.framework.web.domain.server.Cpu;
import com.ruoyi.framework.web.domain.server.Jvm; import com.ruoyi.framework.web.domain.server.Jvm;
import com.ruoyi.framework.web.domain.server.Mem; import com.ruoyi.framework.web.domain.server.Mem;
import com.ruoyi.framework.web.domain.server.Sys; import com.ruoyi.framework.web.domain.server.Sys;
import com.ruoyi.framework.web.domain.server.SysFile; import com.ruoyi.framework.web.domain.server.SysFile;
import oshi.SystemInfo; import oshi.SystemInfo;
import oshi.hardware.CentralProcessor; import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType; import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory; import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer; import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem; import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore; import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem; import oshi.software.os.OperatingSystem;
import oshi.util.Util; import oshi.util.Util;
/** /**
* 服务器相关信息 * 服务器相关信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Server public class Server
{ {
private static final int OSHI_WAIT_SECOND = 1000; private static final int OSHI_WAIT_SECOND = 1000;
/** /**
* CPU相关信息 * CPU相关信息
*/ */
private Cpu cpu = new Cpu(); private Cpu cpu = new Cpu();
/** /**
* 內存相关信息 * 內存相关信息
*/ */
private Mem mem = new Mem(); private Mem mem = new Mem();
/** /**
* JVM相关信息 * JVM相关信息
*/ */
private Jvm jvm = new Jvm(); private Jvm jvm = new Jvm();
/** /**
* 服务器相关信息 * 服务器相关信息
*/ */
private Sys sys = new Sys(); private Sys sys = new Sys();
/** /**
* 磁盘相关信息 * 磁盘相关信息
*/ */
private List<SysFile> sysFiles = new LinkedList<SysFile>(); private List<SysFile> sysFiles = new LinkedList<SysFile>();
public Cpu getCpu() public Cpu getCpu()
{ {
return cpu; return cpu;
} }
public void setCpu(Cpu cpu) public void setCpu(Cpu cpu)
{ {
this.cpu = cpu; this.cpu = cpu;
} }
public Mem getMem() public Mem getMem()
{ {
return mem; return mem;
} }
public void setMem(Mem mem) public void setMem(Mem mem)
{ {
this.mem = mem; this.mem = mem;
} }
public Jvm getJvm() public Jvm getJvm()
{ {
return jvm; return jvm;
} }
public void setJvm(Jvm jvm) public void setJvm(Jvm jvm)
{ {
this.jvm = jvm; this.jvm = jvm;
} }
public Sys getSys() public Sys getSys()
{ {
return sys; return sys;
} }
public void setSys(Sys sys) public void setSys(Sys sys)
{ {
this.sys = sys; this.sys = sys;
} }
public List<SysFile> getSysFiles() public List<SysFile> getSysFiles()
{ {
return sysFiles; return sysFiles;
} }
public void setSysFiles(List<SysFile> sysFiles) public void setSysFiles(List<SysFile> sysFiles)
{ {
this.sysFiles = sysFiles; this.sysFiles = sysFiles;
} }
public void copyTo() throws Exception public void copyTo() throws Exception
{ {
SystemInfo si = new SystemInfo(); SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware(); HardwareAbstractionLayer hal = si.getHardware();
setCpuInfo(hal.getProcessor()); setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory()); setMemInfo(hal.getMemory());
setSysInfo(); setSysInfo();
setJvmInfo(); setJvmInfo();
setSysFiles(si.getOperatingSystem()); setSysFiles(si.getOperatingSystem());
} }
/** /**
* 设置CPU信息 * 设置CPU信息
*/ */
private void setCpuInfo(CentralProcessor processor) private void setCpuInfo(CentralProcessor processor)
{ {
// CPU信息 // CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks(); long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND); Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks(); long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal; long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount()); cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(totalCpu); cpu.setTotal(totalCpu);
cpu.setSys(cSys); cpu.setSys(cSys);
cpu.setUsed(user); cpu.setUsed(user);
cpu.setWait(iowait); cpu.setWait(iowait);
cpu.setFree(idle); cpu.setFree(idle);
} }
/** /**
* 设置内存信息 * 设置内存信息
*/ */
private void setMemInfo(GlobalMemory memory) private void setMemInfo(GlobalMemory memory)
{ {
mem.setTotal(memory.getTotal()); mem.setTotal(memory.getTotal());
mem.setUsed(memory.getTotal() - memory.getAvailable()); mem.setUsed(memory.getTotal() - memory.getAvailable());
mem.setFree(memory.getAvailable()); mem.setFree(memory.getAvailable());
} }
/** /**
* 设置服务器信息 * 设置服务器信息
*/ */
private void setSysInfo() private void setSysInfo()
{ {
Properties props = System.getProperties(); Properties props = System.getProperties();
sys.setComputerName(IpUtils.getHostName()); sys.setComputerName(IpUtils.getHostName());
sys.setComputerIp(IpUtils.getHostIp()); sys.setComputerIp(IpUtils.getHostIp());
sys.setOsName(props.getProperty("os.name")); sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch")); sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir")); sys.setUserDir(props.getProperty("user.dir"));
} }
/** /**
* 设置Java虚拟机 * 设置Java虚拟机
*/ */
private void setJvmInfo() throws UnknownHostException private void setJvmInfo() throws UnknownHostException
{ {
Properties props = System.getProperties(); Properties props = System.getProperties();
jvm.setTotal(Runtime.getRuntime().totalMemory()); jvm.setTotal(Runtime.getRuntime().totalMemory());
jvm.setMax(Runtime.getRuntime().maxMemory()); jvm.setMax(Runtime.getRuntime().maxMemory());
jvm.setFree(Runtime.getRuntime().freeMemory()); jvm.setFree(Runtime.getRuntime().freeMemory());
jvm.setVersion(props.getProperty("java.version")); jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home")); jvm.setHome(props.getProperty("java.home"));
} }
/** /**
* 设置磁盘信息 * 设置磁盘信息
*/ */
private void setSysFiles(OperatingSystem os) private void setSysFiles(OperatingSystem os)
{ {
FileSystem fileSystem = os.getFileSystem(); FileSystem fileSystem = os.getFileSystem();
OSFileStore[] fsArray = fileSystem.getFileStores(); OSFileStore[] fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray) for (OSFileStore fs : fsArray)
{ {
long free = fs.getUsableSpace(); long free = fs.getUsableSpace();
long total = fs.getTotalSpace(); long total = fs.getTotalSpace();
long used = total - free; long used = total - free;
SysFile sysFile = new SysFile(); SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount()); sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType()); sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName()); sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total)); sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free)); sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used)); sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100)); sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
sysFiles.add(sysFile); sysFiles.add(sysFile);
} }
} }
/** /**
* 字节转换 * 字节转换
* *
* @param size 字节大小 * @param size 字节大小
* @return 转换后值 * @return 转换后值
*/ */
public String convertFileSize(long size) public String convertFileSize(long size)
{ {
long kb = 1024; long kb = 1024;
long mb = kb * 1024; long mb = kb * 1024;
long gb = mb * 1024; long gb = mb * 1024;
if (size >= gb) if (size >= gb)
{ {
return String.format("%.1f GB", (float) size / gb); return String.format("%.1f GB", (float) size / gb);
} }
else if (size >= mb) else if (size >= mb)
{ {
float f = (float) size / mb; float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
} }
else if (size >= kb) else if (size >= kb)
{ {
float f = (float) size / kb; float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
} }
else else
{ {
return String.format("%d B", size); return String.format("%d B", size);
} }
} }
} }

View File

@ -1,79 +1,79 @@
package com.ruoyi.framework.web.domain; package com.ruoyi.framework.web.domain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Tree基类 * Tree基类
* *
* @author ruoyi * @author ruoyi
*/ */
public class TreeEntity extends BaseEntity public class TreeEntity extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 父菜单名称 */ /** 父菜单名称 */
private String parentName; private String parentName;
/** 父菜单ID */ /** 父菜单ID */
private Long parentId; private Long parentId;
/** 显示顺序 */ /** 显示顺序 */
private Integer orderNum; private Integer orderNum;
/** 祖级列表 */ /** 祖级列表 */
private String ancestors; private String ancestors;
/** 子部门 */ /** 子部门 */
private List<?> children = new ArrayList<>(); private List<?> children = new ArrayList<>();
public String getParentName() public String getParentName()
{ {
return parentName; return parentName;
} }
public void setParentName(String parentName) public void setParentName(String parentName)
{ {
this.parentName = parentName; this.parentName = parentName;
} }
public Long getParentId() public Long getParentId()
{ {
return parentId; return parentId;
} }
public void setParentId(Long parentId) public void setParentId(Long parentId)
{ {
this.parentId = parentId; this.parentId = parentId;
} }
public Integer getOrderNum() public Integer getOrderNum()
{ {
return orderNum; return orderNum;
} }
public void setOrderNum(Integer orderNum) public void setOrderNum(Integer orderNum)
{ {
this.orderNum = orderNum; this.orderNum = orderNum;
} }
public String getAncestors() public String getAncestors()
{ {
return ancestors; return ancestors;
} }
public void setAncestors(String ancestors) public void setAncestors(String ancestors)
{ {
this.ancestors = ancestors; this.ancestors = ancestors;
} }
public List<?> getChildren() public List<?> getChildren()
{ {
return children; return children;
} }
public void setChildren(List<?> children) public void setChildren(List<?> children)
{ {
this.children = children; this.children = children;
} }
} }

View File

@ -1,77 +1,77 @@
package com.ruoyi.framework.web.domain; package com.ruoyi.framework.web.domain;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysMenu; import com.ruoyi.project.system.domain.SysMenu;
/** /**
* Treeselect树结构实体类 * Treeselect树结构实体类
* *
* @author ruoyi * @author ruoyi
*/ */
public class TreeSelect implements Serializable public class TreeSelect implements Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 节点ID */ /** 节点ID */
private Long id; private Long id;
/** 节点名称 */ /** 节点名称 */
private String label; private String label;
/** 子节点 */ /** 子节点 */
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<TreeSelect> children; private List<TreeSelect> children;
public TreeSelect() public TreeSelect()
{ {
} }
public TreeSelect(SysDept dept) public TreeSelect(SysDept dept)
{ {
this.id = dept.getDeptId(); this.id = dept.getDeptId();
this.label = dept.getDeptName(); this.label = dept.getDeptName();
this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
} }
public TreeSelect(SysMenu menu) public TreeSelect(SysMenu menu)
{ {
this.id = menu.getMenuId(); this.id = menu.getMenuId();
this.label = menu.getMenuName(); this.label = menu.getMenuName();
this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
} }
public Long getId() public Long getId()
{ {
return id; return id;
} }
public void setId(Long id) public void setId(Long id)
{ {
this.id = id; this.id = id;
} }
public String getLabel() public String getLabel()
{ {
return label; return label;
} }
public void setLabel(String label) public void setLabel(String label)
{ {
this.label = label; this.label = label;
} }
public List<TreeSelect> getChildren() public List<TreeSelect> getChildren()
{ {
return children; return children;
} }
public void setChildren(List<TreeSelect> children) public void setChildren(List<TreeSelect> children)
{ {
this.children = children; this.children = children;
} }
} }

View File

@ -1,101 +1,101 @@
package com.ruoyi.framework.web.domain.server; package com.ruoyi.framework.web.domain.server;
import com.ruoyi.common.utils.Arith; import com.ruoyi.common.utils.Arith;
/** /**
* CPU相关信息 * CPU相关信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Cpu public class Cpu
{ {
/** /**
* 核心数 * 核心数
*/ */
private int cpuNum; private int cpuNum;
/** /**
* CPU总的使用率 * CPU总的使用率
*/ */
private double total; private double total;
/** /**
* CPU系统使用率 * CPU系统使用率
*/ */
private double sys; private double sys;
/** /**
* CPU用户使用率 * CPU用户使用率
*/ */
private double used; private double used;
/** /**
* CPU当前等待率 * CPU当前等待率
*/ */
private double wait; private double wait;
/** /**
* CPU当前空闲率 * CPU当前空闲率
*/ */
private double free; private double free;
public int getCpuNum() public int getCpuNum()
{ {
return cpuNum; return cpuNum;
} }
public void setCpuNum(int cpuNum) public void setCpuNum(int cpuNum)
{ {
this.cpuNum = cpuNum; this.cpuNum = cpuNum;
} }
public double getTotal() public double getTotal()
{ {
return Arith.round(Arith.mul(total, 100), 2); return Arith.round(Arith.mul(total, 100), 2);
} }
public void setTotal(double total) public void setTotal(double total)
{ {
this.total = total; this.total = total;
} }
public double getSys() public double getSys()
{ {
return Arith.round(Arith.mul(sys / total, 100), 2); return Arith.round(Arith.mul(sys / total, 100), 2);
} }
public void setSys(double sys) public void setSys(double sys)
{ {
this.sys = sys; this.sys = sys;
} }
public double getUsed() public double getUsed()
{ {
return Arith.round(Arith.mul(used / total, 100), 2); return Arith.round(Arith.mul(used / total, 100), 2);
} }
public void setUsed(double used) public void setUsed(double used)
{ {
this.used = used; this.used = used;
} }
public double getWait() public double getWait()
{ {
return Arith.round(Arith.mul(wait / total, 100), 2); return Arith.round(Arith.mul(wait / total, 100), 2);
} }
public void setWait(double wait) public void setWait(double wait)
{ {
this.wait = wait; this.wait = wait;
} }
public double getFree() public double getFree()
{ {
return Arith.round(Arith.mul(free / total, 100), 2); return Arith.round(Arith.mul(free / total, 100), 2);
} }
public void setFree(double free) public void setFree(double free)
{ {
this.free = free; this.free = free;
} }
} }

View File

@ -1,122 +1,122 @@
package com.ruoyi.framework.web.domain.server; package com.ruoyi.framework.web.domain.server;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import com.ruoyi.common.utils.Arith; import com.ruoyi.common.utils.Arith;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
/** /**
* JVM相关信息 * JVM相关信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Jvm public class Jvm
{ {
/** /**
* 当前JVM占用的内存总数(M) * 当前JVM占用的内存总数(M)
*/ */
private double total; private double total;
/** /**
* JVM最大可用内存总数(M) * JVM最大可用内存总数(M)
*/ */
private double max; private double max;
/** /**
* JVM空闲内存(M) * JVM空闲内存(M)
*/ */
private double free; private double free;
/** /**
* JDK版本 * JDK版本
*/ */
private String version; private String version;
/** /**
* JDK路径 * JDK路径
*/ */
private String home; private String home;
public double getTotal() public double getTotal()
{ {
return Arith.div(total, (1024 * 1024), 2); return Arith.div(total, (1024 * 1024), 2);
} }
public void setTotal(double total) public void setTotal(double total)
{ {
this.total = total; this.total = total;
} }
public double getMax() public double getMax()
{ {
return Arith.div(max, (1024 * 1024), 2); return Arith.div(max, (1024 * 1024), 2);
} }
public void setMax(double max) public void setMax(double max)
{ {
this.max = max; this.max = max;
} }
public double getFree() public double getFree()
{ {
return Arith.div(free, (1024 * 1024), 2); return Arith.div(free, (1024 * 1024), 2);
} }
public void setFree(double free) public void setFree(double free)
{ {
this.free = free; this.free = free;
} }
public double getUsed() public double getUsed()
{ {
return Arith.div(total - free, (1024 * 1024), 2); return Arith.div(total - free, (1024 * 1024), 2);
} }
public double getUsage() public double getUsage()
{ {
return Arith.mul(Arith.div(total - free, total, 4), 100); return Arith.mul(Arith.div(total - free, total, 4), 100);
} }
/** /**
* 获取JDK名称 * 获取JDK名称
*/ */
public String getName() public String getName()
{ {
return ManagementFactory.getRuntimeMXBean().getVmName(); return ManagementFactory.getRuntimeMXBean().getVmName();
} }
public String getVersion() public String getVersion()
{ {
return version; return version;
} }
public void setVersion(String version) public void setVersion(String version)
{ {
this.version = version; this.version = version;
} }
public String getHome() public String getHome()
{ {
return home; return home;
} }
public void setHome(String home) public void setHome(String home)
{ {
this.home = home; this.home = home;
} }
/** /**
* JDK启动时间 * JDK启动时间
*/ */
public String getStartTime() public String getStartTime()
{ {
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate()); return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
} }
/** /**
* JDK运行时间 * JDK运行时间
*/ */
public String getRunTime() public String getRunTime()
{ {
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate()); return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
} }
} }

View File

@ -1,61 +1,61 @@
package com.ruoyi.framework.web.domain.server; package com.ruoyi.framework.web.domain.server;
import com.ruoyi.common.utils.Arith; import com.ruoyi.common.utils.Arith;
/** /**
* 內存相关信息 * 內存相关信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Mem public class Mem
{ {
/** /**
* 内存总量 * 内存总量
*/ */
private double total; private double total;
/** /**
* 已用内存 * 已用内存
*/ */
private double used; private double used;
/** /**
* 剩余内存 * 剩余内存
*/ */
private double free; private double free;
public double getTotal() public double getTotal()
{ {
return Arith.div(total, (1024 * 1024 * 1024), 2); return Arith.div(total, (1024 * 1024 * 1024), 2);
} }
public void setTotal(long total) public void setTotal(long total)
{ {
this.total = total; this.total = total;
} }
public double getUsed() public double getUsed()
{ {
return Arith.div(used, (1024 * 1024 * 1024), 2); return Arith.div(used, (1024 * 1024 * 1024), 2);
} }
public void setUsed(long used) public void setUsed(long used)
{ {
this.used = used; this.used = used;
} }
public double getFree() public double getFree()
{ {
return Arith.div(free, (1024 * 1024 * 1024), 2); return Arith.div(free, (1024 * 1024 * 1024), 2);
} }
public void setFree(long free) public void setFree(long free)
{ {
this.free = free; this.free = free;
} }
public double getUsage() public double getUsage()
{ {
return Arith.mul(Arith.div(used, total, 4), 100); return Arith.mul(Arith.div(used, total, 4), 100);
} }
} }

View File

@ -1,84 +1,84 @@
package com.ruoyi.framework.web.domain.server; package com.ruoyi.framework.web.domain.server;
/** /**
* 系统相关信息 * 系统相关信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Sys public class Sys
{ {
/** /**
* 服务器名称 * 服务器名称
*/ */
private String computerName; private String computerName;
/** /**
* 服务器Ip * 服务器Ip
*/ */
private String computerIp; private String computerIp;
/** /**
* 项目路径 * 项目路径
*/ */
private String userDir; private String userDir;
/** /**
* 操作系统 * 操作系统
*/ */
private String osName; private String osName;
/** /**
* 系统架构 * 系统架构
*/ */
private String osArch; private String osArch;
public String getComputerName() public String getComputerName()
{ {
return computerName; return computerName;
} }
public void setComputerName(String computerName) public void setComputerName(String computerName)
{ {
this.computerName = computerName; this.computerName = computerName;
} }
public String getComputerIp() public String getComputerIp()
{ {
return computerIp; return computerIp;
} }
public void setComputerIp(String computerIp) public void setComputerIp(String computerIp)
{ {
this.computerIp = computerIp; this.computerIp = computerIp;
} }
public String getUserDir() public String getUserDir()
{ {
return userDir; return userDir;
} }
public void setUserDir(String userDir) public void setUserDir(String userDir)
{ {
this.userDir = userDir; this.userDir = userDir;
} }
public String getOsName() public String getOsName()
{ {
return osName; return osName;
} }
public void setOsName(String osName) public void setOsName(String osName)
{ {
this.osName = osName; this.osName = osName;
} }
public String getOsArch() public String getOsArch()
{ {
return osArch; return osArch;
} }
public void setOsArch(String osArch) public void setOsArch(String osArch)
{ {
this.osArch = osArch; this.osArch = osArch;
} }
} }

Some files were not shown because too many files have changed in this diff Show More