初始提交
This commit is contained in:
commit
2ec3d09dc2
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
18
.idea/encodings.xml
generated
Normal file
18
.idea/encodings.xml
generated
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/api-common/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-common/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-community/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-community/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-gateway/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-gateway/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-public/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-school/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-school/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-student/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/api-student/src/main/resources" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
14
.idea/misc.xml
generated
Normal file
14
.idea/misc.xml
generated
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="temurin-17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
62
api-common/pom.xml
Normal file
62
api-common/pom.xml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?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"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-common</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- redis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Spring Web -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- JSON 解析器和生成器 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- Java Servlet -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>io.projectreactor</groupId>-->
|
||||||
|
<!-- <artifactId>reactor-core</artifactId>-->
|
||||||
|
<!-- <version>3.5.9</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package com.lxbtech.lxb.common;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
/**
|
||||||
|
* UTF-8 字符集
|
||||||
|
*/
|
||||||
|
public static final String UTF8 = "UTF-8";
|
||||||
|
/**
|
||||||
|
* 成功标记
|
||||||
|
*/
|
||||||
|
public static final Integer SUCCESS = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 失败标记
|
||||||
|
*/
|
||||||
|
public static final Integer FAIL = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限缓存前缀
|
||||||
|
*/
|
||||||
|
public final static String LOGIN_TOKEN_KEY = "login_tokens:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生token在redis中的有效时间,单位(天)
|
||||||
|
*/
|
||||||
|
public static final Long REDIS_TOKEN_TIME_OUT_DAY = 30L;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
package com.lxbtech.lxb.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回状态码
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class HttpStatus
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 操作成功
|
||||||
|
*/
|
||||||
|
public static final int SUCCESS = 200;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象创建成功
|
||||||
|
*/
|
||||||
|
public static final int CREATED = 201;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求已经被接受
|
||||||
|
*/
|
||||||
|
public static final int ACCEPTED = 202;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作已经执行成功,但是没有返回数据
|
||||||
|
*/
|
||||||
|
public static final int NO_CONTENT = 204;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源已被移除
|
||||||
|
*/
|
||||||
|
public static final int MOVED_PERM = 301;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向
|
||||||
|
*/
|
||||||
|
public static final int SEE_OTHER = 303;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源没有被修改
|
||||||
|
*/
|
||||||
|
public static final int NOT_MODIFIED = 304;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数列表错误(缺少,格式不匹配)
|
||||||
|
*/
|
||||||
|
public static final int BAD_REQUEST = 400;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未授权
|
||||||
|
*/
|
||||||
|
public static final int UNAUTHORIZED = 401;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问受限,授权过期
|
||||||
|
*/
|
||||||
|
public static final int FORBIDDEN = 403;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源,服务未找到
|
||||||
|
*/
|
||||||
|
public static final int NOT_FOUND = 404;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不允许的http方法
|
||||||
|
*/
|
||||||
|
public static final int BAD_METHOD = 405;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 资源冲突,或者资源被锁
|
||||||
|
*/
|
||||||
|
public static final int CONFLICT = 409;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 不支持的数据,媒体类型
|
||||||
|
*/
|
||||||
|
public static final int UNSUPPORTED_TYPE = 415;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统内部错误
|
||||||
|
*/
|
||||||
|
public static final int ERROR = 500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接口未实现
|
||||||
|
*/
|
||||||
|
public static final int NOT_IMPLEMENTED = 501;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统警告消息
|
||||||
|
*/
|
||||||
|
public static final int WARN = 601;
|
||||||
|
}
|
||||||
130
api-common/src/main/java/com/lxbtech/lxb/common/JwtUtils.java
Normal file
130
api-common/src/main/java/com/lxbtech/lxb/common/JwtUtils.java
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
package com.lxbtech.lxb.common;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.utils.Convert;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.SignatureAlgorithm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jwt工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class JwtUtils
|
||||||
|
{
|
||||||
|
public static String secret = TokenConstants.SECRET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从数据声明生成令牌
|
||||||
|
*
|
||||||
|
* @param claims 数据声明
|
||||||
|
* @return 令牌
|
||||||
|
*/
|
||||||
|
public static String createToken(Map<String, Object> claims)
|
||||||
|
{
|
||||||
|
String token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从令牌中获取数据声明
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 数据声明
|
||||||
|
*/
|
||||||
|
public static Claims parseToken(String token)
|
||||||
|
{
|
||||||
|
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户标识
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserKey(String token)
|
||||||
|
{
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return getValue(claims, SecurityConstants.USER_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户标识
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserKey(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, SecurityConstants.USER_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户ID
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserId(String token)
|
||||||
|
{
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取用户ID
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户ID
|
||||||
|
*/
|
||||||
|
public static String getUserId(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据令牌获取用户名
|
||||||
|
*
|
||||||
|
* @param token 令牌
|
||||||
|
* @return 用户名
|
||||||
|
*/
|
||||||
|
public static String getUserName(String token)
|
||||||
|
{
|
||||||
|
Claims claims = parseToken(token);
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USERNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取用户名
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @return 用户名
|
||||||
|
*/
|
||||||
|
public static String getUserName(Claims claims)
|
||||||
|
{
|
||||||
|
return getValue(claims, SecurityConstants.DETAILS_USERNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据身份信息获取键值
|
||||||
|
*
|
||||||
|
* @param claims 身份信息
|
||||||
|
* @param key 键
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
public static String getValue(Claims claims, String key)
|
||||||
|
{
|
||||||
|
return Convert.toStr(claims.get(key), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存key
|
||||||
|
*/
|
||||||
|
public static String getTokenKey(String token)
|
||||||
|
{
|
||||||
|
return Constants.LOGIN_TOKEN_KEY + token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.lxbtech.lxb.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 权限相关通用常量
|
||||||
|
*/
|
||||||
|
public class SecurityConstants
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生标识
|
||||||
|
*/
|
||||||
|
public static final String USER_KEY = "student_key";
|
||||||
|
/**
|
||||||
|
* 学生ID字段
|
||||||
|
*/
|
||||||
|
public static final String DETAILS_USER_ID = "student_id";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 学生名字段
|
||||||
|
*/
|
||||||
|
public static final String DETAILS_USERNAME = "student_name";
|
||||||
|
/**
|
||||||
|
* 学生名字段
|
||||||
|
*/
|
||||||
|
public static final String DETAILS_EMAIL = "student_email";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权信息字段
|
||||||
|
*/
|
||||||
|
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求来源
|
||||||
|
*/
|
||||||
|
public static final String FROM_SOURCE = "from-source";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内部请求
|
||||||
|
*/
|
||||||
|
public static final String INNER = "inner";
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.lxbtech.lxb.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token的Key常量
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class TokenConstants
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 令牌前缀
|
||||||
|
*/
|
||||||
|
public static final String PREFIX = "Bearer ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 令牌秘钥
|
||||||
|
*/
|
||||||
|
public final static String SECRET = "qqpotinbnjnrnbjkbniuhsdfggui";
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.lxbtech.lxb.common.domain;
|
||||||
|
|
||||||
|
public class BaseBean {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
116
api-common/src/main/java/com/lxbtech/lxb/common/domain/R.java
Normal file
116
api-common/src/main/java/com/lxbtech/lxb/common/domain/R.java
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
package com.lxbtech.lxb.common.domain;
|
||||||
|
|
||||||
|
import com.lxb.common.Constants;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应信息主体
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class R<T> implements Serializable
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 成功 */
|
||||||
|
public static final int SUCCESS = Constants.SUCCESS;
|
||||||
|
|
||||||
|
/** 失败 */
|
||||||
|
public static final int FAIL = Constants.FAIL;
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
public static <T> R<T> ok()
|
||||||
|
{
|
||||||
|
return restResult(null, SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> ok(T data)
|
||||||
|
{
|
||||||
|
return restResult(data, SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> ok(T data, String msg)
|
||||||
|
{
|
||||||
|
return restResult(data, SUCCESS, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail()
|
||||||
|
{
|
||||||
|
return restResult(null, FAIL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(String msg)
|
||||||
|
{
|
||||||
|
return restResult(null, FAIL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(T data)
|
||||||
|
{
|
||||||
|
return restResult(data, FAIL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(T data, String msg)
|
||||||
|
{
|
||||||
|
return restResult(data, FAIL, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> R<T> fail(int code, String msg)
|
||||||
|
{
|
||||||
|
return restResult(null, code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> R<T> restResult(T data, int code, String msg)
|
||||||
|
{
|
||||||
|
R<T> apiResult = new R<>();
|
||||||
|
apiResult.setCode(code);
|
||||||
|
apiResult.setData(data);
|
||||||
|
apiResult.setMsg(msg);
|
||||||
|
return apiResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(int code)
|
||||||
|
{
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMsg()
|
||||||
|
{
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMsg(String msg)
|
||||||
|
{
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getData()
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(T data)
|
||||||
|
{
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Boolean isError(R<T> ret)
|
||||||
|
{
|
||||||
|
return !isSuccess(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Boolean isSuccess(R<T> ret)
|
||||||
|
{
|
||||||
|
return R.SUCCESS == ret.getCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.lxbtech.lxb.common.domain;
|
||||||
|
|
||||||
|
public class StudentBean extends BaseBean{
|
||||||
|
private String userName;
|
||||||
|
private String phone;
|
||||||
|
private String email;
|
||||||
|
private String nickname;
|
||||||
|
private String password;
|
||||||
|
private String avatar;
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserName(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPhone(String phone) {
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNickname() {
|
||||||
|
return nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNickname(String nickname) {
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAvatar() {
|
||||||
|
return avatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvatar(String avatar) {
|
||||||
|
this.avatar = avatar;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,268 @@
|
|||||||
|
package com.lxbtech.lxb.common.redis;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.BoundSetOperations;
|
||||||
|
import org.springframework.data.redis.core.HashOperations;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.core.ValueOperations;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* spring redis 工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
**/
|
||||||
|
@SuppressWarnings(value = { "unchecked", "rawtypes" })
|
||||||
|
@Component
|
||||||
|
public class RedisService
|
||||||
|
{
|
||||||
|
@Autowired
|
||||||
|
public RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
*/
|
||||||
|
public <T> void setCacheObject(final String key, final T value)
|
||||||
|
{
|
||||||
|
redisTemplate.opsForValue().set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存基本的对象,Integer、String、实体类等
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param value 缓存的值
|
||||||
|
* @param timeout 时间
|
||||||
|
* @param timeUnit 时间颗粒度
|
||||||
|
*/
|
||||||
|
public <T> void setCacheObject(final String key, final T value, final Long timeout, final TimeUnit timeUnit)
|
||||||
|
{
|
||||||
|
redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置有效时间
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param timeout 超时时间
|
||||||
|
* @return true=设置成功;false=设置失败
|
||||||
|
*/
|
||||||
|
public boolean expire(final String key, final long timeout)
|
||||||
|
{
|
||||||
|
return expire(key, timeout, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置有效时间
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param timeout 超时时间
|
||||||
|
* @param unit 时间单位
|
||||||
|
* @return true=设置成功;false=设置失败
|
||||||
|
*/
|
||||||
|
public boolean expire(final String key, final long timeout, final TimeUnit unit)
|
||||||
|
{
|
||||||
|
return redisTemplate.expire(key, timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取有效时间
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @return 有效时间
|
||||||
|
*/
|
||||||
|
public long getExpire(final String key)
|
||||||
|
{
|
||||||
|
return redisTemplate.getExpire(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断 key是否存在
|
||||||
|
*
|
||||||
|
* @param key 键
|
||||||
|
* @return true 存在 false不存在
|
||||||
|
*/
|
||||||
|
public Boolean hasKey(String key)
|
||||||
|
{
|
||||||
|
return redisTemplate.hasKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的基本对象。
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public <T> T getCacheObject(final String key)
|
||||||
|
{
|
||||||
|
ValueOperations<String, T> operation = redisTemplate.opsForValue();
|
||||||
|
return operation.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除单个对象
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
public boolean deleteObject(final String key)
|
||||||
|
{
|
||||||
|
return redisTemplate.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除集合对象
|
||||||
|
*
|
||||||
|
* @param collection 多个对象
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean deleteObject(final Collection collection)
|
||||||
|
{
|
||||||
|
return redisTemplate.delete(collection) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存List数据
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @param dataList 待缓存的List数据
|
||||||
|
* @return 缓存的对象
|
||||||
|
*/
|
||||||
|
public <T> long setCacheList(final String key, final List<T> dataList)
|
||||||
|
{
|
||||||
|
Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
|
||||||
|
return count == null ? 0 : count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的list对象
|
||||||
|
*
|
||||||
|
* @param key 缓存的键值
|
||||||
|
* @return 缓存键值对应的数据
|
||||||
|
*/
|
||||||
|
public <T> List<T> getCacheList(final String key)
|
||||||
|
{
|
||||||
|
return redisTemplate.opsForList().range(key, 0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存Set
|
||||||
|
*
|
||||||
|
* @param key 缓存键值
|
||||||
|
* @param dataSet 缓存的数据
|
||||||
|
* @return 缓存数据的对象
|
||||||
|
*/
|
||||||
|
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
|
||||||
|
{
|
||||||
|
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
|
||||||
|
Iterator<T> it = dataSet.iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
setOperation.add(it.next());
|
||||||
|
}
|
||||||
|
return setOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的set
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public <T> Set<T> getCacheSet(final String key)
|
||||||
|
{
|
||||||
|
return redisTemplate.opsForSet().members(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存Map
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @param dataMap
|
||||||
|
*/
|
||||||
|
public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
|
||||||
|
{
|
||||||
|
if (dataMap != null) {
|
||||||
|
redisTemplate.opsForHash().putAll(key, dataMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的Map
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public <T> Map<String, T> getCacheMap(final String key)
|
||||||
|
{
|
||||||
|
return redisTemplate.opsForHash().entries(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 往Hash中存入数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @param value 值
|
||||||
|
*/
|
||||||
|
public <T> void setCacheMapValue(final String key, final String hKey, final T value)
|
||||||
|
{
|
||||||
|
redisTemplate.opsForHash().put(key, hKey, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Hash中的数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @return Hash中的对象
|
||||||
|
*/
|
||||||
|
public <T> T getCacheMapValue(final String key, final String hKey)
|
||||||
|
{
|
||||||
|
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
|
||||||
|
return opsForHash.get(key, hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取多个Hash中的数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKeys Hash键集合
|
||||||
|
* @return Hash对象集合
|
||||||
|
*/
|
||||||
|
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
|
||||||
|
{
|
||||||
|
return redisTemplate.opsForHash().multiGet(key, hKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除Hash中的某条数据
|
||||||
|
*
|
||||||
|
* @param key Redis键
|
||||||
|
* @param hKey Hash键
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
public boolean deleteCacheMapValue(final String key, final String hKey)
|
||||||
|
{
|
||||||
|
return redisTemplate.opsForHash().delete(key, hKey) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得缓存的基本对象列表
|
||||||
|
*
|
||||||
|
* @param pattern 字符串前缀
|
||||||
|
* @return 对象列表
|
||||||
|
*/
|
||||||
|
public Collection<String> keys(final String pattern)
|
||||||
|
{
|
||||||
|
return redisTemplate.keys(pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,144 @@
|
|||||||
|
package com.lxbtech.lxb.common.utils;
|
||||||
|
|
||||||
|
public class Convert {
|
||||||
|
/**
|
||||||
|
* 转换为字符串<br>
|
||||||
|
* 如果给定的值为null,或者转换失败,返回默认值<br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String toStr(Object value, String defaultValue)
|
||||||
|
{
|
||||||
|
if (null == value)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof String)
|
||||||
|
{
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为字符串<br>
|
||||||
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static String toStr(Object value)
|
||||||
|
{
|
||||||
|
return toStr(value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为int<br>
|
||||||
|
* 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Integer toInt(Object value, Integer defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Integer)
|
||||||
|
{
|
||||||
|
return (Integer) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Number)
|
||||||
|
{
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
final String valueStr = toStr(value, null);
|
||||||
|
if (CustomStringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Integer.parseInt(valueStr.trim());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为int<br>
|
||||||
|
* 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Integer toInt(Object value)
|
||||||
|
{
|
||||||
|
return toInt(value, null);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 转换为boolean<br>
|
||||||
|
* String支持的值为:true、false、yes、ok、no、1、0、是、否, 如果给定的值为空,或者转换失败,返回默认值<br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @param defaultValue 转换错误时的默认值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Boolean toBool(Object value, Boolean defaultValue)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
if (value instanceof Boolean)
|
||||||
|
{
|
||||||
|
return (Boolean) value;
|
||||||
|
}
|
||||||
|
String valueStr = toStr(value, null);
|
||||||
|
if (CustomStringUtils.isEmpty(valueStr))
|
||||||
|
{
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
valueStr = valueStr.trim().toLowerCase();
|
||||||
|
switch (valueStr)
|
||||||
|
{
|
||||||
|
case "true":
|
||||||
|
case "yes":
|
||||||
|
case "ok":
|
||||||
|
case "1":
|
||||||
|
case "是":
|
||||||
|
return true;
|
||||||
|
case "false":
|
||||||
|
case "no":
|
||||||
|
case "0":
|
||||||
|
case "否":
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为boolean<br>
|
||||||
|
* 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
|
||||||
|
* 转换失败不会报错
|
||||||
|
*
|
||||||
|
* @param value 被转换的值
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public static Boolean toBool(Object value)
|
||||||
|
{
|
||||||
|
return toBool(value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
package com.lxbtech.lxb.common.utils;
|
||||||
|
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
public class CustomStringUtils {
|
||||||
|
/** 空字符串 */
|
||||||
|
private static final String NULLSTR = "";
|
||||||
|
|
||||||
|
/** 下划线 */
|
||||||
|
private static final char SEPARATOR = '_';
|
||||||
|
|
||||||
|
/** 星号 */
|
||||||
|
private static final char ASTERISK = '*';
|
||||||
|
/**
|
||||||
|
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
|
||||||
|
*
|
||||||
|
* @param str 指定字符串
|
||||||
|
* @param strs 需要检查的字符串数组
|
||||||
|
* @return 是否匹配
|
||||||
|
*/
|
||||||
|
public static boolean matches(String str, List<String> strs)
|
||||||
|
{
|
||||||
|
if (isEmpty(str) || isEmpty(strs))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (String pattern : strs)
|
||||||
|
{
|
||||||
|
if (isMatch(pattern, str))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* * 判断一个字符串是否为空串
|
||||||
|
*
|
||||||
|
* @param str String
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(String str)
|
||||||
|
{
|
||||||
|
return isNull(str) || NULLSTR.equals(str.trim());
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否为空
|
||||||
|
*
|
||||||
|
* @param object Object
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isNull(Object object)
|
||||||
|
{
|
||||||
|
return object == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象是否非空
|
||||||
|
*
|
||||||
|
* @param object Object
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotNull(Object object)
|
||||||
|
{
|
||||||
|
return !isNull(object);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 判断url是否与规则配置:
|
||||||
|
* ? 表示单个字符;
|
||||||
|
* * 表示一层路径内的任意字符串,不可跨层级;
|
||||||
|
* ** 表示任意层路径;
|
||||||
|
*
|
||||||
|
* @param pattern 匹配规则
|
||||||
|
* @param url 需要匹配的url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean isMatch(String pattern, String url)
|
||||||
|
{
|
||||||
|
AntPathMatcher matcher = new AntPathMatcher();
|
||||||
|
return matcher.match(pattern, url);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* * 判断一个Collection是否为空, 包含List,Set,Queue
|
||||||
|
*
|
||||||
|
* @param coll 要判断的Collection
|
||||||
|
* @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Collection<?> coll)
|
||||||
|
{
|
||||||
|
return isNull(coll) || coll.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个Collection是否非空,包含List,Set,Queue
|
||||||
|
*
|
||||||
|
* @param coll 要判断的Collection
|
||||||
|
* @return true:非空 false:空
|
||||||
|
*/
|
||||||
|
public static boolean isNotEmpty(Collection<?> coll)
|
||||||
|
{
|
||||||
|
return !isEmpty(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 判断一个对象数组是否为空
|
||||||
|
*
|
||||||
|
* @param objects 要判断的对象数组
|
||||||
|
** @return true:为空 false:非空
|
||||||
|
*/
|
||||||
|
public static boolean isEmpty(Object[] objects)
|
||||||
|
{
|
||||||
|
return isNull(objects) || (objects.length == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String join(Object[] array, String delimiter) {
|
||||||
|
return array == null ? null : join((Object[])array, delimiter, 0, array.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String join(Object[] array, String delimiter, int startIndex, int endIndex) {
|
||||||
|
if (array == null) {
|
||||||
|
return null;
|
||||||
|
} else if (endIndex - startIndex <= 0) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
StringJoiner joiner = new StringJoiner(toStringOrEmpty(delimiter));
|
||||||
|
|
||||||
|
for(int i = startIndex; i < endIndex; ++i) {
|
||||||
|
joiner.add(toStringOrEmpty(array[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return joiner.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static String toStringOrEmpty(Object obj) {
|
||||||
|
return Objects.toString(obj, "");
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 是否包含字符串
|
||||||
|
*
|
||||||
|
* @param str 验证字符串
|
||||||
|
* @param strs 字符串组
|
||||||
|
* @return 包含返回true
|
||||||
|
*/
|
||||||
|
public static boolean inStringIgnoreCase(String str, String... strs)
|
||||||
|
{
|
||||||
|
if (str != null && strs != null)
|
||||||
|
{
|
||||||
|
for (String s : strs)
|
||||||
|
{
|
||||||
|
if (str.equalsIgnoreCase(trim(s)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 去空格
|
||||||
|
*/
|
||||||
|
public static String trim(String str)
|
||||||
|
{
|
||||||
|
return (str == null ? "" : str.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package com.lxbtech.lxb.common.utils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID生成器工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class IdUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取随机UUID
|
||||||
|
*
|
||||||
|
* @return 随机UUID
|
||||||
|
*/
|
||||||
|
public static String randomUUID()
|
||||||
|
{
|
||||||
|
return UUID.randomUUID().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简化的UUID,去掉了横线
|
||||||
|
*
|
||||||
|
* @return 简化的UUID,去掉了横线
|
||||||
|
*/
|
||||||
|
public static String simpleUUID()
|
||||||
|
{
|
||||||
|
return UUID.randomUUID().toString(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取随机UUID,使用性能更好的ThreadLocalRandom生成UUID
|
||||||
|
*
|
||||||
|
* @return 随机UUID
|
||||||
|
*/
|
||||||
|
public static String fastUUID()
|
||||||
|
{
|
||||||
|
return UUID.fastUUID().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简化的UUID,去掉了横线,使用性能更好的ThreadLocalRandom生成UUID
|
||||||
|
*
|
||||||
|
* @return 简化的UUID,去掉了横线
|
||||||
|
*/
|
||||||
|
public static String fastSimpleUUID()
|
||||||
|
{
|
||||||
|
return UUID.fastUUID().toString(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,334 @@
|
|||||||
|
package com.lxbtech.lxb.common.utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import com.lxb.common.Constants;
|
||||||
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.util.LinkedCaseInsensitiveMap;
|
||||||
|
import org.springframework.web.context.request.RequestAttributes;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.domain.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端工具类
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public class ServletUtils
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取String参数
|
||||||
|
*/
|
||||||
|
public static String getParameter(String name)
|
||||||
|
{
|
||||||
|
return getRequest().getParameter(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取String参数
|
||||||
|
*/
|
||||||
|
public static String getParameter(String name, String defaultValue)
|
||||||
|
{
|
||||||
|
return Convert.toStr(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Integer参数
|
||||||
|
*/
|
||||||
|
public static Integer getParameterToInt(String name)
|
||||||
|
{
|
||||||
|
return Convert.toInt(getRequest().getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Integer参数
|
||||||
|
*/
|
||||||
|
public static Integer getParameterToInt(String name, Integer defaultValue)
|
||||||
|
{
|
||||||
|
return Convert.toInt(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Boolean参数
|
||||||
|
*/
|
||||||
|
public static Boolean getParameterToBool(String name)
|
||||||
|
{
|
||||||
|
return Convert.toBool(getRequest().getParameter(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Boolean参数
|
||||||
|
*/
|
||||||
|
public static Boolean getParameterToBool(String name, Boolean defaultValue)
|
||||||
|
{
|
||||||
|
return Convert.toBool(getRequest().getParameter(name), defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得所有请求参数
|
||||||
|
*
|
||||||
|
* @param request 请求对象{@link ServletRequest}
|
||||||
|
* @return Map
|
||||||
|
*/
|
||||||
|
public static Map<String, String[]> getParams(ServletRequest request)
|
||||||
|
{
|
||||||
|
final Map<String, String[]> map = request.getParameterMap();
|
||||||
|
return Collections.unmodifiableMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得所有请求参数
|
||||||
|
*
|
||||||
|
* @param request 请求对象{@link ServletRequest}
|
||||||
|
* @return Map
|
||||||
|
*/
|
||||||
|
public static Map<String, String> getParamMap(ServletRequest request)
|
||||||
|
{
|
||||||
|
Map<String, String> params = new HashMap<>();
|
||||||
|
for (Map.Entry<String, String[]> entry : getParams(request).entrySet())
|
||||||
|
{
|
||||||
|
params.put(entry.getKey(), CustomStringUtils.join(entry.getValue(), ","));
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取request
|
||||||
|
*/
|
||||||
|
public static HttpServletRequest getRequest()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getRequestAttributes().getRequest();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取response
|
||||||
|
*/
|
||||||
|
public static HttpServletResponse getResponse()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getRequestAttributes().getResponse();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取session
|
||||||
|
*/
|
||||||
|
public static HttpSession getSession()
|
||||||
|
{
|
||||||
|
return getRequest().getSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ServletRequestAttributes getRequestAttributes()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
|
||||||
|
return (ServletRequestAttributes) attributes;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getHeader(HttpServletRequest request, String name)
|
||||||
|
{
|
||||||
|
String value = request.getHeader(name);
|
||||||
|
if (CustomStringUtils.isEmpty(value))
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return urlDecode(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> getHeaders(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
Map<String, String> map = new LinkedCaseInsensitiveMap<>();
|
||||||
|
Enumeration<String> enumeration = request.getHeaderNames();
|
||||||
|
if (enumeration != null)
|
||||||
|
{
|
||||||
|
while (enumeration.hasMoreElements())
|
||||||
|
{
|
||||||
|
String key = enumeration.nextElement();
|
||||||
|
String value = request.getHeader(key);
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将字符串渲染到客户端
|
||||||
|
*
|
||||||
|
* @param response 渲染对象
|
||||||
|
* @param string 待渲染的字符串
|
||||||
|
*/
|
||||||
|
public static void renderString(HttpServletResponse response, String string)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response.setStatus(200);
|
||||||
|
response.setContentType("application/json");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.getWriter().print(string);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否是Ajax异步请求
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
*/
|
||||||
|
public static boolean isAjaxRequest(HttpServletRequest request)
|
||||||
|
{
|
||||||
|
String accept = request.getHeader("accept");
|
||||||
|
if (accept != null && accept.contains("application/json"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String xRequestedWith = request.getHeader("X-Requested-With");
|
||||||
|
if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String uri = request.getRequestURI();
|
||||||
|
if (CustomStringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ajax = request.getParameter("__ajax");
|
||||||
|
return CustomStringUtils.inStringIgnoreCase(ajax, "json", "xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容编码
|
||||||
|
*
|
||||||
|
* @param str 内容
|
||||||
|
* @return 编码后的内容
|
||||||
|
*/
|
||||||
|
public static String urlEncode(String str)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return URLEncoder.encode(str, Constants.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 内容解码
|
||||||
|
*
|
||||||
|
* @param str 内容
|
||||||
|
* @return 解码后的内容
|
||||||
|
*/
|
||||||
|
public static String urlDecode(String str)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return URLDecoder.decode(str, Constants.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value)
|
||||||
|
{
|
||||||
|
return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param code 响应状态码
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code)
|
||||||
|
{
|
||||||
|
return webFluxResponseWriter(response, HttpStatus.OK, value, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param status http状态码
|
||||||
|
* @param code 响应状态码
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code)
|
||||||
|
{
|
||||||
|
return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置webflux模型响应
|
||||||
|
*
|
||||||
|
* @param response ServerHttpResponse
|
||||||
|
* @param contentType content-type
|
||||||
|
* @param status http状态码
|
||||||
|
* @param code 响应状态码
|
||||||
|
* @param value 响应内容
|
||||||
|
* @return Mono<Void>
|
||||||
|
*/
|
||||||
|
public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code)
|
||||||
|
{
|
||||||
|
response.setStatusCode(status);
|
||||||
|
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);
|
||||||
|
R<?> result = R.fail(code, value.toString());
|
||||||
|
DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes());
|
||||||
|
return response.writeWith(Mono.just(dataBuffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
483
api-common/src/main/java/com/lxbtech/lxb/common/utils/UUID.java
Normal file
483
api-common/src/main/java/com/lxbtech/lxb/common/utils/UUID.java
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
package com.lxbtech.lxb.common.utils;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供通用唯一识别码(universally unique identifier)(UUID)实现
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
public final class UUID implements java.io.Serializable, Comparable<UUID>
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -1185015143654744140L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SecureRandom 的单例
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static class Holder
|
||||||
|
{
|
||||||
|
static final SecureRandom numberGenerator = getSecureRandom();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 此UUID的最高64有效位 */
|
||||||
|
private final long mostSigBits;
|
||||||
|
|
||||||
|
/** 此UUID的最低64有效位 */
|
||||||
|
private final long leastSigBits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 私有构造
|
||||||
|
*
|
||||||
|
* @param data 数据
|
||||||
|
*/
|
||||||
|
private UUID(byte[] data)
|
||||||
|
{
|
||||||
|
long msb = 0;
|
||||||
|
long lsb = 0;
|
||||||
|
assert data.length == 16 : "data must be 16 bytes in length";
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
msb = (msb << 8) | (data[i] & 0xff);
|
||||||
|
}
|
||||||
|
for (int i = 8; i < 16; i++)
|
||||||
|
{
|
||||||
|
lsb = (lsb << 8) | (data[i] & 0xff);
|
||||||
|
}
|
||||||
|
this.mostSigBits = msb;
|
||||||
|
this.leastSigBits = lsb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用指定的数据构造新的 UUID。
|
||||||
|
*
|
||||||
|
* @param mostSigBits 用于 {@code UUID} 的最高有效 64 位
|
||||||
|
* @param leastSigBits 用于 {@code UUID} 的最低有效 64 位
|
||||||
|
*/
|
||||||
|
public UUID(long mostSigBits, long leastSigBits)
|
||||||
|
{
|
||||||
|
this.mostSigBits = mostSigBits;
|
||||||
|
this.leastSigBits = leastSigBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。
|
||||||
|
*
|
||||||
|
* @return 随机生成的 {@code UUID}
|
||||||
|
*/
|
||||||
|
public static UUID fastUUID()
|
||||||
|
{
|
||||||
|
return randomUUID(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
||||||
|
*
|
||||||
|
* @return 随机生成的 {@code UUID}
|
||||||
|
*/
|
||||||
|
public static UUID randomUUID()
|
||||||
|
{
|
||||||
|
return randomUUID(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类型 4(伪随机生成的)UUID 的静态工厂。 使用加密的强伪随机数生成器生成该 UUID。
|
||||||
|
*
|
||||||
|
* @param isSecure 是否使用{@link SecureRandom}如果是可以获得更安全的随机码,否则可以得到更好的性能
|
||||||
|
* @return 随机生成的 {@code UUID}
|
||||||
|
*/
|
||||||
|
public static UUID randomUUID(boolean isSecure)
|
||||||
|
{
|
||||||
|
final Random ng = isSecure ? Holder.numberGenerator : getRandom();
|
||||||
|
|
||||||
|
byte[] randomBytes = new byte[16];
|
||||||
|
ng.nextBytes(randomBytes);
|
||||||
|
randomBytes[6] &= 0x0f; /* clear version */
|
||||||
|
randomBytes[6] |= 0x40; /* set to version 4 */
|
||||||
|
randomBytes[8] &= 0x3f; /* clear variant */
|
||||||
|
randomBytes[8] |= 0x80; /* set to IETF variant */
|
||||||
|
return new UUID(randomBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据指定的字节数组获取类型 3(基于名称的)UUID 的静态工厂。
|
||||||
|
*
|
||||||
|
* @param name 用于构造 UUID 的字节数组。
|
||||||
|
*
|
||||||
|
* @return 根据指定数组生成的 {@code UUID}
|
||||||
|
*/
|
||||||
|
public static UUID nameUUIDFromBytes(byte[] name)
|
||||||
|
{
|
||||||
|
MessageDigest md;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
md = MessageDigest.getInstance("MD5");
|
||||||
|
}
|
||||||
|
catch (NoSuchAlgorithmException nsae)
|
||||||
|
{
|
||||||
|
throw new InternalError("MD5 not supported");
|
||||||
|
}
|
||||||
|
byte[] md5Bytes = md.digest(name);
|
||||||
|
md5Bytes[6] &= 0x0f; /* clear version */
|
||||||
|
md5Bytes[6] |= 0x30; /* set to version 3 */
|
||||||
|
md5Bytes[8] &= 0x3f; /* clear variant */
|
||||||
|
md5Bytes[8] |= 0x80; /* set to IETF variant */
|
||||||
|
return new UUID(md5Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 {@link #toString()} 方法中描述的字符串标准表示形式创建{@code UUID}。
|
||||||
|
*
|
||||||
|
* @param name 指定 {@code UUID} 字符串
|
||||||
|
* @return 具有指定值的 {@code UUID}
|
||||||
|
* @throws IllegalArgumentException 如果 name 与 {@link #toString} 中描述的字符串表示形式不符抛出此异常
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static UUID fromString(String name)
|
||||||
|
{
|
||||||
|
String[] components = name.split("-");
|
||||||
|
if (components.length != 5)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid UUID string: " + name);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
components[i] = "0x" + components[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
long mostSigBits = Long.decode(components[0]).longValue();
|
||||||
|
mostSigBits <<= 16;
|
||||||
|
mostSigBits |= Long.decode(components[1]).longValue();
|
||||||
|
mostSigBits <<= 16;
|
||||||
|
mostSigBits |= Long.decode(components[2]).longValue();
|
||||||
|
|
||||||
|
long leastSigBits = Long.decode(components[3]).longValue();
|
||||||
|
leastSigBits <<= 48;
|
||||||
|
leastSigBits |= Long.decode(components[4]).longValue();
|
||||||
|
|
||||||
|
return new UUID(mostSigBits, leastSigBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此 UUID 的 128 位值中的最低有效 64 位。
|
||||||
|
*
|
||||||
|
* @return 此 UUID 的 128 位值中的最低有效 64 位。
|
||||||
|
*/
|
||||||
|
public long getLeastSignificantBits()
|
||||||
|
{
|
||||||
|
return leastSigBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此 UUID 的 128 位值中的最高有效 64 位。
|
||||||
|
*
|
||||||
|
* @return 此 UUID 的 128 位值中最高有效 64 位。
|
||||||
|
*/
|
||||||
|
public long getMostSignificantBits()
|
||||||
|
{
|
||||||
|
return mostSigBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与此 {@code UUID} 相关联的版本号. 版本号描述此 {@code UUID} 是如何生成的。
|
||||||
|
* <p>
|
||||||
|
* 版本号具有以下含意:
|
||||||
|
* <ul>
|
||||||
|
* <li>1 基于时间的 UUID
|
||||||
|
* <li>2 DCE 安全 UUID
|
||||||
|
* <li>3 基于名称的 UUID
|
||||||
|
* <li>4 随机生成的 UUID
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return 此 {@code UUID} 的版本号
|
||||||
|
*/
|
||||||
|
public int version()
|
||||||
|
{
|
||||||
|
// Version is bits masked by 0x000000000000F000 in MS long
|
||||||
|
return (int) ((mostSigBits >> 12) & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与此 {@code UUID} 相关联的变体号。变体号描述 {@code UUID} 的布局。
|
||||||
|
* <p>
|
||||||
|
* 变体号具有以下含意:
|
||||||
|
* <ul>
|
||||||
|
* <li>0 为 NCS 向后兼容保留
|
||||||
|
* <li>2 <a href="http://www.ietf.org/rfc/rfc4122.txt">IETF RFC 4122</a>(Leach-Salz), 用于此类
|
||||||
|
* <li>6 保留,微软向后兼容
|
||||||
|
* <li>7 保留供以后定义使用
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return 此 {@code UUID} 相关联的变体号
|
||||||
|
*/
|
||||||
|
public int variant()
|
||||||
|
{
|
||||||
|
// This field is composed of a varying number of bits.
|
||||||
|
// 0 - - Reserved for NCS backward compatibility
|
||||||
|
// 1 0 - The IETF aka Leach-Salz variant (used by this class)
|
||||||
|
// 1 1 0 Reserved, Microsoft backward compatibility
|
||||||
|
// 1 1 1 Reserved for future definition.
|
||||||
|
return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与此 UUID 相关联的时间戳值。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 60 位的时间戳值根据此 {@code UUID} 的 time_low、time_mid 和 time_hi 字段构造。<br>
|
||||||
|
* 所得到的时间戳以 100 毫微秒为单位,从 UTC(通用协调时间) 1582 年 10 月 15 日零时开始。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 时间戳值仅在在基于时间的 UUID(其 version 类型为 1)中才有意义。<br>
|
||||||
|
* 如果此 {@code UUID} 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException 如果此 {@code UUID} 不是 version 为 1 的 UUID。
|
||||||
|
*/
|
||||||
|
public long timestamp() throws UnsupportedOperationException
|
||||||
|
{
|
||||||
|
checkTimeBase();
|
||||||
|
return (mostSigBits & 0x0FFFL) << 48//
|
||||||
|
| ((mostSigBits >> 16) & 0x0FFFFL) << 32//
|
||||||
|
| mostSigBits >>> 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与此 UUID 相关联的时钟序列值。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 14 位的时钟序列值根据此 UUID 的 clock_seq 字段构造。clock_seq 字段用于保证在基于时间的 UUID 中的时间唯一性。
|
||||||
|
* <p>
|
||||||
|
* {@code clockSequence} 值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。 如果此 UUID 不是基于时间的 UUID,则此方法抛出
|
||||||
|
* UnsupportedOperationException。
|
||||||
|
*
|
||||||
|
* @return 此 {@code UUID} 的时钟序列
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
|
||||||
|
*/
|
||||||
|
public int clockSequence() throws UnsupportedOperationException
|
||||||
|
{
|
||||||
|
checkTimeBase();
|
||||||
|
return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与此 UUID 相关的节点值。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 48 位的节点值根据此 UUID 的 node 字段构造。此字段旨在用于保存机器的 IEEE 802 地址,该地址用于生成此 UUID 以保证空间唯一性。
|
||||||
|
* <p>
|
||||||
|
* 节点值仅在基于时间的 UUID(其 version 类型为 1)中才有意义。<br>
|
||||||
|
* 如果此 UUID 不是基于时间的 UUID,则此方法抛出 UnsupportedOperationException。
|
||||||
|
*
|
||||||
|
* @return 此 {@code UUID} 的节点值
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException 如果此 UUID 的 version 不为 1
|
||||||
|
*/
|
||||||
|
public long node() throws UnsupportedOperationException
|
||||||
|
{
|
||||||
|
checkTimeBase();
|
||||||
|
return leastSigBits & 0x0000FFFFFFFFFFFFL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此{@code UUID} 的字符串表现形式。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* UUID 的字符串表示形式由此 BNF 描述:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
||||||
|
* time_low = 4*<hexOctet>
|
||||||
|
* time_mid = 2*<hexOctet>
|
||||||
|
* time_high_and_version = 2*<hexOctet>
|
||||||
|
* variant_and_sequence = 2*<hexOctet>
|
||||||
|
* node = 6*<hexOctet>
|
||||||
|
* hexOctet = <hexDigit><hexDigit>
|
||||||
|
* hexDigit = [0-9a-fA-F]
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* </blockquote>
|
||||||
|
*
|
||||||
|
* @return 此{@code UUID} 的字符串表现形式
|
||||||
|
* @see #toString(boolean)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return toString(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此{@code UUID} 的字符串表现形式。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* UUID 的字符串表示形式由此 BNF 描述:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {@code
|
||||||
|
* UUID = <time_low>-<time_mid>-<time_high_and_version>-<variant_and_sequence>-<node>
|
||||||
|
* time_low = 4*<hexOctet>
|
||||||
|
* time_mid = 2*<hexOctet>
|
||||||
|
* time_high_and_version = 2*<hexOctet>
|
||||||
|
* variant_and_sequence = 2*<hexOctet>
|
||||||
|
* node = 6*<hexOctet>
|
||||||
|
* hexOctet = <hexDigit><hexDigit>
|
||||||
|
* hexDigit = [0-9a-fA-F]
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* </blockquote>
|
||||||
|
*
|
||||||
|
* @param isSimple 是否简单模式,简单模式为不带'-'的UUID字符串
|
||||||
|
* @return 此{@code UUID} 的字符串表现形式
|
||||||
|
*/
|
||||||
|
public String toString(boolean isSimple)
|
||||||
|
{
|
||||||
|
final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
|
||||||
|
// time_low
|
||||||
|
builder.append(digits(mostSigBits >> 32, 8));
|
||||||
|
if (!isSimple)
|
||||||
|
{
|
||||||
|
builder.append('-');
|
||||||
|
}
|
||||||
|
// time_mid
|
||||||
|
builder.append(digits(mostSigBits >> 16, 4));
|
||||||
|
if (!isSimple)
|
||||||
|
{
|
||||||
|
builder.append('-');
|
||||||
|
}
|
||||||
|
// time_high_and_version
|
||||||
|
builder.append(digits(mostSigBits, 4));
|
||||||
|
if (!isSimple)
|
||||||
|
{
|
||||||
|
builder.append('-');
|
||||||
|
}
|
||||||
|
// variant_and_sequence
|
||||||
|
builder.append(digits(leastSigBits >> 48, 4));
|
||||||
|
if (!isSimple)
|
||||||
|
{
|
||||||
|
builder.append('-');
|
||||||
|
}
|
||||||
|
// node
|
||||||
|
builder.append(digits(leastSigBits, 12));
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此 UUID 的哈希码。
|
||||||
|
*
|
||||||
|
* @return UUID 的哈希码值。
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
long hilo = mostSigBits ^ leastSigBits;
|
||||||
|
return ((int) (hilo >> 32)) ^ (int) hilo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将此对象与指定对象比较。
|
||||||
|
* <p>
|
||||||
|
* 当且仅当参数不为 {@code null}、而是一个 UUID 对象、具有与此 UUID 相同的 varriant、包含相同的值(每一位均相同)时,结果才为 {@code true}。
|
||||||
|
*
|
||||||
|
* @param obj 要与之比较的对象
|
||||||
|
*
|
||||||
|
* @return 如果对象相同,则返回 {@code true};否则返回 {@code false}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if ((null == obj) || (obj.getClass() != UUID.class))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UUID id = (UUID) obj;
|
||||||
|
return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison Operations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将此 UUID 与指定的 UUID 比较。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 如果两个 UUID 不同,且第一个 UUID 的最高有效字段大于第二个 UUID 的对应字段,则第一个 UUID 大于第二个 UUID。
|
||||||
|
*
|
||||||
|
* @param val 与此 UUID 比较的 UUID
|
||||||
|
*
|
||||||
|
* @return 在此 UUID 小于、等于或大于 val 时,分别返回 -1、0 或 1。
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(UUID val)
|
||||||
|
{
|
||||||
|
// The ordering is intentionally set up so that the UUIDs
|
||||||
|
// can simply be numerically compared as two numbers
|
||||||
|
return (this.mostSigBits < val.mostSigBits ? -1 : //
|
||||||
|
(this.mostSigBits > val.mostSigBits ? 1 : //
|
||||||
|
(this.leastSigBits < val.leastSigBits ? -1 : //
|
||||||
|
(this.leastSigBits > val.leastSigBits ? 1 : //
|
||||||
|
0))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------------------------------
|
||||||
|
// Private method start
|
||||||
|
/**
|
||||||
|
* 返回指定数字对应的hex值
|
||||||
|
*
|
||||||
|
* @param val 值
|
||||||
|
* @param digits 位
|
||||||
|
* @return 值
|
||||||
|
*/
|
||||||
|
private static String digits(long val, int digits)
|
||||||
|
{
|
||||||
|
long hi = 1L << (digits * 4);
|
||||||
|
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否为time-based版本UUID
|
||||||
|
*/
|
||||||
|
private void checkTimeBase()
|
||||||
|
{
|
||||||
|
if (version() != 1)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException("Not a time-based UUID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取{@link SecureRandom},类提供加密的强随机数生成器 (RNG)
|
||||||
|
*
|
||||||
|
* @return {@link SecureRandom}
|
||||||
|
*/
|
||||||
|
public static SecureRandom getSecureRandom()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return SecureRandom.getInstance("SHA1PRNG");
|
||||||
|
}
|
||||||
|
catch (NoSuchAlgorithmException e)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取随机数生成器对象<br>
|
||||||
|
* ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。
|
||||||
|
*
|
||||||
|
* @return {@link ThreadLocalRandom}
|
||||||
|
*/
|
||||||
|
public static ThreadLocalRandom getRandom()
|
||||||
|
{
|
||||||
|
return ThreadLocalRandom.current();
|
||||||
|
}
|
||||||
|
}
|
||||||
27
api-community/pom.xml
Normal file
27
api-community/pom.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?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"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-community</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
69
api-gateway/pom.xml
Normal file
69
api-gateway/pom.xml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?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"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-gateway</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-gateway-server</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- springcloud loadbalancer -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 负载均衡 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Actuator 监控 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- JWT -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>api-common</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.lxbtech.lxb.gateway;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
|
@SpringBootApplication()
|
||||||
|
@EnableDiscoveryClient()
|
||||||
|
@ComponentScan(basePackages = {
|
||||||
|
"com.lxbtech.lxb",
|
||||||
|
"com.alibaba.cloud.nacos" // 第三方组件包
|
||||||
|
})
|
||||||
|
public class GatewayApplication {
|
||||||
|
public static void main( String[] args){
|
||||||
|
SpringApplication.run(GatewayApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.lxbtech.lxb.gateway.config;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RateLimitConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public KeyResolver userKeyResolver() {
|
||||||
|
return exchange -> Mono.just(
|
||||||
|
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package com.lxbtech.lxb.gateway.config.properties;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 放行白名单配置
|
||||||
|
*
|
||||||
|
* @author ruoyi
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@RefreshScope
|
||||||
|
@ConfigurationProperties(prefix = "security.ignore")
|
||||||
|
public class IgnoreWhiteProperties
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 放行白名单配置,网关不校验此处的白名单
|
||||||
|
*/
|
||||||
|
private List<String> whites = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<String> getWhites()
|
||||||
|
{
|
||||||
|
return whites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWhites(List<String> whites)
|
||||||
|
{
|
||||||
|
this.whites = whites;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
package com.lxbtech.lxb.gateway.filter;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.*;
|
||||||
|
import com.lxbtech.lxb.common.redis.RedisService;
|
||||||
|
import com.lxbtech.lxb.common.utils.CustomStringUtils;
|
||||||
|
import com.lxbtech.lxb.common.utils.ServletUtils;
|
||||||
|
import com.lxb.gateway.config.properties.IgnoreWhiteProperties;
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AuthFilter implements GlobalFilter, Ordered
|
||||||
|
{
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AuthFilter.class);
|
||||||
|
|
||||||
|
// 排除过滤的 uri 地址,nacos自行添加
|
||||||
|
@Autowired
|
||||||
|
private IgnoreWhiteProperties ignoreWhite;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
|
||||||
|
{
|
||||||
|
ServerHttpRequest request = exchange.getRequest();
|
||||||
|
ServerHttpRequest.Builder mutate = request.mutate();
|
||||||
|
|
||||||
|
String url = request.getURI().getPath();
|
||||||
|
// 跳过不需要验证的路径
|
||||||
|
if (CustomStringUtils.matches(url, ignoreWhite.getWhites()))
|
||||||
|
{
|
||||||
|
return chain.filter(exchange);
|
||||||
|
}
|
||||||
|
String token = getRequestToken(request);
|
||||||
|
if (StringUtils.isEmpty(token))
|
||||||
|
{
|
||||||
|
return unauthorizedResponse(exchange, "令牌不能为空");
|
||||||
|
}
|
||||||
|
Claims claims = JwtUtils.parseToken(token);
|
||||||
|
if (claims == null)
|
||||||
|
{
|
||||||
|
return unauthorizedResponse(exchange, "令牌已过期或验证不正确!");
|
||||||
|
}
|
||||||
|
String userkey = JwtUtils.getUserKey(claims);
|
||||||
|
boolean islogin = redisService.hasKey(JwtUtils.getTokenKey(userkey));
|
||||||
|
if (!islogin)
|
||||||
|
{
|
||||||
|
return unauthorizedResponse(exchange, "登录状态已过期");
|
||||||
|
}
|
||||||
|
String userid = JwtUtils.getUserId(claims);
|
||||||
|
String username = JwtUtils.getUserName(claims);
|
||||||
|
if (StringUtils.isEmpty(userid) || StringUtils.isEmpty(username))
|
||||||
|
{
|
||||||
|
return unauthorizedResponse(exchange, "令牌验证失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置用户信息到请求
|
||||||
|
addHeader(mutate, SecurityConstants.USER_KEY, userkey);
|
||||||
|
addHeader(mutate, SecurityConstants.DETAILS_USER_ID, userid);
|
||||||
|
addHeader(mutate, SecurityConstants.DETAILS_USERNAME, username);
|
||||||
|
// 内部请求来源参数清除
|
||||||
|
removeHeader(mutate, SecurityConstants.FROM_SOURCE);
|
||||||
|
return chain.filter(exchange.mutate().request(mutate.build()).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeader(ServerHttpRequest.Builder mutate, String name, Object value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String valueStr = value.toString();
|
||||||
|
String valueEncode = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
valueEncode = URLEncoder.encode(valueStr, Constants.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e){}
|
||||||
|
mutate.header(name, valueEncode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeHeader(ServerHttpRequest.Builder mutate, String name)
|
||||||
|
{
|
||||||
|
mutate.headers(httpHeaders -> httpHeaders.remove(name)).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mono<Void> unauthorizedResponse(ServerWebExchange exchange, String msg)
|
||||||
|
{
|
||||||
|
log.error("[鉴权异常处理]请求路径:{},错误信息:{}", exchange.getRequest().getPath(), msg);
|
||||||
|
return ServletUtils.webFluxResponseWriter(exchange.getResponse(), msg, HttpStatus.UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求token
|
||||||
|
*/
|
||||||
|
private String getRequestToken(ServerHttpRequest request)
|
||||||
|
{
|
||||||
|
String token = request.getHeaders().getFirst(SecurityConstants.AUTHORIZATION_HEADER);
|
||||||
|
// 如果前端设置了令牌前缀,则裁剪掉前缀
|
||||||
|
if (!StringUtils.isEmpty(token) && token.startsWith(TokenConstants.PREFIX))
|
||||||
|
{
|
||||||
|
token = token.replaceFirst(TokenConstants.PREFIX, "");
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder()
|
||||||
|
{
|
||||||
|
return -200;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package com.lxbtech.lxb.gateway.filter;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RequestTrackingFilter implements GlobalFilter, Ordered {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
// 添加请求ID
|
||||||
|
String requestId = UUID.randomUUID().toString();
|
||||||
|
ServerHttpRequest request = exchange.getRequest().mutate()
|
||||||
|
.header("X-Request-ID", requestId)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 记录请求日志
|
||||||
|
System.out.printf("Incoming request %s %s%n",
|
||||||
|
request.getMethod(),
|
||||||
|
request.getPath());
|
||||||
|
|
||||||
|
return chain.filter(exchange.mutate().request(request).build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
api-gateway/src/main/resources/bootstrap.yml
Normal file
21
api-gateway/src/main/resources/bootstrap.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: api-gateway
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 127.0.0.1:8848
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 127.0.0.1:8848
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yaml
|
||||||
|
refresh-enabled: true
|
||||||
28
api-public/pom.xml
Normal file
28
api-public/pom.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?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"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>org.practice</groupId>
|
||||||
|
<artifactId>api-public</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
27
api-school/pom.xml
Normal file
27
api-school/pom.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?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"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-school</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
62
api-student/pom.xml
Normal file
62
api-student/pom.xml
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<?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"
|
||||||
|
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>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>api-student</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- springcloud loadbalancer -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-loadbalancer</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- mysql -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- 连接池 (可选) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>api-common</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.lxbtech.lxb.student;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication(exclude = {
|
||||||
|
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class,
|
||||||
|
org.mybatis.spring.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration.class
|
||||||
|
})
|
||||||
|
@EnableDiscoveryClient()
|
||||||
|
@ComponentScan(basePackages = {
|
||||||
|
"com.lxbtech.lxb"
|
||||||
|
})
|
||||||
|
public class StudentApplication {
|
||||||
|
public static void main( String[] args){
|
||||||
|
SpringApplication.run(StudentApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package com.lxbtech.lxb.student.controller;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.JwtUtils;
|
||||||
|
import com.lxbtech.lxb.common.Constants;
|
||||||
|
import com.lxbtech.lxb.common.SecurityConstants;
|
||||||
|
import com.lxbtech.lxb.common.domain.R;
|
||||||
|
import com.lxbtech.lxb.common.domain.StudentBean;
|
||||||
|
import com.lxbtech.lxb.common.redis.RedisService;
|
||||||
|
import com.lxbtech.lxb.common.utils.IdUtils;
|
||||||
|
import com.lxbtech.lxb.student.service.IStudentService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/student")
|
||||||
|
public class StudentController {
|
||||||
|
@Autowired
|
||||||
|
IStudentService studentService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public StudentBean getDataById(@PathVariable Long id){
|
||||||
|
return studentService.selectStudentById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @GetMapping("/{id}")
|
||||||
|
// public R<StudentBean> getDataById(@PathVariable Long id){
|
||||||
|
// return R.ok(studentService.selectStudentById(id));
|
||||||
|
// }
|
||||||
|
@PostMapping("/login")
|
||||||
|
public R<String> login(StudentBean requestBean){
|
||||||
|
StudentBean studentBean=studentService.selectStudentByUserName(requestBean.getUserName());
|
||||||
|
if (requestBean.getPassword().equals(studentBean.getPassword())) {
|
||||||
|
String userkey=IdUtils.fastUUID();
|
||||||
|
Map<String, Object> claims = new HashMap<>();
|
||||||
|
claims.put(SecurityConstants.USER_KEY, userkey);
|
||||||
|
claims.put(SecurityConstants.DETAILS_USER_ID, studentBean.getId());
|
||||||
|
claims.put(SecurityConstants.DETAILS_USERNAME, studentBean.getUserName());
|
||||||
|
claims.put(SecurityConstants.DETAILS_EMAIL, studentBean.getEmail());
|
||||||
|
String token=JwtUtils.createToken(claims);
|
||||||
|
redisService.setCacheObject(JwtUtils.getTokenKey(userkey),token,Constants.REDIS_TOKEN_TIME_OUT_DAY, TimeUnit.DAYS);
|
||||||
|
return R.ok(token);
|
||||||
|
}else
|
||||||
|
return R.fail("密码错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.lxbtech.lxb.student.mapper;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.domain.StudentBean;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface IStudentMapper {
|
||||||
|
@Select("SELECT id,user_name,phone,email,password,nickname,avatar FROM student "
|
||||||
|
+ "WHERE id=#{id}")
|
||||||
|
StudentBean getDateByStudentId(@Param("id") Long id);
|
||||||
|
@Select("SELECT id,user_name,phone,email,password,nickname,avatar FROM student "
|
||||||
|
+ "WHERE user_name=#{user_name} limit 1")
|
||||||
|
StudentBean getDateByStudentName(@Param("user_name") String userName);
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.lxbtech.lxb.student.service;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.domain.StudentBean;
|
||||||
|
|
||||||
|
public interface IStudentService {
|
||||||
|
/**
|
||||||
|
* 查询学生信息
|
||||||
|
*
|
||||||
|
* @param studentId 参数配置ID
|
||||||
|
* @return 参数配置信息
|
||||||
|
*/
|
||||||
|
public StudentBean selectStudentById(Long studentId);
|
||||||
|
public StudentBean selectStudentByUserName(String userName);
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.lxbtech.lxb.student.service.impl;
|
||||||
|
|
||||||
|
import com.lxbtech.lxb.common.domain.StudentBean;
|
||||||
|
import com.lxbtech.lxb.student.mapper.IStudentMapper;
|
||||||
|
import com.lxbtech.lxb.student.service.IStudentService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class StudentServiceImpl implements IStudentService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
IStudentMapper studentMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StudentBean selectStudentById(Long studentId) {
|
||||||
|
return studentMapper.getDateByStudentId(studentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StudentBean selectStudentByUserName(String userName) {
|
||||||
|
return studentMapper.getDateByStudentName(userName);
|
||||||
|
// return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
api-student/src/main/resources/bootstrap.yml
Normal file
21
api-student/src/main/resources/bootstrap.yml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 8090
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: api-student
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 127.0.0.1:8848
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 127.0.0.1:8848
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yaml
|
||||||
239
pom.xml
Normal file
239
pom.xml
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
<?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"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.lxbtech.lxb</groupId>
|
||||||
|
<artifactId>app_interface</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.18</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>api-gateway</module>
|
||||||
|
<module>api-common</module>
|
||||||
|
<module>api-student</module>
|
||||||
|
<module>api-school</module>
|
||||||
|
<module>api-community</module>
|
||||||
|
<module>api-public</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
<spring-boot.version>2.7.18</spring-boot.version>
|
||||||
|
<spring-cloud.version>2021.0.9</spring-cloud.version>
|
||||||
|
<spring-cloud-alibaba.version>2021.0.6.1</spring-cloud-alibaba.version>
|
||||||
|
<spring-boot-admin.version>2.7.16</spring-boot-admin.version>
|
||||||
|
<kaptcha.version>2.3.3</kaptcha.version>
|
||||||
|
<pagehelper.boot.version>2.0.0</pagehelper.boot.version>
|
||||||
|
<druid.version>1.2.23</druid.version>
|
||||||
|
<dynamic-ds.version>4.3.1</dynamic-ds.version>
|
||||||
|
<commons.io.version>2.13.0</commons.io.version>
|
||||||
|
<velocity.version>2.3</velocity.version>
|
||||||
|
<fastjson.version>2.0.53</fastjson.version>
|
||||||
|
<jjwt.version>0.9.1</jjwt.version>
|
||||||
|
<poi.version>4.1.2</poi.version>
|
||||||
|
<springdoc.version>1.6.9</springdoc.version>
|
||||||
|
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
|
||||||
|
<mybatis.version>2.2.2</mybatis.version>
|
||||||
|
<org.mybatis.version>3.5.17</org.mybatis.version>
|
||||||
|
<mysql.version>8.2.0</mysql.version>
|
||||||
|
<alibaba.druid.version>1.2.22</alibaba.druid.version>
|
||||||
|
<tomcat.version>9.0.102</tomcat.version>
|
||||||
|
<!-- override dependency version -->
|
||||||
|
<logback.version>1.2.13</logback.version>
|
||||||
|
<spring-framework.version>5.3.39</spring-framework.version>
|
||||||
|
<projectreactor.version>3.5.9</projectreactor.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<!-- 依赖声明 -->
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- 覆盖SpringFramework的依赖配置-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-framework-bom</artifactId>
|
||||||
|
<version>${spring-framework.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud 微服务 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot 依赖配置 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba 微服务 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||||
|
<version>${spring-cloud-alibaba.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<version>${mysql.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- 连接池 (可选) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
<version>${alibaba.druid.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis.spring.boot</groupId>
|
||||||
|
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||||
|
<version>${mybatis.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt</artifactId>
|
||||||
|
<version>${jjwt.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- 覆盖logback的依赖配置-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>${logback.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Springdoc webmvc 依赖配置 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-ui</artifactId>
|
||||||
|
<version>${springdoc.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- pagehelper 分页插件 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.pagehelper</groupId>
|
||||||
|
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||||
|
<version>${pagehelper.boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- io常用工具类 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>${commons.io.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JSON 解析器和生成器 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
<version>${fastjson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mybatis</groupId>
|
||||||
|
<artifactId>mybatis</artifactId>
|
||||||
|
<version>${org.mybatis.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>io.projectreactor</groupId>-->
|
||||||
|
<!-- <artifactId>reactor-core</artifactId>-->
|
||||||
|
<!-- <version>${projectreactor.version}</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- bootstrap 启动器 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
<encoding>${project.build.sourceEncoding}</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>public</id>
|
||||||
|
<name>aliyun nexus</name>
|
||||||
|
<url>https://maven.aliyun.com/repository/public</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>public</id>
|
||||||
|
<name>aliyun nexus</name>
|
||||||
|
<url>https://maven.aliyun.com/repository/public</url>
|
||||||
|
<releases>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</releases>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
</project>
|
||||||
Loading…
x
Reference in New Issue
Block a user