|
@@ -1,315 +1,379 @@
|
|
|
package com.scbfkj.uni.library;
|
|
|
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
import com.scbfkj.uni.process.DataBase;
|
|
|
import com.scbfkj.uni.system.Config;
|
|
|
+import jakarta.servlet.ServletInputStream;
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
|
import org.springframework.web.context.request.RequestContextHolder;
|
|
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
|
|
|
|
|
+import java.io.BufferedReader;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStreamReader;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
|
|
|
public class RequestUtil {
|
|
|
- public final static String APP_ID = "appid";
|
|
|
- private static final DataBase DATABASE = new DataBase();
|
|
|
-
|
|
|
- private RequestUtil() {
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取客户端IP地址
|
|
|
- * 该方法首先尝试从HTTP请求头中的"x-forwarded-for"字段获取IP地址,如果该字段不存在或为空,
|
|
|
- * 则尝试从"Proxy-Client-IP"字段获取,接着是"WL-Proxy-Client-IP"字段,
|
|
|
- * 如果所有尝试都失败或返回不可识别的值,则返回远程地址。
|
|
|
- * 注意:这个方法适用于通过代理或负载均衡服务器转发的请求获取真实客户端IP地址的场景。
|
|
|
- *
|
|
|
- * @return 客户端的IP地址字符串。如果无法确定客户端IP地址,则返回null。
|
|
|
- */
|
|
|
- public static String getIpAddr() {
|
|
|
- String ip = getHeader("x-forwarded-for"); // 尝试从"x-forwarded-for"头部获取IP地址
|
|
|
- String unknown = "unknown";
|
|
|
- if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
|
|
|
- ip = getHeader("Proxy-Client-IP"); // 如果失败,尝试从"Proxy-Client-IP"头部获取
|
|
|
- }
|
|
|
- if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
|
|
|
- ip = getHeader("WL-Proxy-Client-IP"); // 如果再次失败,尝试从"WL-Proxy-Client-IP"头部获取
|
|
|
- }
|
|
|
- if (ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip)) {
|
|
|
- ip = getRemoteAddr(); // 所有尝试失败,返回远程地址
|
|
|
- }
|
|
|
- return ip;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前请求的客户端IP地址。
|
|
|
- *
|
|
|
- * 该方法不接受任何参数,它通过检索当前线程绑定的ServletRequestAttributes,
|
|
|
- * 进而获取HttpServletRequest对象,最后从HttpServletRequest中提取客户端的IP地址。
|
|
|
- *
|
|
|
- * @return String 客户端的IP地址。
|
|
|
- */
|
|
|
- private static String getRemoteAddr() {
|
|
|
- // 获取当前请求的属性
|
|
|
- ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
- // 从属性中获取HttpServletRequest对象
|
|
|
- HttpServletRequest request = requestAttributes.getRequest();
|
|
|
- // 返回客户端的IP地址
|
|
|
- return request.getRemoteAddr();
|
|
|
- }
|
|
|
-
|
|
|
-/**
|
|
|
- * 获取应用令牌。
|
|
|
- * <p>此方法从请求头中获取名为"token"的字段值,并返回其字符串表示形式。
|
|
|
- * 如果找不到该字段或字段值为null,则返回null。</p>
|
|
|
- *
|
|
|
- * @return 如果找到有效的token,则返回其字符串形式;否则返回null。
|
|
|
- */
|
|
|
-public static String getAppToken() {
|
|
|
- // 从请求头中获取名为"token"的字段值
|
|
|
- Object appToken = getHeader("token");
|
|
|
- // 判断appToken是否非空,非空则返回其字符串形式,否则返回null
|
|
|
- return Objects.nonNull(appToken) ? appToken.toString() : null;
|
|
|
-}
|
|
|
+ public final static String APP_ID = "appid";
|
|
|
+ private static final DataBase DATABASE = new DataBase();
|
|
|
|
|
|
+ private RequestUtil() {
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 获取用户令牌。
|
|
|
- * <p>
|
|
|
- * 该方法从请求头中提取名为"usertoken"的字段,并返回其值。
|
|
|
- * 如果不存在该字段,则返回null。
|
|
|
- *
|
|
|
- * @return 用户令牌的字符串表示,如果不存在则返回null。
|
|
|
- */
|
|
|
- public static String getUserToken() {
|
|
|
- // 从请求头中获取名为"usertoken"的字段
|
|
|
- Object userToken = getHeader("usertoken");
|
|
|
- // 判断用户令牌是否非空,非空则返回其字符串形式,否则返回null
|
|
|
- return Objects.nonNull(userToken) ? userToken.toString() : null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前HTTP请求的指定头信息。
|
|
|
- *
|
|
|
- * @param headerName 需要获取的头名称。
|
|
|
- * @return 返回请求头中指定头名称的值。如果不存在该头,则返回null。
|
|
|
- */
|
|
|
- private static String getHeader(String headerName) {
|
|
|
- // 获取当前请求的属性
|
|
|
- ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
- // 从属性中获取HttpServletRequest对象
|
|
|
- HttpServletRequest request = requestAttributes.getRequest();
|
|
|
- // 返回指定头名称的值
|
|
|
- return request.getHeader(headerName);
|
|
|
- }
|
|
|
- /**
|
|
|
- * 获取当前HTTP请求的所有头信息。
|
|
|
- *
|
|
|
- * 该方法不接受任何参数,但需要当前线程绑定的HTTP请求上下文。
|
|
|
- *
|
|
|
- * @return 一个包含所有头信息的Map,其中头名称为键,头值为值。
|
|
|
- */
|
|
|
- public static Map<String, String> getHeaders() {
|
|
|
- // 获取当前请求的属性
|
|
|
- ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
- // 从属性中获取HttpServletRequest对象
|
|
|
- HttpServletRequest request = requestAttributes.getRequest();
|
|
|
- // 获取所有头名称的枚举
|
|
|
- Enumeration<String> headerNames = request.getHeaderNames();
|
|
|
- // 创建一个空的Map来存储头信息
|
|
|
- Map<String,String> headers = new HashMap<>();
|
|
|
- // 遍历所有头名称,并将它们及其对应的值添加到Map中
|
|
|
- while (headerNames.hasMoreElements()) {
|
|
|
- String element = headerNames.nextElement();
|
|
|
- headers.put(element,request.getHeader(element));
|
|
|
- }
|
|
|
- // 返回包含所有头信息的Map
|
|
|
- return headers;
|
|
|
- }
|
|
|
-
|
|
|
-/**
|
|
|
- * 获取应用程序ID。
|
|
|
- * 此方法首先尝试从会话ID中检索应用程序ID。如果会话ID不存在或相关应用程序ID未找到,
|
|
|
- * 则方法将尝试从应用程序实例中获取应用程序ID。
|
|
|
- *
|
|
|
- * @return 返回应用程序ID的字符串表示。如果无法获取有效的应用程序ID,则返回null。
|
|
|
- * @throws Exception 如果在获取会话ID或应用程序ID过程中遇到错误,则抛出异常。
|
|
|
- */
|
|
|
-public static String getAppId() throws Exception {
|
|
|
- String session = getSessionId(); // 尝试获取会话ID
|
|
|
- if (session == null) {
|
|
|
- return null; // 如果会话ID不存在,直接返回null
|
|
|
- }
|
|
|
- // 尝试从缓存中获取会话信息
|
|
|
- Map<String, Object> sessionMap = Config.CACHE.get(session);
|
|
|
- if (sessionMap == null) {
|
|
|
- sessionMap = new Hashtable<>(); // 如果会话信息不存在,则创建新的会话信息容器
|
|
|
- Config.CACHE.put(session, sessionMap); // 将新的会话信息容器放入缓存
|
|
|
- }
|
|
|
- // 尝试从会话信息中获取应用程序ID
|
|
|
- Object appid = sessionMap.get(APP_ID);
|
|
|
- if (Objects.nonNull(appid)) {
|
|
|
- return appid.toString(); // 如果找到应用程序ID,返回其字符串形式
|
|
|
- }
|
|
|
- // 如果在会话信息中未找到应用程序ID,尝试从应用程序实例中获取并返回
|
|
|
- return getApplication().get(APP_ID).toString();
|
|
|
-}
|
|
|
+ /**
|
|
|
+ * 获取客户端IP地址 该方法首先尝试从HTTP请求头中的"x-forwarded-for"字段获取IP地址,如果该字段不存在或为空,
|
|
|
+ * 则尝试从"Proxy-Client-IP"字段获取,接着是"WL-Proxy-Client-IP"字段, 如果所有尝试都失败或返回不可识别的值,则返回远程地址。
|
|
|
+ * 注意:这个方法适用于通过代理或负载均衡服务器转发的请求获取真实客户端IP地址的场景。
|
|
|
+ *
|
|
|
+ * @return 客户端的IP地址字符串。如果无法确定客户端IP地址,则返回null。
|
|
|
+ */
|
|
|
+ public static String getIpAddr() {
|
|
|
+ String ip = getHeader("x-forwarded-for"); // 尝试从"x-forwarded-for"头部获取IP地址
|
|
|
+ String unknown = "unknown";
|
|
|
+ if ( ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip) ) {
|
|
|
+ ip = getHeader("Proxy-Client-IP"); // 如果失败,尝试从"Proxy-Client-IP"头部获取
|
|
|
+ }
|
|
|
+ if ( ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip) ) {
|
|
|
+ ip = getHeader("WL-Proxy-Client-IP"); // 如果再次失败,尝试从"WL-Proxy-Client-IP"头部获取
|
|
|
+ }
|
|
|
+ if ( ip == null || ip.isEmpty() || unknown.equalsIgnoreCase(ip) ) {
|
|
|
+ ip = getRemoteAddr(); // 所有尝试失败,返回远程地址
|
|
|
+ }
|
|
|
+ return ip;
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取当前请求的客户端IP地址。
|
|
|
+ * <p>
|
|
|
+ * 该方法不接受任何参数,它通过检索当前线程绑定的ServletRequestAttributes, 进而获取HttpServletRequest对象,最后从HttpServletRequest中提取客户端的IP地址。
|
|
|
+ *
|
|
|
+ * @return String 客户端的IP地址。
|
|
|
+ */
|
|
|
+ private static String getRemoteAddr() {
|
|
|
+ // 获取当前请求的属性
|
|
|
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
+ // 从属性中获取HttpServletRequest对象
|
|
|
+ HttpServletRequest request = requestAttributes.getRequest();
|
|
|
+ // 返回客户端的IP地址
|
|
|
+ return request.getRemoteAddr();
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
- * 获取当前应用的信息。
|
|
|
- * <p>
|
|
|
- * 这个方法首先会尝试从会话中获取应用信息。如果会话中不存在该信息,则会通过应用令牌和请求IP来查询数据库,
|
|
|
- * 获取应用的详细信息,并将其保存到会话中,供后续使用。
|
|
|
- * </p>
|
|
|
- * @return 一个包含应用信息的Map对象。如果会话不存在或应用未登录,则返回null。
|
|
|
- * @throws Exception 如果查询数据库时发生错误,或者无法获取应用信息,则抛出异常。
|
|
|
- */
|
|
|
-public static Map<String, Object> getApplication() throws Exception {
|
|
|
-
|
|
|
- String session = getSessionId();
|
|
|
- String clean = "delete from appconnectlog where expiretime < ?";
|
|
|
-
|
|
|
- // 清理数据库中过期的连接日志
|
|
|
- DATABASE.update(Config.getSecurityConnectionStr(), clean, LocalDateTime.now());
|
|
|
-
|
|
|
- // 检查会话是否有效
|
|
|
- if (session == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- Map<String, Object> sessionMap = Config.CACHE.get(session);
|
|
|
- if (sessionMap == null) {
|
|
|
- sessionMap = new Hashtable<>();
|
|
|
- Config.CACHE.put(session, sessionMap);
|
|
|
- }
|
|
|
- // 尝试从会话映射中获取应用信息
|
|
|
- Object application = sessionMap.get("application");
|
|
|
- if (Objects.isNull(application)) {
|
|
|
- // 如果应用信息不存在,则通过应用令牌和IP地址查询应用连接日志
|
|
|
- String appToken = getAppToken();
|
|
|
- String requestIp = getIpAddr();
|
|
|
- String query = "select appid from appconnectlog where apptoken=? and requestip =? and expiretime > ?";
|
|
|
- List<Map<String, Object>> appConnectLogList = DATABASE.query(Config.getSecurityConnectionStr(), query,
|
|
|
- appToken, requestIp, LocalDateTime.now());
|
|
|
- // 如果查询结果为空,表示应用未登录
|
|
|
- if (appConnectLogList.isEmpty()) {
|
|
|
- throw new RuntimeException("当前连接未登录");
|
|
|
- }
|
|
|
- // 获取应用ID
|
|
|
- Map<String, Object> stringObjectMap = appConnectLogList.get(0);
|
|
|
- Object applicationid = stringObjectMap.get(APP_ID);
|
|
|
-
|
|
|
- // 根据应用ID查询应用的详细信息
|
|
|
- query = """
|
|
|
- select applicationid,
|
|
|
- appid,
|
|
|
- appsecret,
|
|
|
- appname,
|
|
|
- appengname,
|
|
|
- appdescribe,
|
|
|
- applogo,
|
|
|
- smalllogo,
|
|
|
- backgroundimage,
|
|
|
- apptokeneffective,
|
|
|
- securitycoderule,
|
|
|
- securitycodeeffective,
|
|
|
- multilogin,
|
|
|
- passwordrule,
|
|
|
- passwordeffective
|
|
|
- from application
|
|
|
- where appid = ?""";
|
|
|
- List<Map<String, Object>> applicationList = DATABASE.query(Config.getSecurityConnectionStr(), query, applicationid);
|
|
|
- // 如果查询结果为空,表示无法获取应用信息
|
|
|
- if (applicationList.isEmpty()) {
|
|
|
- throw new RuntimeException("获取应用失败");
|
|
|
- }
|
|
|
- // 保存查询到的应用信息到会话映射中
|
|
|
- application = applicationList.get(0);
|
|
|
-
|
|
|
- sessionMap.put("application", application);
|
|
|
-
|
|
|
- }
|
|
|
- // 将应用信息转换为Map对象并返回
|
|
|
- Map<String, Object> applicationMap = (Map<String, Object>) application;
|
|
|
-
|
|
|
- return applicationMap;
|
|
|
+ /**
|
|
|
+ * 获取应用令牌。
|
|
|
+ * <p>此方法从请求头中获取名为"token"的字段值,并返回其字符串表示形式。
|
|
|
+ * 如果找不到该字段或字段值为null,则返回null。</p>
|
|
|
+ *
|
|
|
+ * @return 如果找到有效的token,则返回其字符串形式;否则返回null。
|
|
|
+ */
|
|
|
+ public static String getAppToken() {
|
|
|
+ // 从请求头中获取名为"token"的字段值
|
|
|
+ Object appToken = getHeader("token");
|
|
|
+ // 判断appToken是否非空,非空则返回其字符串形式,否则返回null
|
|
|
+ return Objects.nonNull(appToken) ? appToken.toString() : null;
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取用户令牌。
|
|
|
+ * <p>
|
|
|
+ * 该方法从请求头中提取名为"usertoken"的字段,并返回其值。 如果不存在该字段,则返回null。
|
|
|
+ *
|
|
|
+ * @return 用户令牌的字符串表示,如果不存在则返回null。
|
|
|
+ */
|
|
|
+ public static String getUserToken() {
|
|
|
+ // 从请求头中获取名为"usertoken"的字段
|
|
|
+ Object userToken = getHeader("usertoken");
|
|
|
+ // 判断用户令牌是否非空,非空则返回其字符串形式,否则返回null
|
|
|
+ return Objects.nonNull(userToken) ? userToken.toString() : null;
|
|
|
+ }
|
|
|
|
|
|
-}
|
|
|
+ /**
|
|
|
+ * 获取当前HTTP请求的指定头信息。
|
|
|
+ *
|
|
|
+ * @param headerName 需要获取的头名称。
|
|
|
+ *
|
|
|
+ * @return 返回请求头中指定头名称的值。如果不存在该头,则返回null。
|
|
|
+ */
|
|
|
+ private static String getHeader(String headerName) {
|
|
|
+ // 获取当前请求的属性
|
|
|
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
+ // 从属性中获取HttpServletRequest对象
|
|
|
+ HttpServletRequest request = requestAttributes.getRequest();
|
|
|
+ // 返回指定头名称的值
|
|
|
+ return request.getHeader(headerName);
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 获取当前HTTP请求的所有头信息。
|
|
|
+ * <p>
|
|
|
+ * 该方法不接受任何参数,但需要当前线程绑定的HTTP请求上下文。
|
|
|
+ *
|
|
|
+ * @return 一个包含所有头信息的Map,其中头名称为键,头值为值。
|
|
|
+ */
|
|
|
+ public static Map<String, String> getHeaders() {
|
|
|
+ // 获取当前请求的属性
|
|
|
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
+ // 从属性中获取HttpServletRequest对象
|
|
|
+ HttpServletRequest request = requestAttributes.getRequest();
|
|
|
+ // 获取所有头名称的枚举
|
|
|
+ Enumeration<String> headerNames = request.getHeaderNames();
|
|
|
+ // 创建一个空的Map来存储头信息
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
+ // 遍历所有头名称,并将它们及其对应的值添加到Map中
|
|
|
+ while ( headerNames.hasMoreElements() ) {
|
|
|
+ String element = headerNames.nextElement();
|
|
|
+ headers.put(element, request.getHeader(element));
|
|
|
+ }
|
|
|
+ // 返回包含所有头信息的Map
|
|
|
+ return headers;
|
|
|
+ }
|
|
|
|
|
|
-/**
|
|
|
- * 获取用户ID。
|
|
|
- * <p>此方法不接受任何参数,尝试从外部获取用户信息,并提取其中的用户ID。</p>
|
|
|
- *
|
|
|
- * @return 返回用户ID的字符串形式。如果无法获取用户信息或用户信息中不包含用户ID,则返回null。
|
|
|
- */
|
|
|
-public static String getUserId() {
|
|
|
-
|
|
|
- // 尝试获取用户信息
|
|
|
- Map<String, Object> userInfo = getUserInfo();
|
|
|
- if (Objects.isNull(userInfo)) {
|
|
|
- return null;
|
|
|
- } else {
|
|
|
- // 从用户信息中提取用户ID,并转换为字符串格式
|
|
|
- Object userid = userInfo.get("userid");
|
|
|
- return Objects.isNull(userid) ? null : DataFormatUtil.toString(userid);
|
|
|
- }
|
|
|
-}
|
|
|
+ /**
|
|
|
+ * 获取应用程序ID。 此方法首先尝试从会话ID中检索应用程序ID。如果会话ID不存在或相关应用程序ID未找到, 则方法将尝试从应用程序实例中获取应用程序ID。
|
|
|
+ *
|
|
|
+ * @return 返回应用程序ID的字符串表示。如果无法获取有效的应用程序ID,则返回null。
|
|
|
+ *
|
|
|
+ * @throws Exception 如果在获取会话ID或应用程序ID过程中遇到错误,则抛出异常。
|
|
|
+ */
|
|
|
+ public static String getAppId() throws Exception {
|
|
|
+ String session = getSessionId(); // 尝试获取会话ID
|
|
|
+ if ( session == null ) {
|
|
|
+ return null; // 如果会话ID不存在,直接返回null
|
|
|
+ }
|
|
|
+ // 尝试从缓存中获取会话信息
|
|
|
+ Map<String, Object> sessionMap = Config.CACHE.get(session);
|
|
|
+ if ( sessionMap == null ) {
|
|
|
+ sessionMap = new Hashtable<>(); // 如果会话信息不存在,则创建新的会话信息容器
|
|
|
+ Config.CACHE.put(session, sessionMap); // 将新的会话信息容器放入缓存
|
|
|
+ }
|
|
|
+ // 尝试从会话信息中获取应用程序ID
|
|
|
+ Object appid = sessionMap.get(APP_ID);
|
|
|
+ if ( Objects.nonNull(appid) ) {
|
|
|
+ return appid.toString(); // 如果找到应用程序ID,返回其字符串形式
|
|
|
+ }
|
|
|
+ // 如果在会话信息中未找到应用程序ID,尝试从应用程序实例中获取并返回
|
|
|
+ return getApplication().get(APP_ID).toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前应用的信息。
|
|
|
+ * <p>
|
|
|
+ * 这个方法首先会尝试从会话中获取应用信息。如果会话中不存在该信息,则会通过应用令牌和请求IP来查询数据库, 获取应用的详细信息,并将其保存到会话中,供后续使用。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @return 一个包含应用信息的Map对象。如果会话不存在或应用未登录,则返回null。
|
|
|
+ *
|
|
|
+ * @throws Exception 如果查询数据库时发生错误,或者无法获取应用信息,则抛出异常。
|
|
|
+ */
|
|
|
+ public static Map<String, Object> getApplication() throws Exception {
|
|
|
+
|
|
|
+ String session = getSessionId();
|
|
|
+ String clean = "delete from appconnectlog where expiretime < ?";
|
|
|
+
|
|
|
+ // 清理数据库中过期的连接日志
|
|
|
+ DATABASE.update(Config.getSecurityConnectionStr(), clean, LocalDateTime.now());
|
|
|
+
|
|
|
+ // 检查会话是否有效
|
|
|
+ if ( session == null ) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Map<String, Object> sessionMap = Config.CACHE.get(session);
|
|
|
+ if ( sessionMap == null ) {
|
|
|
+ sessionMap = new Hashtable<>();
|
|
|
+ Config.CACHE.put(session, sessionMap);
|
|
|
+ }
|
|
|
+ // 尝试从会话映射中获取应用信息
|
|
|
+ Object application = sessionMap.get("application");
|
|
|
+ if ( Objects.isNull(application) ) {
|
|
|
+ // 如果应用信息不存在,则通过应用令牌和IP地址查询应用连接日志
|
|
|
+ String appToken = getAppToken();
|
|
|
+ String requestIp = getIpAddr();
|
|
|
+ String query = "select appid from appconnectlog where apptoken=? and requestip =? and expiretime > ?";
|
|
|
+ List<Map<String, Object>> appConnectLogList = DATABASE.query(Config.getSecurityConnectionStr(), query,
|
|
|
+ appToken, requestIp, LocalDateTime.now());
|
|
|
+ // 如果查询结果为空,表示应用未登录
|
|
|
+ if ( appConnectLogList.isEmpty() ) {
|
|
|
+ throw new RuntimeException("当前连接未登录");
|
|
|
+ }
|
|
|
+ // 获取应用ID
|
|
|
+ Map<String, Object> stringObjectMap = appConnectLogList.get(0);
|
|
|
+ Object applicationid = stringObjectMap.get(APP_ID);
|
|
|
+
|
|
|
+ // 根据应用ID查询应用的详细信息
|
|
|
+ query = """
|
|
|
+ select applicationid,
|
|
|
+ appid,
|
|
|
+ appsecret,
|
|
|
+ appname,
|
|
|
+ appengname,
|
|
|
+ appdescribe,
|
|
|
+ applogo,
|
|
|
+ smalllogo,
|
|
|
+ backgroundimage,
|
|
|
+ apptokeneffective,
|
|
|
+ securitycoderule,
|
|
|
+ securitycodeeffective,
|
|
|
+ multilogin,
|
|
|
+ passwordrule,
|
|
|
+ passwordeffective
|
|
|
+ from application
|
|
|
+ where appid = ?""";
|
|
|
+ List<Map<String, Object>> applicationList = DATABASE.query(Config.getSecurityConnectionStr(), query, applicationid);
|
|
|
+ // 如果查询结果为空,表示无法获取应用信息
|
|
|
+ if ( applicationList.isEmpty() ) {
|
|
|
+ throw new RuntimeException("获取应用失败");
|
|
|
+ }
|
|
|
+ // 保存查询到的应用信息到会话映射中
|
|
|
+ application = applicationList.get(0);
|
|
|
+
|
|
|
+ sessionMap.put("application", application);
|
|
|
+
|
|
|
+ }
|
|
|
+ // 将应用信息转换为Map对象并返回
|
|
|
+ Map<String, Object> applicationMap = (Map<String, Object>) application;
|
|
|
+
|
|
|
+ return applicationMap;
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户ID。
|
|
|
+ * <p>此方法不接受任何参数,尝试从外部获取用户信息,并提取其中的用户ID。</p>
|
|
|
+ *
|
|
|
+ * @return 返回用户ID的字符串形式。如果无法获取用户信息或用户信息中不包含用户ID,则返回null。
|
|
|
+ */
|
|
|
+ public static String getUserId() {
|
|
|
+
|
|
|
+ // 尝试获取用户信息
|
|
|
+ Map<String, Object> userInfo = getUserInfo();
|
|
|
+ if ( Objects.isNull(userInfo) ) {
|
|
|
+ return null;
|
|
|
+ } else {
|
|
|
+ // 从用户信息中提取用户ID,并转换为字符串格式
|
|
|
+ Object userid = userInfo.get("userid");
|
|
|
+ return Objects.isNull(userid) ? null : DataFormatUtil.toString(userid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取用户信息。 此方法会首先尝试从会话ID中获取用户信息,如果不存在,则返回null。 如果会话ID存在但对应用户信息为空,则创建一个新的用户信息容器并返回。
|
|
|
+ *
|
|
|
+ * @return Map<String, Object> 如果用户信息存在,则返回一个包含用户信息的Map;否则返回null。
|
|
|
+ */
|
|
|
+ public static Map<String, Object> getUserInfo() {
|
|
|
+
|
|
|
+ // 获取当前会话ID
|
|
|
+ String session = getSessionId();
|
|
|
+ // 如果会话ID为空,则直接返回null
|
|
|
+ if ( session == null ) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 尝试从缓存中获取会话对应的用户信息
|
|
|
+ Map<String, Object> sessionMap = Config.CACHE.get(session);
|
|
|
+ // 如果该会话ID未被缓存,创建一个新的会话信息容器并加入缓存
|
|
|
+ if ( sessionMap == null ) {
|
|
|
+ sessionMap = new Hashtable<>();
|
|
|
+ Config.CACHE.put(session, sessionMap);
|
|
|
+ }
|
|
|
+ // 尝试从会话信息容器中获取用户信息
|
|
|
+ Object userInfo = sessionMap.get("userinfo");
|
|
|
+ // 如果用户信息存在,则返回,否则返回null
|
|
|
+ return Objects.nonNull(userInfo) ? (Map<String, Object>) userInfo : null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取会话ID。
|
|
|
+ * <p>
|
|
|
+ * 该方法是一个静态方法,不需要实例化对象即可调用。它通过调用另一个名为getHeader的方法, 并传入参数"sessionid"来获取会话ID。会话ID通常用于追踪和识别用户在应用程序中的会话。
|
|
|
+ *
|
|
|
+ * @return 返回一个String类型的会话ID。如果无法获取到会话ID,则可能返回null或空字符串, 具体取决于getHeader方法的实现。
|
|
|
+ */
|
|
|
+ public static String getSessionId() {
|
|
|
+ return getHeader("sessionid");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前请求的URI。
|
|
|
+ * <p>
|
|
|
+ * 该方法不接受任何参数。
|
|
|
+ *
|
|
|
+ * @return 返回当前HTTP请求的URI字符串。
|
|
|
+ */
|
|
|
+ public static String getUri() {
|
|
|
+ // 获取当前请求的属性
|
|
|
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
+
|
|
|
+ // 从请求属性中提取并返回请求的URI
|
|
|
+ return requestAttributes.getRequest().getRequestURI();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前线程中的HttpServletRequest对象。 本方法主要用于在Spring MVC环境下,获取当前请求的HttpServletRequest对象。
|
|
|
+ * 通过利用Spring提供的RequestContextHolder工具类,可以方便地获取到当前线程绑定的请求属性, 进而获取到HttpServletRequest对象,以便进行后续的请求处理或信息获取操作。
|
|
|
+ *
|
|
|
+ * @return 当前线程中的HttpServletRequest对象,如果线程中没有绑定请求属性,则返回null。
|
|
|
+ */
|
|
|
+ public static HttpServletRequest getRequest() {
|
|
|
+ // 通过RequestContextHolder获取当前线程绑定的请求属性
|
|
|
+ ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
+
|
|
|
+ // 从请求属性中获取HttpServletRequest对象并返回
|
|
|
+ return requestAttributes.getRequest();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从HttpServletRequest中获取请求体的内容。
|
|
|
+ * <p>
|
|
|
+ * 注意:此操作会消费输入流,确保在调用此方法前未有其他组件读取过请求体
|
|
|
+ *
|
|
|
+ * @return 请求体中的字符串内容,如果发生IO异常则返回null。
|
|
|
+ */
|
|
|
+ public static String getRequestBody() {
|
|
|
+ HttpServletRequest request = getRequest();
|
|
|
+ try {
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
+ BufferedReader bufferedReader = null;
|
|
|
+
|
|
|
+ // 获取请求的输入流
|
|
|
+ ServletInputStream inputStream = request.getInputStream();
|
|
|
+ if ( inputStream != null ) {
|
|
|
+ bufferedReader = new BufferedReader(new InputStreamReader(inputStream, request.getCharacterEncoding()));
|
|
|
+
|
|
|
+ // 读取请求体内容
|
|
|
+ char[] charBuffer = new char[128];
|
|
|
+ int bytesRead = - 1;
|
|
|
+ while ( (bytesRead = bufferedReader.read(charBuffer)) > 0 ) {
|
|
|
+ stringBuilder.append(charBuffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String body = stringBuilder.toString();
|
|
|
+ try {
|
|
|
+ DataFormatUtil.getObjectMapper().readValue(body, Map.class);
|
|
|
+ } catch ( JsonProcessingException e ) {
|
|
|
+ Map<String, String> temp = new HashMap<>();
|
|
|
+ for ( String s : body.split("&") ) {
|
|
|
+ String[] strings = s.split("=");
|
|
|
+ temp.put(strings[0], strings[1]);
|
|
|
+ }
|
|
|
+ body = DataFormatUtil.toString(temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! request.getParameterMap().isEmpty() && stringBuilder.isEmpty() ) {
|
|
|
+ return DataFormatUtil.toString(request.getParameterMap());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭流(如果使用了bufferedReader)
|
|
|
+ if ( bufferedReader != null ) {
|
|
|
+ bufferedReader.close();
|
|
|
+ }
|
|
|
|
|
|
+ return body;
|
|
|
+ } catch ( IOException e ) {
|
|
|
+ // 处理读取时的IO异常
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 获取用户信息。
|
|
|
- * 此方法会首先尝试从会话ID中获取用户信息,如果不存在,则返回null。
|
|
|
- * 如果会话ID存在但对应用户信息为空,则创建一个新的用户信息容器并返回。
|
|
|
- *
|
|
|
- * @return Map<String, Object> 如果用户信息存在,则返回一个包含用户信息的Map;否则返回null。
|
|
|
- */
|
|
|
- public static Map<String, Object> getUserInfo() {
|
|
|
-
|
|
|
- // 获取当前会话ID
|
|
|
- String session = getSessionId();
|
|
|
- // 如果会话ID为空,则直接返回null
|
|
|
- if (session == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- // 尝试从缓存中获取会话对应的用户信息
|
|
|
- Map<String, Object> sessionMap = Config.CACHE.get(session);
|
|
|
- // 如果该会话ID未被缓存,创建一个新的会话信息容器并加入缓存
|
|
|
- if (sessionMap == null) {
|
|
|
- sessionMap = new Hashtable<>();
|
|
|
- Config.CACHE.put(session, sessionMap);
|
|
|
- }
|
|
|
- // 尝试从会话信息容器中获取用户信息
|
|
|
- Object userInfo = sessionMap.get("userinfo");
|
|
|
- // 如果用户信息存在,则返回,否则返回null
|
|
|
- return Objects.nonNull(userInfo) ? (Map<String, Object>) userInfo : null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取会话ID。
|
|
|
- *
|
|
|
- * 该方法是一个静态方法,不需要实例化对象即可调用。它通过调用另一个名为getHeader的方法,
|
|
|
- * 并传入参数"sessionid"来获取会话ID。会话ID通常用于追踪和识别用户在应用程序中的会话。
|
|
|
- *
|
|
|
- * @return 返回一个String类型的会话ID。如果无法获取到会话ID,则可能返回null或空字符串,
|
|
|
- * 具体取决于getHeader方法的实现。
|
|
|
- */
|
|
|
- public static String getSessionId() {
|
|
|
- return getHeader("sessionid");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前请求的URI。
|
|
|
- *
|
|
|
- * 该方法不接受任何参数。
|
|
|
- *
|
|
|
- * @return 返回当前HTTP请求的URI字符串。
|
|
|
- */
|
|
|
- public static String getUri() {
|
|
|
- // 获取当前请求的属性
|
|
|
- ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
|
|
|
-
|
|
|
- // 从请求属性中提取并返回请求的URI
|
|
|
- return requestAttributes.getRequest().getRequestURI();
|
|
|
- }
|
|
|
}
|