Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
杨图强
ewaytek-deepseek
Commits
0487b6d5
Commit
0487b6d5
authored
Aug 28, 2025
by
何处是我家
Browse files
提交
parents
Changes
148
Hide whitespace changes
Inline
Side-by-side
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/DesensitizedUtil.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
/**
* 脱敏工具类
*
* @author admin
*/
public
class
DesensitizedUtil
{
/**
* 密码的全部字符都用*代替,比如:******
*
* @param password 密码
* @return 脱敏后的密码
*/
public
static
String
password
(
String
password
)
{
if
(
StringUtils
.
isBlank
(
password
))
{
return
StringUtils
.
EMPTY
;
}
return
StringUtils
.
repeat
(
'*'
,
password
.
length
());
}
/**
* 车牌中间用*代替,如果是错误的车牌,不处理
*
* @param carLicense 完整的车牌号
* @return 脱敏后的车牌
*/
public
static
String
carLicense
(
String
carLicense
)
{
if
(
StringUtils
.
isBlank
(
carLicense
))
{
return
StringUtils
.
EMPTY
;
}
// 普通车牌
if
(
carLicense
.
length
()
==
7
)
{
carLicense
=
StringUtils
.
hide
(
carLicense
,
3
,
6
);
}
else
if
(
carLicense
.
length
()
==
8
)
{
// 新能源车牌
carLicense
=
StringUtils
.
hide
(
carLicense
,
3
,
7
);
}
return
carLicense
;
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/ExceptionUtil.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
import
org.apache.commons.lang3.exception.ExceptionUtils
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
/**
* 错误信息处理类。
*
* @author admin
*/
public
class
ExceptionUtil
{
/**
* 获取exception的详细错误信息。
*/
public
static
String
getExceptionMessage
(
Throwable
e
)
{
StringWriter
sw
=
new
StringWriter
();
e
.
printStackTrace
(
new
PrintWriter
(
sw
,
true
));
return
sw
.
toString
();
}
public
static
String
getRootErrorMessage
(
Exception
e
)
{
Throwable
root
=
ExceptionUtils
.
getRootCause
(
e
);
root
=
(
root
==
null
?
e
:
root
);
if
(
root
==
null
)
{
return
""
;
}
String
msg
=
root
.
getMessage
();
if
(
msg
==
null
)
{
return
"null"
;
}
return
StringUtils
.
defaultString
(
msg
);
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/LogUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
/**
* 处理并记录日志文件
*
* @author admin
*/
public
class
LogUtils
{
public
static
String
getBlock
(
Object
msg
)
{
if
(
msg
==
null
)
{
msg
=
""
;
}
return
"["
+
msg
+
"]"
;
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/MessageUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
import
com.ewaytek.deepseek.common.utils.spring.SpringUtils
;
import
org.springframework.context.MessageSource
;
import
org.springframework.context.i18n.LocaleContextHolder
;
/**
* 获取i18n资源文件
*
* @author admin
*/
public
class
MessageUtils
{
/**
* 根据消息键和参数 获取消息 委托给spring messageSource
*
* @param code 消息键
* @param args 参数
* @return 获取国际化翻译值
*/
public
static
String
message
(
String
code
,
Object
...
args
)
{
MessageSource
messageSource
=
SpringUtils
.
getBean
(
MessageSource
.
class
);
return
messageSource
.
getMessage
(
code
,
args
,
LocaleContextHolder
.
getLocale
());
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/ServletUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
import
com.ewaytek.deepseek.common.constant.Constants
;
import
com.ewaytek.deepseek.common.core.text.Convert
;
import
org.springframework.web.context.request.RequestAttributes
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
javax.servlet.ServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
javax.servlet.http.HttpSession
;
import
java.io.IOException
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLDecoder
;
import
java.net.URLEncoder
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 客户端工具类
*
* @author admin
*/
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
(),
StringUtils
.
join
(
entry
.
getValue
(),
","
));
}
return
params
;
}
/**
* 获取request
*/
public
static
HttpServletRequest
getRequest
()
{
return
getRequestAttributes
().
getRequest
();
}
/**
* 获取response
*/
public
static
HttpServletResponse
getResponse
()
{
return
getRequestAttributes
().
getResponse
();
}
/**
* 获取session
*/
public
static
HttpSession
getSession
()
{
return
getRequest
().
getSession
();
}
public
static
ServletRequestAttributes
getRequestAttributes
()
{
RequestAttributes
attributes
=
RequestContextHolder
.
getRequestAttributes
();
return
(
ServletRequestAttributes
)
attributes
;
}
/**
* 将字符串渲染到客户端
*
* @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
(
StringUtils
.
inStringIgnoreCase
(
uri
,
".json"
,
".xml"
))
{
return
true
;
}
String
ajax
=
request
.
getParameter
(
"__ajax"
);
return
StringUtils
.
inStringIgnoreCase
(
ajax
,
"json"
,
"xml"
);
}
/**
* 内容编码
*
* @param str 内容
* @return 编码后的内容
*/
public
static
String
urlEncode
(
String
str
)
{
try
{
return
URLEncoder
.
encode
(
str
,
Constants
.
UTF8
);
}
catch
(
UnsupportedEncodingException
e
)
{
return
StringUtils
.
EMPTY
;
}
}
/**
* 内容解码
*
* @param str 内容
* @return 解码后的内容
*/
public
static
String
urlDecode
(
String
str
)
{
try
{
return
URLDecoder
.
decode
(
str
,
Constants
.
UTF8
);
}
catch
(
UnsupportedEncodingException
e
)
{
return
StringUtils
.
EMPTY
;
}
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/StringUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
import
com.ewaytek.deepseek.common.constant.Constants
;
import
com.ewaytek.deepseek.common.core.text.StrFormatter
;
import
org.springframework.util.AntPathMatcher
;
import
java.util.*
;
/**
* 字符串工具类
*
* @author admin
*/
public
class
StringUtils
extends
org
.
apache
.
commons
.
lang3
.
StringUtils
{
/**
* 空字符串
*/
private
static
final
String
NULLSTR
=
""
;
/**
* 下划线
*/
private
static
final
char
SEPARATOR
=
'_'
;
/**
* 星号
*/
private
static
final
char
ASTERISK
=
'*'
;
/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public
static
<
T
>
T
nvl
(
T
value
,
T
defaultValue
)
{
return
value
!=
null
?
value
:
defaultValue
;
}
/**
* * 判断一个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
);
}
/**
* * 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true:非空 false:空
*/
public
static
boolean
isNotEmpty
(
Object
[]
objects
)
{
return
!
isEmpty
(
objects
);
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true:为空 false:非空
*/
public
static
boolean
isEmpty
(
Map
<?,
?>
map
)
{
return
isNull
(
map
)
||
map
.
isEmpty
();
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true:非空 false:空
*/
public
static
boolean
isNotEmpty
(
Map
<?,
?>
map
)
{
return
!
isEmpty
(
map
);
}
/**
* * 判断一个字符串是否为空串
*
* @param str String
* @return true:为空 false:非空
*/
public
static
boolean
isEmpty
(
String
str
)
{
return
isNull
(
str
)
||
NULLSTR
.
equals
(
str
.
trim
());
}
/**
* * 判断一个字符串是否为非空串
*
* @param str String
* @return true:非空串 false:空串
*/
public
static
boolean
isNotEmpty
(
String
str
)
{
return
!
isEmpty
(
str
);
}
/**
* * 判断一个对象是否为空
*
* @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
);
}
/**
* * 判断一个对象是否是数组类型(Java基本型别的数组)
*
* @param object 对象
* @return true:是数组 false:不是数组
*/
public
static
boolean
isArray
(
Object
object
)
{
return
isNotNull
(
object
)
&&
object
.
getClass
().
isArray
();
}
/**
* 去空格
*/
public
static
String
trim
(
String
str
)
{
return
(
str
==
null
?
""
:
str
.
trim
());
}
/**
* 替换指定字符串的指定区间内字符为"*"
*
* @param str 字符串
* @param startInclude 开始位置(包含)
* @param endExclude 结束位置(不包含)
* @return 替换后的字符串
*/
public
static
String
hide
(
CharSequence
str
,
int
startInclude
,
int
endExclude
)
{
if
(
isEmpty
(
str
))
{
return
NULLSTR
;
}
final
int
strLength
=
str
.
length
();
if
(
startInclude
>
strLength
)
{
return
NULLSTR
;
}
if
(
endExclude
>
strLength
)
{
endExclude
=
strLength
;
}
if
(
startInclude
>
endExclude
)
{
// 如果起始位置大于结束位置,不替换
return
NULLSTR
;
}
final
char
[]
chars
=
new
char
[
strLength
];
for
(
int
i
=
0
;
i
<
strLength
;
i
++)
{
if
(
i
>=
startInclude
&&
i
<
endExclude
)
{
chars
[
i
]
=
ASTERISK
;
}
else
{
chars
[
i
]
=
str
.
charAt
(
i
);
}
}
return
new
String
(
chars
);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public
static
String
substring
(
final
String
str
,
int
start
)
{
if
(
str
==
null
)
{
return
NULLSTR
;
}
if
(
start
<
0
)
{
start
=
str
.
length
()
+
start
;
}
if
(
start
<
0
)
{
start
=
0
;
}
if
(
start
>
str
.
length
())
{
return
NULLSTR
;
}
return
str
.
substring
(
start
);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public
static
String
substring
(
final
String
str
,
int
start
,
int
end
)
{
if
(
str
==
null
)
{
return
NULLSTR
;
}
if
(
end
<
0
)
{
end
=
str
.
length
()
+
end
;
}
if
(
start
<
0
)
{
start
=
str
.
length
()
+
start
;
}
if
(
end
>
str
.
length
())
{
end
=
str
.
length
();
}
if
(
start
>
end
)
{
return
NULLSTR
;
}
if
(
start
<
0
)
{
start
=
0
;
}
if
(
end
<
0
)
{
end
=
0
;
}
return
str
.
substring
(
start
,
end
);
}
/**
* 判断是否为空,并且不是空白字符
*
* @param str 要判断的value
* @return 结果
*/
public
static
boolean
hasText
(
String
str
)
{
return
(
str
!=
null
&&
!
str
.
isEmpty
()
&&
containsText
(
str
));
}
private
static
boolean
containsText
(
CharSequence
str
)
{
int
strLen
=
str
.
length
();
for
(
int
i
=
0
;
i
<
strLen
;
i
++)
{
if
(!
Character
.
isWhitespace
(
str
.
charAt
(
i
)))
{
return
true
;
}
}
return
false
;
}
/**
* 格式化文本, {} 表示占位符<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br>
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param template 文本模板,被替换的部分用 {} 表示
* @param params 参数值
* @return 格式化后的文本
*/
public
static
String
format
(
String
template
,
Object
...
params
)
{
if
(
isEmpty
(
params
)
||
isEmpty
(
template
))
{
return
template
;
}
return
StrFormatter
.
format
(
template
,
params
);
}
/**
* 是否为http(s)://开头
*
* @param link 链接
* @return 结果
*/
public
static
boolean
ishttp
(
String
link
)
{
return
StringUtils
.
startsWithAny
(
link
,
Constants
.
HTTP
,
Constants
.
HTTPS
);
}
/**
* 字符串转set
*
* @param str 字符串
* @param sep 分隔符
* @return set集合
*/
public
static
final
Set
<
String
>
str2Set
(
String
str
,
String
sep
)
{
return
new
HashSet
<
String
>(
str2List
(
str
,
sep
,
true
,
false
));
}
/**
* 字符串转list
*
* @param str 字符串
* @param sep 分隔符
* @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白
* @return list集合
*/
public
static
final
List
<
String
>
str2List
(
String
str
,
String
sep
,
boolean
filterBlank
,
boolean
trim
)
{
List
<
String
>
list
=
new
ArrayList
<
String
>();
if
(
StringUtils
.
isEmpty
(
str
))
{
return
list
;
}
// 过滤空白字符串
if
(
filterBlank
&&
StringUtils
.
isBlank
(
str
))
{
return
list
;
}
String
[]
split
=
str
.
split
(
sep
);
for
(
String
string
:
split
)
{
if
(
filterBlank
&&
StringUtils
.
isBlank
(
string
))
{
continue
;
}
if
(
trim
)
{
string
=
string
.
trim
();
}
list
.
add
(
string
);
}
return
list
;
}
/**
* 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
*
* @param collection 给定的集合
* @param array 给定的数组
* @return boolean 结果
*/
public
static
boolean
containsAny
(
Collection
<
String
>
collection
,
String
...
array
)
{
if
(
isEmpty
(
collection
)
||
isEmpty
(
array
))
{
return
false
;
}
else
{
for
(
String
str
:
array
)
{
if
(
collection
.
contains
(
str
))
{
return
true
;
}
}
return
false
;
}
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*
* @param cs 指定字符串
* @param searchCharSequences 需要检查的字符串数组
* @return 是否包含任意一个字符串
*/
public
static
boolean
containsAnyIgnoreCase
(
CharSequence
cs
,
CharSequence
...
searchCharSequences
)
{
if
(
isEmpty
(
cs
)
||
isEmpty
(
searchCharSequences
))
{
return
false
;
}
for
(
CharSequence
testStr
:
searchCharSequences
)
{
if
(
containsIgnoreCase
(
cs
,
testStr
))
{
return
true
;
}
}
return
false
;
}
/**
* 驼峰转下划线命名
*/
public
static
String
toUnderScoreCase
(
String
str
)
{
if
(
str
==
null
)
{
return
null
;
}
StringBuilder
sb
=
new
StringBuilder
();
// 前置字符是否大写
boolean
preCharIsUpperCase
=
true
;
// 当前字符是否大写
boolean
curreCharIsUpperCase
=
true
;
// 下一字符是否大写
boolean
nexteCharIsUpperCase
=
true
;
for
(
int
i
=
0
;
i
<
str
.
length
();
i
++)
{
char
c
=
str
.
charAt
(
i
);
if
(
i
>
0
)
{
preCharIsUpperCase
=
Character
.
isUpperCase
(
str
.
charAt
(
i
-
1
));
}
else
{
preCharIsUpperCase
=
false
;
}
curreCharIsUpperCase
=
Character
.
isUpperCase
(
c
);
if
(
i
<
(
str
.
length
()
-
1
))
{
nexteCharIsUpperCase
=
Character
.
isUpperCase
(
str
.
charAt
(
i
+
1
));
}
if
(
preCharIsUpperCase
&&
curreCharIsUpperCase
&&
!
nexteCharIsUpperCase
)
{
sb
.
append
(
SEPARATOR
);
}
else
if
((
i
!=
0
&&
!
preCharIsUpperCase
)
&&
curreCharIsUpperCase
)
{
sb
.
append
(
SEPARATOR
);
}
sb
.
append
(
Character
.
toLowerCase
(
c
));
}
return
sb
.
toString
();
}
/**
* 是否包含字符串
*
* @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
;
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public
static
String
convertToCamelCase
(
String
name
)
{
StringBuilder
result
=
new
StringBuilder
();
// 快速检查
if
(
name
==
null
||
name
.
isEmpty
())
{
// 没必要转换
return
""
;
}
else
if
(!
name
.
contains
(
"_"
))
{
// 不含下划线,仅将首字母大写
return
name
.
substring
(
0
,
1
).
toUpperCase
()
+
name
.
substring
(
1
);
}
// 用下划线将原始字符串分割
String
[]
camels
=
name
.
split
(
"_"
);
for
(
String
camel
:
camels
)
{
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if
(
camel
.
isEmpty
())
{
continue
;
}
// 首字母大写
result
.
append
(
camel
.
substring
(
0
,
1
).
toUpperCase
());
result
.
append
(
camel
.
substring
(
1
).
toLowerCase
());
}
return
result
.
toString
();
}
/**
* 驼峰式命名法
* 例如:user_name->userName
*/
public
static
String
toCamelCase
(
String
s
)
{
if
(
s
==
null
)
{
return
null
;
}
if
(
s
.
indexOf
(
SEPARATOR
)
==
-
1
)
{
return
s
;
}
s
=
s
.
toLowerCase
();
StringBuilder
sb
=
new
StringBuilder
(
s
.
length
());
boolean
upperCase
=
false
;
for
(
int
i
=
0
;
i
<
s
.
length
();
i
++)
{
char
c
=
s
.
charAt
(
i
);
if
(
c
==
SEPARATOR
)
{
upperCase
=
true
;
}
else
if
(
upperCase
)
{
sb
.
append
(
Character
.
toUpperCase
(
c
));
upperCase
=
false
;
}
else
{
sb
.
append
(
c
);
}
}
return
sb
.
toString
();
}
/**
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
*
* @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
;
}
/**
* 判断url是否与规则配置:
* ? 表示单个字符;
* * 表示一层路径内的任意字符串,不可跨层级;
* ** 表示任意层路径;
*
* @param pattern 匹配规则
* @param url 需要匹配的url
* @return
*/
public
static
boolean
isMatch
(
String
pattern
,
String
url
)
{
AntPathMatcher
matcher
=
new
AntPathMatcher
();
return
matcher
.
match
(
pattern
,
url
);
}
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
T
cast
(
Object
obj
)
{
return
(
T
)
obj
;
}
/**
* 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
*
* @param num 数字对象
* @param size 字符串指定长度
* @return 返回数字的字符串格式,该字符串为指定长度。
*/
public
static
final
String
padl
(
final
Number
num
,
final
int
size
)
{
return
padl
(
num
.
toString
(),
size
,
'0'
);
}
/**
* 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
*
* @param s 原始字符串
* @param size 字符串指定长度
* @param c 用于补齐的字符
* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
*/
public
static
final
String
padl
(
final
String
s
,
final
int
size
,
final
char
c
)
{
final
StringBuilder
sb
=
new
StringBuilder
(
size
);
if
(
s
!=
null
)
{
final
int
len
=
s
.
length
();
if
(
s
.
length
()
<=
size
)
{
for
(
int
i
=
size
-
len
;
i
>
0
;
i
--)
{
sb
.
append
(
c
);
}
sb
.
append
(
s
);
}
else
{
return
s
.
substring
(
len
-
size
,
len
);
}
}
else
{
for
(
int
i
=
size
;
i
>
0
;
i
--)
{
sb
.
append
(
c
);
}
}
return
sb
.
toString
();
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/Threads.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.util.concurrent.*
;
/**
* 线程相关工具类.
*
* @author admin
*/
public
class
Threads
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
Threads
.
class
);
/**
* sleep等待,单位为毫秒
*/
public
static
void
sleep
(
long
milliseconds
)
{
try
{
Thread
.
sleep
(
milliseconds
);
}
catch
(
InterruptedException
e
)
{
}
}
/**
* 停止线程池
* 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
* 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
* 如果仍然超時,則強制退出.
* 另对在shutdown时线程本身被调用中断做了处理.
*/
public
static
void
shutdownAndAwaitTermination
(
ExecutorService
pool
)
{
if
(
pool
!=
null
&&
!
pool
.
isShutdown
())
{
pool
.
shutdown
();
try
{
if
(!
pool
.
awaitTermination
(
120
,
TimeUnit
.
SECONDS
))
{
pool
.
shutdownNow
();
if
(!
pool
.
awaitTermination
(
120
,
TimeUnit
.
SECONDS
))
{
logger
.
info
(
"Pool did not terminate"
);
}
}
}
catch
(
InterruptedException
ie
)
{
pool
.
shutdownNow
();
Thread
.
currentThread
().
interrupt
();
}
}
}
/**
* 打印线程异常信息
*/
public
static
void
printException
(
Runnable
r
,
Throwable
t
)
{
if
(
t
==
null
&&
r
instanceof
Future
<?>)
{
try
{
Future
<?>
future
=
(
Future
<?>)
r
;
if
(
future
.
isDone
())
{
future
.
get
();
}
}
catch
(
CancellationException
ce
)
{
t
=
ce
;
}
catch
(
ExecutionException
ee
)
{
t
=
ee
.
getCause
();
}
catch
(
InterruptedException
ie
)
{
Thread
.
currentThread
().
interrupt
();
}
}
if
(
t
!=
null
)
{
logger
.
error
(
t
.
getMessage
(),
t
);
}
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/bean/BeanUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.bean
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* Bean 工具类
*
* @author admin
*/
public
class
BeanUtils
extends
org
.
springframework
.
beans
.
BeanUtils
{
/**
* Bean方法名中属性名开始的下标
*/
private
static
final
int
BEAN_METHOD_PROP_INDEX
=
3
;
/**
* 匹配getter方法的正则表达式
*/
private
static
final
Pattern
GET_PATTERN
=
Pattern
.
compile
(
"get(\\p{javaUpperCase}\\w*)"
);
/**
* 匹配setter方法的正则表达式
*/
private
static
final
Pattern
SET_PATTERN
=
Pattern
.
compile
(
"set(\\p{javaUpperCase}\\w*)"
);
/**
* Bean属性复制工具方法。
*
* @param dest 目标对象
* @param src 源对象
*/
public
static
void
copyBeanProp
(
Object
dest
,
Object
src
)
{
try
{
copyProperties
(
src
,
dest
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
/**
* 获取对象的setter方法。
*
* @param obj 对象
* @return 对象的setter方法列表
*/
public
static
List
<
Method
>
getSetterMethods
(
Object
obj
)
{
// setter方法列表
List
<
Method
>
setterMethods
=
new
ArrayList
<
Method
>();
// 获取所有方法
Method
[]
methods
=
obj
.
getClass
().
getMethods
();
// 查找setter方法
for
(
Method
method
:
methods
)
{
Matcher
m
=
SET_PATTERN
.
matcher
(
method
.
getName
());
if
(
m
.
matches
()
&&
(
method
.
getParameterTypes
().
length
==
1
))
{
setterMethods
.
add
(
method
);
}
}
// 返回setter方法列表
return
setterMethods
;
}
/**
* 获取对象的getter方法。
*
* @param obj 对象
* @return 对象的getter方法列表
*/
public
static
List
<
Method
>
getGetterMethods
(
Object
obj
)
{
// getter方法列表
List
<
Method
>
getterMethods
=
new
ArrayList
<
Method
>();
// 获取所有方法
Method
[]
methods
=
obj
.
getClass
().
getMethods
();
// 查找getter方法
for
(
Method
method
:
methods
)
{
Matcher
m
=
GET_PATTERN
.
matcher
(
method
.
getName
());
if
(
m
.
matches
()
&&
(
method
.
getParameterTypes
().
length
==
0
))
{
getterMethods
.
add
(
method
);
}
}
// 返回getter方法列表
return
getterMethods
;
}
/**
* 检查Bean方法名中的属性名是否相等。<br>
* 如getName()和setName()属性名一样,getName()和setAge()属性名不一样。
*
* @param m1 方法名1
* @param m2 方法名2
* @return 属性名一样返回true,否则返回false
*/
public
static
boolean
isMethodPropEquals
(
String
m1
,
String
m2
)
{
return
m1
.
substring
(
BEAN_METHOD_PROP_INDEX
).
equals
(
m2
.
substring
(
BEAN_METHOD_PROP_INDEX
));
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/bean/BeanValidators.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.bean
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.ConstraintViolationException
;
import
javax.xml.validation.Validator
;
import
java.util.Set
;
/**
* bean对象属性验证
*
* @author admin
*/
public
class
BeanValidators
{
public
static
void
validateWithException
(
Validator
validator
,
Object
object
,
Class
<?>...
groups
)
throws
ConstraintViolationException
{
// Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
// if (!constraintViolations.isEmpty()) {
// throw new ConstraintViolationException(constraintViolations);
// }
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/file/FileTypeUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.file
;
import
org.apache.commons.lang3.StringUtils
;
import
java.io.File
;
/**
* 文件类型工具类
*
* @author admin
*/
public
class
FileTypeUtils
{
/**
* 获取文件类型
* <p>
* 例如: robot.txt, 返回: txt
*
* @param file 文件名
* @return 后缀(不含".")
*/
public
static
String
getFileType
(
File
file
)
{
if
(
null
==
file
)
{
return
StringUtils
.
EMPTY
;
}
return
getFileType
(
file
.
getName
());
}
/**
* 获取文件类型
* <p>
* 例如: robot.txt, 返回: txt
*
* @param fileName 文件名
* @return 后缀(不含".")
*/
public
static
String
getFileType
(
String
fileName
)
{
int
separatorIndex
=
fileName
.
lastIndexOf
(
"."
);
if
(
separatorIndex
<
0
)
{
return
""
;
}
return
fileName
.
substring
(
separatorIndex
+
1
).
toLowerCase
();
}
/**
* 获取文件类型
*
* @param photoByte 文件字节码
* @return 后缀(不含".")
*/
public
static
String
getFileExtendName
(
byte
[]
photoByte
)
{
String
strFileExtendName
=
"JPG"
;
if
((
photoByte
[
0
]
==
71
)
&&
(
photoByte
[
1
]
==
73
)
&&
(
photoByte
[
2
]
==
70
)
&&
(
photoByte
[
3
]
==
56
)
&&
((
photoByte
[
4
]
==
55
)
||
(
photoByte
[
4
]
==
57
))
&&
(
photoByte
[
5
]
==
97
))
{
strFileExtendName
=
"GIF"
;
}
else
if
((
photoByte
[
6
]
==
74
)
&&
(
photoByte
[
7
]
==
70
)
&&
(
photoByte
[
8
]
==
73
)
&&
(
photoByte
[
9
]
==
70
))
{
strFileExtendName
=
"JPG"
;
}
else
if
((
photoByte
[
0
]
==
66
)
&&
(
photoByte
[
1
]
==
77
))
{
strFileExtendName
=
"BMP"
;
}
else
if
((
photoByte
[
1
]
==
80
)
&&
(
photoByte
[
2
]
==
78
)
&&
(
photoByte
[
3
]
==
71
))
{
strFileExtendName
=
"PNG"
;
}
return
strFileExtendName
;
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/file/FileUploadUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.file
;
import
com.ewaytek.deepseek.common.config.DeepseekConfig
;
import
com.ewaytek.deepseek.common.constant.Constants
;
import
com.ewaytek.deepseek.common.exception.file.FileNameLengthLimitExceededException
;
import
com.ewaytek.deepseek.common.exception.file.FileSizeLimitExceededException
;
import
com.ewaytek.deepseek.common.exception.file.InvalidExtensionException
;
import
com.ewaytek.deepseek.common.utils.DateUtils
;
import
com.ewaytek.deepseek.common.utils.StringUtils
;
import
com.ewaytek.deepseek.common.utils.uuid.Seq
;
import
org.apache.commons.io.FilenameUtils
;
import
org.springframework.web.multipart.MultipartFile
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.file.Paths
;
import
java.util.Objects
;
/**
* 文件上传工具类
*
* @author admin
*/
public
class
FileUploadUtils
{
/**
* 默认大小 50M
*/
public
static
final
long
DEFAULT_MAX_SIZE
=
50
*
1024
*
1024L
;
/**
* 默认的文件名最大长度 100
*/
public
static
final
int
DEFAULT_FILE_NAME_LENGTH
=
100
;
/**
* 默认上传的地址
*/
private
static
String
defaultBaseDir
=
DeepseekConfig
.
getProfile
();
public
static
String
getDefaultBaseDir
()
{
return
defaultBaseDir
;
}
public
static
void
setDefaultBaseDir
(
String
defaultBaseDir
)
{
FileUploadUtils
.
defaultBaseDir
=
defaultBaseDir
;
}
/**
* 以默认配置进行文件上传
*
* @param file 上传的文件
* @return 文件名称
* @throws Exception
*/
public
static
final
String
upload
(
MultipartFile
file
)
throws
IOException
{
try
{
return
upload
(
getDefaultBaseDir
(),
file
,
MimeTypeUtils
.
DEFAULT_ALLOWED_EXTENSION
);
}
catch
(
Exception
e
)
{
throw
new
IOException
(
e
.
getMessage
(),
e
);
}
}
/**
* 根据文件路径上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @return 文件名称
* @throws IOException
*/
public
static
final
String
upload
(
String
baseDir
,
MultipartFile
file
)
throws
IOException
{
try
{
return
upload
(
baseDir
,
file
,
MimeTypeUtils
.
DEFAULT_ALLOWED_EXTENSION
);
}
catch
(
Exception
e
)
{
throw
new
IOException
(
e
.
getMessage
(),
e
);
}
}
/**
* 文件上传
*
* @param baseDir 相对应用的基目录
* @param file 上传的文件
* @param allowedExtension 上传文件类型
* @return 返回上传成功的文件名
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws FileNameLengthLimitExceededException 文件名太长
* @throws IOException 比如读写文件出错时
* @throws InvalidExtensionException 文件校验异常
*/
public
static
final
String
upload
(
String
baseDir
,
MultipartFile
file
,
String
[]
allowedExtension
)
throws
FileSizeLimitExceededException
,
IOException
,
FileNameLengthLimitExceededException
,
InvalidExtensionException
{
int
fileNameLength
=
Objects
.
requireNonNull
(
file
.
getOriginalFilename
()).
length
();
if
(
fileNameLength
>
FileUploadUtils
.
DEFAULT_FILE_NAME_LENGTH
)
{
throw
new
FileNameLengthLimitExceededException
(
FileUploadUtils
.
DEFAULT_FILE_NAME_LENGTH
);
}
assertAllowed
(
file
,
allowedExtension
);
String
fileName
=
extractFilename
(
file
);
String
absPath
=
getAbsoluteFile
(
baseDir
,
fileName
).
getAbsolutePath
();
file
.
transferTo
(
Paths
.
get
(
absPath
));
return
getPathFileName
(
baseDir
,
fileName
);
}
/**
* 编码文件名
*/
public
static
final
String
extractFilename
(
MultipartFile
file
)
{
return
StringUtils
.
format
(
"{}/{}_{}.{}"
,
DateUtils
.
datePath
(),
FilenameUtils
.
getBaseName
(
file
.
getOriginalFilename
()),
Seq
.
getId
(
Seq
.
uploadSeqType
),
getExtension
(
file
));
}
public
static
final
File
getAbsoluteFile
(
String
uploadDir
,
String
fileName
)
throws
IOException
{
File
desc
=
new
File
(
uploadDir
+
File
.
separator
+
fileName
);
if
(!
desc
.
exists
())
{
if
(!
desc
.
getParentFile
().
exists
())
{
desc
.
getParentFile
().
mkdirs
();
}
}
return
desc
;
}
public
static
final
String
getPathFileName
(
String
uploadDir
,
String
fileName
)
throws
IOException
{
int
dirLastIndex
=
DeepseekConfig
.
getProfile
().
length
()
+
1
;
String
currentDir
=
StringUtils
.
substring
(
uploadDir
,
dirLastIndex
);
return
Constants
.
RESOURCE_PREFIX
+
"/"
+
currentDir
+
"/"
+
fileName
;
}
/**
* 文件大小校验
*
* @param file 上传的文件
* @return
* @throws FileSizeLimitExceededException 如果超出最大大小
* @throws InvalidExtensionException
*/
public
static
final
void
assertAllowed
(
MultipartFile
file
,
String
[]
allowedExtension
)
throws
FileSizeLimitExceededException
,
InvalidExtensionException
{
long
size
=
file
.
getSize
();
if
(
size
>
DEFAULT_MAX_SIZE
)
{
throw
new
FileSizeLimitExceededException
(
DEFAULT_MAX_SIZE
/
1024
/
1024
);
}
String
fileName
=
file
.
getOriginalFilename
();
String
extension
=
getExtension
(
file
);
if
(
allowedExtension
!=
null
&&
!
isAllowedExtension
(
extension
,
allowedExtension
))
{
if
(
allowedExtension
==
MimeTypeUtils
.
IMAGE_EXTENSION
)
{
throw
new
InvalidExtensionException
.
InvalidImageExtensionException
(
allowedExtension
,
extension
,
fileName
);
}
else
if
(
allowedExtension
==
MimeTypeUtils
.
FLASH_EXTENSION
)
{
throw
new
InvalidExtensionException
.
InvalidFlashExtensionException
(
allowedExtension
,
extension
,
fileName
);
}
else
if
(
allowedExtension
==
MimeTypeUtils
.
MEDIA_EXTENSION
)
{
throw
new
InvalidExtensionException
.
InvalidMediaExtensionException
(
allowedExtension
,
extension
,
fileName
);
}
else
if
(
allowedExtension
==
MimeTypeUtils
.
VIDEO_EXTENSION
)
{
throw
new
InvalidExtensionException
.
InvalidVideoExtensionException
(
allowedExtension
,
extension
,
fileName
);
}
else
{
throw
new
InvalidExtensionException
(
allowedExtension
,
extension
,
fileName
);
}
}
}
/**
* 判断MIME类型是否是允许的MIME类型
*
* @param extension
* @param allowedExtension
* @return
*/
public
static
final
boolean
isAllowedExtension
(
String
extension
,
String
[]
allowedExtension
)
{
for
(
String
str
:
allowedExtension
)
{
if
(
str
.
equalsIgnoreCase
(
extension
))
{
return
true
;
}
}
return
false
;
}
/**
* 获取文件名的后缀
*
* @param file 表单文件
* @return 后缀名
*/
public
static
final
String
getExtension
(
MultipartFile
file
)
{
String
extension
=
FilenameUtils
.
getExtension
(
file
.
getOriginalFilename
());
if
(
StringUtils
.
isEmpty
(
extension
))
{
extension
=
MimeTypeUtils
.
getExtension
(
Objects
.
requireNonNull
(
file
.
getContentType
()));
}
return
extension
;
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/file/FileUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.file
;
import
com.ewaytek.deepseek.common.config.DeepseekConfig
;
import
com.ewaytek.deepseek.common.utils.DateUtils
;
import
com.ewaytek.deepseek.common.utils.StringUtils
;
import
com.ewaytek.deepseek.common.utils.uuid.IdUtils
;
import
org.apache.commons.io.FilenameUtils
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang3.ArrayUtils
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.*
;
import
java.net.URLEncoder
;
import
java.nio.charset.StandardCharsets
;
/**
* 文件处理工具类
*
* @author admin
*/
public
class
FileUtils
{
public
static
String
FILENAME_PATTERN
=
"[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"
;
/**
* 输出指定文件的byte数组
*
* @param filePath 文件路径
* @param os 输出流
* @return
*/
public
static
void
writeBytes
(
String
filePath
,
OutputStream
os
)
throws
IOException
{
FileInputStream
fis
=
null
;
try
{
File
file
=
new
File
(
filePath
);
if
(!
file
.
exists
())
{
throw
new
FileNotFoundException
(
filePath
);
}
fis
=
new
FileInputStream
(
file
);
byte
[]
b
=
new
byte
[
1024
];
int
length
;
while
((
length
=
fis
.
read
(
b
))
>
0
)
{
os
.
write
(
b
,
0
,
length
);
}
}
catch
(
IOException
e
)
{
throw
e
;
}
finally
{
IOUtils
.
close
(
os
);
IOUtils
.
close
(
fis
);
}
}
/**
* 写数据到文件中
*
* @param data 数据
* @return 目标文件
* @throws IOException IO异常
*/
public
static
String
writeImportBytes
(
byte
[]
data
)
throws
IOException
{
return
writeBytes
(
data
,
DeepseekConfig
.
getImportPath
());
}
/**
* 写数据到文件中
*
* @param data 数据
* @param uploadDir 目标文件
* @return 目标文件
* @throws IOException IO异常
*/
public
static
String
writeBytes
(
byte
[]
data
,
String
uploadDir
)
throws
IOException
{
FileOutputStream
fos
=
null
;
String
pathName
=
""
;
try
{
String
extension
=
getFileExtendName
(
data
);
pathName
=
DateUtils
.
datePath
()
+
"/"
+
IdUtils
.
fastUUID
()
+
"."
+
extension
;
File
file
=
FileUploadUtils
.
getAbsoluteFile
(
uploadDir
,
pathName
);
fos
=
new
FileOutputStream
(
file
);
fos
.
write
(
data
);
}
finally
{
IOUtils
.
close
(
fos
);
}
return
FileUploadUtils
.
getPathFileName
(
uploadDir
,
pathName
);
}
/**
* 删除文件
*
* @param filePath 文件
* @return
*/
public
static
boolean
deleteFile
(
String
filePath
)
{
boolean
flag
=
false
;
File
file
=
new
File
(
filePath
);
// 路径为文件且不为空则进行删除
if
(
file
.
isFile
()
&&
file
.
exists
())
{
flag
=
file
.
delete
();
}
return
flag
;
}
/**
* 文件名称验证
*
* @param filename 文件名称
* @return true 正常 false 非法
*/
public
static
boolean
isValidFilename
(
String
filename
)
{
return
filename
.
matches
(
FILENAME_PATTERN
);
}
/**
* 检查文件是否可下载
*
* @param resource 需要下载的文件
* @return true 正常 false 非法
*/
public
static
boolean
checkAllowDownload
(
String
resource
)
{
// 禁止目录上跳级别
if
(
StringUtils
.
contains
(
resource
,
".."
))
{
return
false
;
}
// 检查允许下载的文件规则
return
ArrayUtils
.
contains
(
MimeTypeUtils
.
DEFAULT_ALLOWED_EXTENSION
,
FileTypeUtils
.
getFileType
(
resource
));
// 不在允许下载的文件规则
}
/**
* 下载文件名重新编码
*
* @param request 请求对象
* @param fileName 文件名
* @return 编码后的文件名
*/
public
static
String
setFileDownloadHeader
(
HttpServletRequest
request
,
String
fileName
)
throws
UnsupportedEncodingException
{
final
String
agent
=
request
.
getHeader
(
"USER-AGENT"
);
String
filename
=
fileName
;
if
(
agent
.
contains
(
"MSIE"
))
{
// IE浏览器
filename
=
URLEncoder
.
encode
(
filename
,
"utf-8"
);
filename
=
filename
.
replace
(
"+"
,
" "
);
}
else
if
(
agent
.
contains
(
"Firefox"
))
{
// 火狐浏览器
filename
=
new
String
(
fileName
.
getBytes
(),
"ISO8859-1"
);
}
else
if
(
agent
.
contains
(
"Chrome"
))
{
// google浏览器
filename
=
URLEncoder
.
encode
(
filename
,
"utf-8"
);
}
else
{
// 其它浏览器
filename
=
URLEncoder
.
encode
(
filename
,
"utf-8"
);
}
return
filename
;
}
/**
* 下载文件名重新编码
*
* @param response 响应对象
* @param realFileName 真实文件名
*/
public
static
void
setAttachmentResponseHeader
(
HttpServletResponse
response
,
String
realFileName
)
throws
UnsupportedEncodingException
{
String
percentEncodedFileName
=
percentEncode
(
realFileName
);
String
contentDispositionValue
=
"attachment; filename="
+
percentEncodedFileName
+
";"
+
"filename*="
+
"utf-8''"
+
percentEncodedFileName
;
response
.
addHeader
(
"Access-Control-Expose-Headers"
,
"Content-Disposition,download-filename"
);
response
.
setHeader
(
"Content-disposition"
,
contentDispositionValue
);
response
.
setHeader
(
"download-filename"
,
percentEncodedFileName
);
}
/**
* 百分号编码工具方法
*
* @param s 需要百分号编码的字符串
* @return 百分号编码后的字符串
*/
public
static
String
percentEncode
(
String
s
)
throws
UnsupportedEncodingException
{
String
encode
=
URLEncoder
.
encode
(
s
,
StandardCharsets
.
UTF_8
.
toString
());
return
encode
.
replaceAll
(
"\\+"
,
"%20"
);
}
/**
* 获取图像后缀
*
* @param photoByte 图像数据
* @return 后缀名
*/
public
static
String
getFileExtendName
(
byte
[]
photoByte
)
{
String
strFileExtendName
=
"jpg"
;
if
((
photoByte
[
0
]
==
71
)
&&
(
photoByte
[
1
]
==
73
)
&&
(
photoByte
[
2
]
==
70
)
&&
(
photoByte
[
3
]
==
56
)
&&
((
photoByte
[
4
]
==
55
)
||
(
photoByte
[
4
]
==
57
))
&&
(
photoByte
[
5
]
==
97
))
{
strFileExtendName
=
"gif"
;
}
else
if
((
photoByte
[
6
]
==
74
)
&&
(
photoByte
[
7
]
==
70
)
&&
(
photoByte
[
8
]
==
73
)
&&
(
photoByte
[
9
]
==
70
))
{
strFileExtendName
=
"jpg"
;
}
else
if
((
photoByte
[
0
]
==
66
)
&&
(
photoByte
[
1
]
==
77
))
{
strFileExtendName
=
"bmp"
;
}
else
if
((
photoByte
[
1
]
==
80
)
&&
(
photoByte
[
2
]
==
78
)
&&
(
photoByte
[
3
]
==
71
))
{
strFileExtendName
=
"png"
;
}
return
strFileExtendName
;
}
/**
* 获取文件名称 /profile/upload/2022/04/16/robot.png -- robot.png
*
* @param fileName 路径名称
* @return 没有文件路径的名称
*/
public
static
String
getName
(
String
fileName
)
{
if
(
fileName
==
null
)
{
return
null
;
}
int
lastUnixPos
=
fileName
.
lastIndexOf
(
'/'
);
int
lastWindowsPos
=
fileName
.
lastIndexOf
(
'\\'
);
int
index
=
Math
.
max
(
lastUnixPos
,
lastWindowsPos
);
return
fileName
.
substring
(
index
+
1
);
}
/**
* 获取不带后缀文件名称 /profile/upload/2022/04/16/robot.png -- robot
*
* @param fileName 路径名称
* @return 没有文件路径和后缀的名称
*/
public
static
String
getNameNotSuffix
(
String
fileName
)
{
if
(
fileName
==
null
)
{
return
null
;
}
String
baseName
=
FilenameUtils
.
getBaseName
(
fileName
);
return
baseName
;
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/file/ImageUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.file
;
import
com.ewaytek.deepseek.common.config.DeepseekConfig
;
import
com.ewaytek.deepseek.common.constant.Constants
;
import
com.ewaytek.deepseek.common.utils.StringUtils
;
import
org.apache.commons.io.IOUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.io.ByteArrayInputStream
;
import
java.io.FileInputStream
;
import
java.io.InputStream
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.util.Arrays
;
/**
* 图片处理工具类
*
* @author admin
*/
public
class
ImageUtils
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
ImageUtils
.
class
);
public
static
byte
[]
getImage
(
String
imagePath
)
{
InputStream
is
=
getFile
(
imagePath
);
try
{
return
IOUtils
.
toByteArray
(
is
);
}
catch
(
Exception
e
)
{
log
.
error
(
"图片加载异常 {}"
,
e
);
return
null
;
}
finally
{
IOUtils
.
closeQuietly
(
is
);
}
}
public
static
InputStream
getFile
(
String
imagePath
)
{
try
{
byte
[]
result
=
readFile
(
imagePath
);
result
=
Arrays
.
copyOf
(
result
,
result
.
length
);
return
new
ByteArrayInputStream
(
result
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取图片异常 {}"
,
e
);
}
return
null
;
}
/**
* 读取文件为字节数据
*
* @param url 地址
* @return 字节数据
*/
public
static
byte
[]
readFile
(
String
url
)
{
InputStream
in
=
null
;
try
{
if
(
url
.
startsWith
(
"http"
))
{
// 网络地址
URL
urlObj
=
new
URL
(
url
);
URLConnection
urlConnection
=
urlObj
.
openConnection
();
urlConnection
.
setConnectTimeout
(
30
*
1000
);
urlConnection
.
setReadTimeout
(
60
*
1000
);
urlConnection
.
setDoInput
(
true
);
in
=
urlConnection
.
getInputStream
();
}
else
{
// 本机地址
String
localPath
=
DeepseekConfig
.
getProfile
();
String
downloadPath
=
localPath
+
StringUtils
.
substringAfter
(
url
,
Constants
.
RESOURCE_PREFIX
);
in
=
new
FileInputStream
(
downloadPath
);
}
return
IOUtils
.
toByteArray
(
in
);
}
catch
(
Exception
e
)
{
log
.
error
(
"获取文件路径异常 {}"
,
e
);
return
null
;
}
finally
{
IOUtils
.
closeQuietly
(
in
);
}
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/file/MimeTypeUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.file
;
/**
* 媒体类型工具类
*
* @author admin
*/
public
class
MimeTypeUtils
{
public
static
final
String
IMAGE_PNG
=
"image/png"
;
public
static
final
String
IMAGE_JPG
=
"image/jpg"
;
public
static
final
String
IMAGE_JPEG
=
"image/jpeg"
;
public
static
final
String
IMAGE_BMP
=
"image/bmp"
;
public
static
final
String
IMAGE_GIF
=
"image/gif"
;
public
static
final
String
[]
IMAGE_EXTENSION
=
{
"bmp"
,
"gif"
,
"jpg"
,
"jpeg"
,
"png"
};
public
static
final
String
[]
FLASH_EXTENSION
=
{
"swf"
,
"flv"
};
public
static
final
String
[]
MEDIA_EXTENSION
=
{
"swf"
,
"flv"
,
"mp3"
,
"wav"
,
"wma"
,
"wmv"
,
"mid"
,
"avi"
,
"mpg"
,
"asf"
,
"rm"
,
"rmvb"
};
public
static
final
String
[]
VIDEO_EXTENSION
=
{
"mp4"
,
"avi"
,
"rmvb"
};
public
static
final
String
[]
DEFAULT_ALLOWED_EXTENSION
=
{
// 图片
"bmp"
,
"gif"
,
"jpg"
,
"jpeg"
,
"png"
,
// word excel powerpoint
"doc"
,
"docx"
,
"xls"
,
"xlsx"
,
"ppt"
,
"pptx"
,
"html"
,
"htm"
,
"txt"
,
// 压缩文件
"rar"
,
"zip"
,
"gz"
,
"bz2"
,
// 视频格式
"mp4"
,
"avi"
,
"rmvb"
,
// pdf
"pdf"
};
public
static
String
getExtension
(
String
prefix
)
{
switch
(
prefix
)
{
case
IMAGE_PNG:
return
"png"
;
case
IMAGE_JPG:
return
"jpg"
;
case
IMAGE_JPEG:
return
"jpeg"
;
case
IMAGE_BMP:
return
"bmp"
;
case
IMAGE_GIF:
return
"gif"
;
default
:
return
""
;
}
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/html/EscapeUtil.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.html
;
import
com.ewaytek.deepseek.common.utils.StringUtils
;
/**
* 转义和反转义工具类
*
* @author admin
*/
public
class
EscapeUtil
{
public
static
final
String
RE_HTML_MARK
=
"(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)"
;
private
static
final
char
[][]
TEXT
=
new
char
[
64
][];
static
{
for
(
int
i
=
0
;
i
<
64
;
i
++)
{
TEXT
[
i
]
=
new
char
[]{(
char
)
i
};
}
// special HTML characters
TEXT
[
'\''
]
=
"'"
.
toCharArray
();
// 单引号
TEXT
[
'"'
]
=
"""
.
toCharArray
();
// 双引号
TEXT
[
'&'
]
=
"&"
.
toCharArray
();
// &符
TEXT
[
'<'
]
=
"<"
.
toCharArray
();
// 小于号
TEXT
[
'>'
]
=
">"
.
toCharArray
();
// 大于号
}
/**
* 转义文本中的HTML字符为安全的字符
*
* @param text 被转义的文本
* @return 转义后的文本
*/
public
static
String
escape
(
String
text
)
{
return
encode
(
text
);
}
/**
* 还原被转义的HTML特殊字符
*
* @param content 包含转义符的HTML内容
* @return 转换后的字符串
*/
public
static
String
unescape
(
String
content
)
{
return
decode
(
content
);
}
/**
* 清除所有HTML标签,但是不删除标签内的内容
*
* @param content 文本
* @return 清除标签后的文本
*/
public
static
String
clean
(
String
content
)
{
return
new
HTMLFilter
().
filter
(
content
);
}
/**
* Escape编码
*
* @param text 被编码的文本
* @return 编码后的字符
*/
private
static
String
encode
(
String
text
)
{
if
(
StringUtils
.
isEmpty
(
text
))
{
return
StringUtils
.
EMPTY
;
}
final
StringBuilder
tmp
=
new
StringBuilder
(
text
.
length
()
*
6
);
char
c
;
for
(
int
i
=
0
;
i
<
text
.
length
();
i
++)
{
c
=
text
.
charAt
(
i
);
if
(
c
<
256
)
{
tmp
.
append
(
"%"
);
if
(
c
<
16
)
{
tmp
.
append
(
"0"
);
}
tmp
.
append
(
Integer
.
toString
(
c
,
16
));
}
else
{
tmp
.
append
(
"%u"
);
if
(
c
<=
0xfff
)
{
// issue#I49JU8@Gitee
tmp
.
append
(
"0"
);
}
tmp
.
append
(
Integer
.
toString
(
c
,
16
));
}
}
return
tmp
.
toString
();
}
/**
* Escape解码
*
* @param content 被转义的内容
* @return 解码后的字符串
*/
public
static
String
decode
(
String
content
)
{
if
(
StringUtils
.
isEmpty
(
content
))
{
return
content
;
}
StringBuilder
tmp
=
new
StringBuilder
(
content
.
length
());
int
lastPos
=
0
,
pos
=
0
;
char
ch
;
while
(
lastPos
<
content
.
length
())
{
pos
=
content
.
indexOf
(
"%"
,
lastPos
);
if
(
pos
==
lastPos
)
{
if
(
content
.
charAt
(
pos
+
1
)
==
'u'
)
{
ch
=
(
char
)
Integer
.
parseInt
(
content
.
substring
(
pos
+
2
,
pos
+
6
),
16
);
tmp
.
append
(
ch
);
lastPos
=
pos
+
6
;
}
else
{
ch
=
(
char
)
Integer
.
parseInt
(
content
.
substring
(
pos
+
1
,
pos
+
3
),
16
);
tmp
.
append
(
ch
);
lastPos
=
pos
+
3
;
}
}
else
{
if
(
pos
==
-
1
)
{
tmp
.
append
(
content
.
substring
(
lastPos
));
lastPos
=
content
.
length
();
}
else
{
tmp
.
append
(
content
,
lastPos
,
pos
);
lastPos
=
pos
;
}
}
}
return
tmp
.
toString
();
}
public
static
void
main
(
String
[]
args
)
{
String
html
=
"<script>alert(1);</script>"
;
String
escape
=
EscapeUtil
.
escape
(
html
);
// String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>";
// String html = "<123";
// String html = "123>";
System
.
out
.
println
(
"clean: "
+
EscapeUtil
.
clean
(
html
));
System
.
out
.
println
(
"escape: "
+
escape
);
System
.
out
.
println
(
"unescape: "
+
EscapeUtil
.
unescape
(
escape
));
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/html/HTMLFilter.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.html
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentMap
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* HTML过滤器,用于去除XSS漏洞隐患。
*
* @author admin
*/
public
final
class
HTMLFilter
{
/**
* regex flag union representing /si modifiers in php
**/
private
static
final
int
REGEX_FLAGS_SI
=
Pattern
.
CASE_INSENSITIVE
|
Pattern
.
DOTALL
;
private
static
final
Pattern
P_COMMENTS
=
Pattern
.
compile
(
"<!--(.*?)-->"
,
Pattern
.
DOTALL
);
private
static
final
Pattern
P_COMMENT
=
Pattern
.
compile
(
"^!--(.*)--$"
,
REGEX_FLAGS_SI
);
private
static
final
Pattern
P_TAGS
=
Pattern
.
compile
(
"<(.*?)>"
,
Pattern
.
DOTALL
);
private
static
final
Pattern
P_END_TAG
=
Pattern
.
compile
(
"^/([a-z0-9]+)"
,
REGEX_FLAGS_SI
);
private
static
final
Pattern
P_START_TAG
=
Pattern
.
compile
(
"^([a-z0-9]+)(.*?)(/?)$"
,
REGEX_FLAGS_SI
);
private
static
final
Pattern
P_QUOTED_ATTRIBUTES
=
Pattern
.
compile
(
"([a-z0-9]+)=([\"'])(.*?)\\2"
,
REGEX_FLAGS_SI
);
private
static
final
Pattern
P_UNQUOTED_ATTRIBUTES
=
Pattern
.
compile
(
"([a-z0-9]+)(=)([^\"\\s']+)"
,
REGEX_FLAGS_SI
);
private
static
final
Pattern
P_PROTOCOL
=
Pattern
.
compile
(
"^([^:]+):"
,
REGEX_FLAGS_SI
);
private
static
final
Pattern
P_ENTITY
=
Pattern
.
compile
(
"&#(\\d+);?"
);
private
static
final
Pattern
P_ENTITY_UNICODE
=
Pattern
.
compile
(
"&#x([0-9a-f]+);?"
);
private
static
final
Pattern
P_ENCODE
=
Pattern
.
compile
(
"%([0-9a-f]{2});?"
);
private
static
final
Pattern
P_VALID_ENTITIES
=
Pattern
.
compile
(
"&([^&;]*)(?=(;|&|$))"
);
private
static
final
Pattern
P_VALID_QUOTES
=
Pattern
.
compile
(
"(>|^)([^<]+?)(<|$)"
,
Pattern
.
DOTALL
);
private
static
final
Pattern
P_END_ARROW
=
Pattern
.
compile
(
"^>"
);
private
static
final
Pattern
P_BODY_TO_END
=
Pattern
.
compile
(
"<([^>]*?)(?=<|$)"
);
private
static
final
Pattern
P_XML_CONTENT
=
Pattern
.
compile
(
"(^|>)([^<]*?)(?=>)"
);
private
static
final
Pattern
P_STRAY_LEFT_ARROW
=
Pattern
.
compile
(
"<([^>]*?)(?=<|$)"
);
private
static
final
Pattern
P_STRAY_RIGHT_ARROW
=
Pattern
.
compile
(
"(^|>)([^<]*?)(?=>)"
);
private
static
final
Pattern
P_AMP
=
Pattern
.
compile
(
"&"
);
private
static
final
Pattern
P_QUOTE
=
Pattern
.
compile
(
"\""
);
private
static
final
Pattern
P_LEFT_ARROW
=
Pattern
.
compile
(
"<"
);
private
static
final
Pattern
P_RIGHT_ARROW
=
Pattern
.
compile
(
">"
);
private
static
final
Pattern
P_BOTH_ARROWS
=
Pattern
.
compile
(
"<>"
);
// @xxx could grow large... maybe use sesat's ReferenceMap
private
static
final
ConcurrentMap
<
String
,
Pattern
>
P_REMOVE_PAIR_BLANKS
=
new
ConcurrentHashMap
<>();
private
static
final
ConcurrentMap
<
String
,
Pattern
>
P_REMOVE_SELF_BLANKS
=
new
ConcurrentHashMap
<>();
/**
* set of allowed html elements, along with allowed attributes for each element
**/
private
final
Map
<
String
,
List
<
String
>>
vAllowed
;
/**
* counts of open tags for each (allowable) html element
**/
private
final
Map
<
String
,
Integer
>
vTagCounts
=
new
HashMap
<>();
/**
* html elements which must always be self-closing (e.g. "<img />")
**/
private
final
String
[]
vSelfClosingTags
;
/**
* html elements which must always have separate opening and closing tags (e.g. "<b></b>")
**/
private
final
String
[]
vNeedClosingTags
;
/**
* set of disallowed html elements
**/
private
final
String
[]
vDisallowed
;
/**
* attributes which should be checked for valid protocols
**/
private
final
String
[]
vProtocolAtts
;
/**
* allowed protocols
**/
private
final
String
[]
vAllowedProtocols
;
/**
* tags which should be removed if they contain no content (e.g. "<b></b>" or "<b />")
**/
private
final
String
[]
vRemoveBlanks
;
/**
* entities allowed within html markup
**/
private
final
String
[]
vAllowedEntities
;
/**
* flag determining whether comments are allowed in input String.
*/
private
final
boolean
stripComment
;
private
final
boolean
encodeQuotes
;
/**
* flag determining whether to try to make tags when presented with "unbalanced" angle brackets (e.g. "<b text </b>"
* becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped.
*/
private
final
boolean
alwaysMakeTags
;
/**
* Default constructor.
*/
public
HTMLFilter
()
{
vAllowed
=
new
HashMap
<>();
final
ArrayList
<
String
>
a_atts
=
new
ArrayList
<>();
a_atts
.
add
(
"href"
);
a_atts
.
add
(
"target"
);
vAllowed
.
put
(
"a"
,
a_atts
);
final
ArrayList
<
String
>
img_atts
=
new
ArrayList
<>();
img_atts
.
add
(
"src"
);
img_atts
.
add
(
"width"
);
img_atts
.
add
(
"height"
);
img_atts
.
add
(
"alt"
);
vAllowed
.
put
(
"img"
,
img_atts
);
final
ArrayList
<
String
>
no_atts
=
new
ArrayList
<>();
vAllowed
.
put
(
"b"
,
no_atts
);
vAllowed
.
put
(
"strong"
,
no_atts
);
vAllowed
.
put
(
"i"
,
no_atts
);
vAllowed
.
put
(
"em"
,
no_atts
);
vSelfClosingTags
=
new
String
[]{
"img"
};
vNeedClosingTags
=
new
String
[]{
"a"
,
"b"
,
"strong"
,
"i"
,
"em"
};
vDisallowed
=
new
String
[]{};
vAllowedProtocols
=
new
String
[]{
"http"
,
"mailto"
,
"https"
};
// no ftp.
vProtocolAtts
=
new
String
[]{
"src"
,
"href"
};
vRemoveBlanks
=
new
String
[]{
"a"
,
"b"
,
"strong"
,
"i"
,
"em"
};
vAllowedEntities
=
new
String
[]{
"amp"
,
"gt"
,
"lt"
,
"quot"
};
stripComment
=
true
;
encodeQuotes
=
true
;
alwaysMakeTags
=
false
;
}
/**
* Map-parameter configurable constructor.
*
* @param conf map containing configuration. keys match field names.
*/
@SuppressWarnings
(
"unchecked"
)
public
HTMLFilter
(
final
Map
<
String
,
Object
>
conf
)
{
assert
conf
.
containsKey
(
"vAllowed"
)
:
"configuration requires vAllowed"
;
assert
conf
.
containsKey
(
"vSelfClosingTags"
)
:
"configuration requires vSelfClosingTags"
;
assert
conf
.
containsKey
(
"vNeedClosingTags"
)
:
"configuration requires vNeedClosingTags"
;
assert
conf
.
containsKey
(
"vDisallowed"
)
:
"configuration requires vDisallowed"
;
assert
conf
.
containsKey
(
"vAllowedProtocols"
)
:
"configuration requires vAllowedProtocols"
;
assert
conf
.
containsKey
(
"vProtocolAtts"
)
:
"configuration requires vProtocolAtts"
;
assert
conf
.
containsKey
(
"vRemoveBlanks"
)
:
"configuration requires vRemoveBlanks"
;
assert
conf
.
containsKey
(
"vAllowedEntities"
)
:
"configuration requires vAllowedEntities"
;
vAllowed
=
Collections
.
unmodifiableMap
((
HashMap
<
String
,
List
<
String
>>)
conf
.
get
(
"vAllowed"
));
vSelfClosingTags
=
(
String
[])
conf
.
get
(
"vSelfClosingTags"
);
vNeedClosingTags
=
(
String
[])
conf
.
get
(
"vNeedClosingTags"
);
vDisallowed
=
(
String
[])
conf
.
get
(
"vDisallowed"
);
vAllowedProtocols
=
(
String
[])
conf
.
get
(
"vAllowedProtocols"
);
vProtocolAtts
=
(
String
[])
conf
.
get
(
"vProtocolAtts"
);
vRemoveBlanks
=
(
String
[])
conf
.
get
(
"vRemoveBlanks"
);
vAllowedEntities
=
(
String
[])
conf
.
get
(
"vAllowedEntities"
);
stripComment
=
conf
.
containsKey
(
"stripComment"
)
?
(
Boolean
)
conf
.
get
(
"stripComment"
)
:
true
;
encodeQuotes
=
conf
.
containsKey
(
"encodeQuotes"
)
?
(
Boolean
)
conf
.
get
(
"encodeQuotes"
)
:
true
;
alwaysMakeTags
=
conf
.
containsKey
(
"alwaysMakeTags"
)
?
(
Boolean
)
conf
.
get
(
"alwaysMakeTags"
)
:
true
;
}
// ---------------------------------------------------------------
// my versions of some PHP library functions
public
static
String
chr
(
final
int
decimal
)
{
return
String
.
valueOf
((
char
)
decimal
);
}
public
static
String
htmlSpecialChars
(
final
String
s
)
{
String
result
=
s
;
result
=
regexReplace
(
P_AMP
,
"&"
,
result
);
result
=
regexReplace
(
P_QUOTE
,
"""
,
result
);
result
=
regexReplace
(
P_LEFT_ARROW
,
"<"
,
result
);
result
=
regexReplace
(
P_RIGHT_ARROW
,
">"
,
result
);
return
result
;
}
private
static
String
regexReplace
(
final
Pattern
regex_pattern
,
final
String
replacement
,
final
String
s
)
{
Matcher
m
=
regex_pattern
.
matcher
(
s
);
return
m
.
replaceAll
(
replacement
);
}
// ---------------------------------------------------------------
private
static
boolean
inArray
(
final
String
s
,
final
String
[]
array
)
{
for
(
String
item
:
array
)
{
if
(
item
!=
null
&&
item
.
equals
(
s
))
{
return
true
;
}
}
return
false
;
}
private
void
reset
()
{
vTagCounts
.
clear
();
}
/**
* given a user submitted input String, filter out any invalid or restricted html.
*
* @param input text (i.e. submitted by a user) than may contain html
* @return "clean" version of input, with only valid, whitelisted html elements allowed
*/
public
String
filter
(
final
String
input
)
{
reset
();
String
s
=
input
;
s
=
escapeComments
(
s
);
s
=
balanceHTML
(
s
);
s
=
checkTags
(
s
);
s
=
processRemoveBlanks
(
s
);
// s = validateEntities(s);
return
s
;
}
public
boolean
isAlwaysMakeTags
()
{
return
alwaysMakeTags
;
}
public
boolean
isStripComments
()
{
return
stripComment
;
}
private
String
escapeComments
(
final
String
s
)
{
final
Matcher
m
=
P_COMMENTS
.
matcher
(
s
);
final
StringBuffer
buf
=
new
StringBuffer
();
if
(
m
.
find
())
{
final
String
match
=
m
.
group
(
1
);
// (.*?)
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
"<!--"
+
htmlSpecialChars
(
match
)
+
"-->"
));
}
m
.
appendTail
(
buf
);
return
buf
.
toString
();
}
private
String
balanceHTML
(
String
s
)
{
if
(
alwaysMakeTags
)
{
//
// try and form html
//
s
=
regexReplace
(
P_END_ARROW
,
""
,
s
);
// 不追加结束标签
s
=
regexReplace
(
P_BODY_TO_END
,
"<$1>"
,
s
);
s
=
regexReplace
(
P_XML_CONTENT
,
"$1<$2"
,
s
);
}
else
{
//
// escape stray brackets
//
s
=
regexReplace
(
P_STRAY_LEFT_ARROW
,
"<$1"
,
s
);
s
=
regexReplace
(
P_STRAY_RIGHT_ARROW
,
"$1$2><"
,
s
);
//
// the last regexp causes '<>' entities to appear
// (we need to do a lookahead assertion so that the last bracket can
// be used in the next pass of the regexp)
//
s
=
regexReplace
(
P_BOTH_ARROWS
,
""
,
s
);
}
return
s
;
}
private
String
checkTags
(
String
s
)
{
Matcher
m
=
P_TAGS
.
matcher
(
s
);
final
StringBuffer
buf
=
new
StringBuffer
();
while
(
m
.
find
())
{
String
replaceStr
=
m
.
group
(
1
);
replaceStr
=
processTag
(
replaceStr
);
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
replaceStr
));
}
m
.
appendTail
(
buf
);
// these get tallied in processTag
// (remember to reset before subsequent calls to filter method)
final
StringBuilder
sBuilder
=
new
StringBuilder
(
buf
.
toString
());
for
(
String
key
:
vTagCounts
.
keySet
())
{
for
(
int
ii
=
0
;
ii
<
vTagCounts
.
get
(
key
);
ii
++)
{
sBuilder
.
append
(
"</"
).
append
(
key
).
append
(
">"
);
}
}
s
=
sBuilder
.
toString
();
return
s
;
}
private
String
processRemoveBlanks
(
final
String
s
)
{
String
result
=
s
;
for
(
String
tag
:
vRemoveBlanks
)
{
if
(!
P_REMOVE_PAIR_BLANKS
.
containsKey
(
tag
))
{
P_REMOVE_PAIR_BLANKS
.
putIfAbsent
(
tag
,
Pattern
.
compile
(
"<"
+
tag
+
"(\\s[^>]*)?></"
+
tag
+
">"
));
}
result
=
regexReplace
(
P_REMOVE_PAIR_BLANKS
.
get
(
tag
),
""
,
result
);
if
(!
P_REMOVE_SELF_BLANKS
.
containsKey
(
tag
))
{
P_REMOVE_SELF_BLANKS
.
putIfAbsent
(
tag
,
Pattern
.
compile
(
"<"
+
tag
+
"(\\s[^>]*)?/>"
));
}
result
=
regexReplace
(
P_REMOVE_SELF_BLANKS
.
get
(
tag
),
""
,
result
);
}
return
result
;
}
private
String
processTag
(
final
String
s
)
{
// ending tags
Matcher
m
=
P_END_TAG
.
matcher
(
s
);
if
(
m
.
find
())
{
final
String
name
=
m
.
group
(
1
).
toLowerCase
();
if
(
allowed
(
name
))
{
if
(!
inArray
(
name
,
vSelfClosingTags
))
{
if
(
vTagCounts
.
containsKey
(
name
))
{
vTagCounts
.
put
(
name
,
vTagCounts
.
get
(
name
)
-
1
);
return
"</"
+
name
+
">"
;
}
}
}
}
// starting tags
m
=
P_START_TAG
.
matcher
(
s
);
if
(
m
.
find
())
{
final
String
name
=
m
.
group
(
1
).
toLowerCase
();
final
String
body
=
m
.
group
(
2
);
String
ending
=
m
.
group
(
3
);
// debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
if
(
allowed
(
name
))
{
final
StringBuilder
params
=
new
StringBuilder
();
final
Matcher
m2
=
P_QUOTED_ATTRIBUTES
.
matcher
(
body
);
final
Matcher
m3
=
P_UNQUOTED_ATTRIBUTES
.
matcher
(
body
);
final
List
<
String
>
paramNames
=
new
ArrayList
<>();
final
List
<
String
>
paramValues
=
new
ArrayList
<>();
while
(
m2
.
find
())
{
paramNames
.
add
(
m2
.
group
(
1
));
// ([a-z0-9]+)
paramValues
.
add
(
m2
.
group
(
3
));
// (.*?)
}
while
(
m3
.
find
())
{
paramNames
.
add
(
m3
.
group
(
1
));
// ([a-z0-9]+)
paramValues
.
add
(
m3
.
group
(
3
));
// ([^\"\\s']+)
}
String
paramName
,
paramValue
;
for
(
int
ii
=
0
;
ii
<
paramNames
.
size
();
ii
++)
{
paramName
=
paramNames
.
get
(
ii
).
toLowerCase
();
paramValue
=
paramValues
.
get
(
ii
);
// debug( "paramName='" + paramName + "'" );
// debug( "paramValue='" + paramValue + "'" );
// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
if
(
allowedAttribute
(
name
,
paramName
))
{
if
(
inArray
(
paramName
,
vProtocolAtts
))
{
paramValue
=
processParamProtocol
(
paramValue
);
}
params
.
append
(
' '
).
append
(
paramName
).
append
(
"=\\\""
).
append
(
paramValue
).
append
(
"\\\""
);
}
}
if
(
inArray
(
name
,
vSelfClosingTags
))
{
ending
=
" /"
;
}
if
(
inArray
(
name
,
vNeedClosingTags
))
{
ending
=
""
;
}
if
(
ending
==
null
||
ending
.
length
()
<
1
)
{
if
(
vTagCounts
.
containsKey
(
name
))
{
vTagCounts
.
put
(
name
,
vTagCounts
.
get
(
name
)
+
1
);
}
else
{
vTagCounts
.
put
(
name
,
1
);
}
}
else
{
ending
=
" /"
;
}
return
"<"
+
name
+
params
+
ending
+
">"
;
}
else
{
return
""
;
}
}
// comments
m
=
P_COMMENT
.
matcher
(
s
);
if
(!
stripComment
&&
m
.
find
())
{
return
"<"
+
m
.
group
()
+
">"
;
}
return
""
;
}
private
String
processParamProtocol
(
String
s
)
{
s
=
decodeEntities
(
s
);
final
Matcher
m
=
P_PROTOCOL
.
matcher
(
s
);
if
(
m
.
find
())
{
final
String
protocol
=
m
.
group
(
1
);
if
(!
inArray
(
protocol
,
vAllowedProtocols
))
{
// bad protocol, turn into local anchor link instead
s
=
"#"
+
s
.
substring
(
protocol
.
length
()
+
1
);
if
(
s
.
startsWith
(
"#//"
))
{
s
=
"#"
+
s
.
substring
(
3
);
}
}
}
return
s
;
}
private
String
decodeEntities
(
String
s
)
{
StringBuffer
buf
=
new
StringBuffer
();
Matcher
m
=
P_ENTITY
.
matcher
(
s
);
while
(
m
.
find
())
{
final
String
match
=
m
.
group
(
1
);
final
int
decimal
=
Integer
.
decode
(
match
).
intValue
();
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
chr
(
decimal
)));
}
m
.
appendTail
(
buf
);
s
=
buf
.
toString
();
buf
=
new
StringBuffer
();
m
=
P_ENTITY_UNICODE
.
matcher
(
s
);
while
(
m
.
find
())
{
final
String
match
=
m
.
group
(
1
);
final
int
decimal
=
Integer
.
valueOf
(
match
,
16
).
intValue
();
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
chr
(
decimal
)));
}
m
.
appendTail
(
buf
);
s
=
buf
.
toString
();
buf
=
new
StringBuffer
();
m
=
P_ENCODE
.
matcher
(
s
);
while
(
m
.
find
())
{
final
String
match
=
m
.
group
(
1
);
final
int
decimal
=
Integer
.
valueOf
(
match
,
16
).
intValue
();
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
chr
(
decimal
)));
}
m
.
appendTail
(
buf
);
s
=
buf
.
toString
();
s
=
validateEntities
(
s
);
return
s
;
}
private
String
validateEntities
(
final
String
s
)
{
StringBuffer
buf
=
new
StringBuffer
();
// validate entities throughout the string
Matcher
m
=
P_VALID_ENTITIES
.
matcher
(
s
);
while
(
m
.
find
())
{
final
String
one
=
m
.
group
(
1
);
// ([^&;]*)
final
String
two
=
m
.
group
(
2
);
// (?=(;|&|$))
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
checkEntity
(
one
,
two
)));
}
m
.
appendTail
(
buf
);
return
encodeQuotes
(
buf
.
toString
());
}
private
String
encodeQuotes
(
final
String
s
)
{
if
(
encodeQuotes
)
{
StringBuffer
buf
=
new
StringBuffer
();
Matcher
m
=
P_VALID_QUOTES
.
matcher
(
s
);
while
(
m
.
find
())
{
final
String
one
=
m
.
group
(
1
);
// (>|^)
final
String
two
=
m
.
group
(
2
);
// ([^<]+?)
final
String
three
=
m
.
group
(
3
);
// (<|$)
// 不替换双引号为",防止json格式无效 regexReplace(P_QUOTE, """, two)
m
.
appendReplacement
(
buf
,
Matcher
.
quoteReplacement
(
one
+
two
+
three
));
}
m
.
appendTail
(
buf
);
return
buf
.
toString
();
}
else
{
return
s
;
}
}
private
String
checkEntity
(
final
String
preamble
,
final
String
term
)
{
return
";"
.
equals
(
term
)
&&
isValidEntity
(
preamble
)
?
'&'
+
preamble
:
"&"
+
preamble
;
}
private
boolean
isValidEntity
(
final
String
entity
)
{
return
inArray
(
entity
,
vAllowedEntities
);
}
private
boolean
allowed
(
final
String
name
)
{
return
(
vAllowed
.
isEmpty
()
||
vAllowed
.
containsKey
(
name
))
&&
!
inArray
(
name
,
vDisallowed
);
}
private
boolean
allowedAttribute
(
final
String
name
,
final
String
paramName
)
{
return
allowed
(
name
)
&&
(
vAllowed
.
isEmpty
()
||
vAllowed
.
get
(
name
).
contains
(
paramName
));
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/http/HttpHelper.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.http
;
import
org.apache.commons.lang3.exception.ExceptionUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.servlet.ServletRequest
;
import
java.io.BufferedReader
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.InputStreamReader
;
import
java.nio.charset.StandardCharsets
;
/**
* 通用http工具封装
*
* @author admin
*/
public
class
HttpHelper
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
HttpHelper
.
class
);
public
static
String
getBodyString
(
ServletRequest
request
)
{
StringBuilder
sb
=
new
StringBuilder
();
BufferedReader
reader
=
null
;
try
(
InputStream
inputStream
=
request
.
getInputStream
())
{
reader
=
new
BufferedReader
(
new
InputStreamReader
(
inputStream
,
StandardCharsets
.
UTF_8
));
String
line
=
""
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
sb
.
append
(
line
);
}
}
catch
(
IOException
e
)
{
LOGGER
.
warn
(
"getBodyString出现问题!"
);
}
finally
{
if
(
reader
!=
null
)
{
try
{
reader
.
close
();
}
catch
(
IOException
e
)
{
LOGGER
.
error
(
ExceptionUtils
.
getMessage
(
e
));
}
}
}
return
sb
.
toString
();
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/http/HttpUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.http
;
import
com.ewaytek.deepseek.common.constant.Constants
;
import
com.ewaytek.deepseek.common.utils.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.net.ssl.*
;
import
java.io.*
;
import
java.net.ConnectException
;
import
java.net.SocketTimeoutException
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.nio.charset.StandardCharsets
;
import
java.security.cert.X509Certificate
;
/**
* 通用http发送方法
*
* @author admin
*/
public
class
HttpUtils
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
HttpUtils
.
class
);
/**
* 向指定 URL 发送GET方法的请求
*
* @param url 发送请求的 URL
* @return 所代表远程资源的响应结果
*/
public
static
String
sendGet
(
String
url
)
{
return
sendGet
(
url
,
StringUtils
.
EMPTY
);
}
/**
* 向指定 URL 发送GET方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public
static
String
sendGet
(
String
url
,
String
param
)
{
return
sendGet
(
url
,
param
,
Constants
.
UTF8
);
}
/**
* 向指定 URL 发送GET方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @param contentType 编码类型
* @return 所代表远程资源的响应结果
*/
public
static
String
sendGet
(
String
url
,
String
param
,
String
contentType
)
{
StringBuilder
result
=
new
StringBuilder
();
BufferedReader
in
=
null
;
try
{
String
urlNameString
=
StringUtils
.
isNotBlank
(
param
)
?
url
+
"?"
+
param
:
url
;
log
.
info
(
"sendGet - {}"
,
urlNameString
);
URL
realUrl
=
new
URL
(
urlNameString
);
URLConnection
connection
=
realUrl
.
openConnection
();
connection
.
setRequestProperty
(
"accept"
,
"*/*"
);
connection
.
setRequestProperty
(
"connection"
,
"Keep-Alive"
);
connection
.
setRequestProperty
(
"user-agent"
,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
);
connection
.
connect
();
in
=
new
BufferedReader
(
new
InputStreamReader
(
connection
.
getInputStream
(),
contentType
));
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
result
.
append
(
line
);
}
log
.
info
(
"recv - {}"
,
result
);
}
catch
(
ConnectException
e
)
{
log
.
error
(
"调用HttpUtils.sendGet ConnectException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
SocketTimeoutException
e
)
{
log
.
error
(
"调用HttpUtils.sendGet SocketTimeoutException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"调用HttpUtils.sendGet IOException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
Exception
e
)
{
log
.
error
(
"调用HttpsUtil.sendGet Exception, url="
+
url
+
",param="
+
param
,
e
);
}
finally
{
try
{
if
(
in
!=
null
)
{
in
.
close
();
}
}
catch
(
Exception
ex
)
{
log
.
error
(
"调用in.close Exception, url="
+
url
+
",param="
+
param
,
ex
);
}
}
return
result
.
toString
();
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public
static
String
sendPost
(
String
url
,
String
param
)
{
PrintWriter
out
=
null
;
BufferedReader
in
=
null
;
StringBuilder
result
=
new
StringBuilder
();
try
{
log
.
info
(
"sendPost - {}"
,
url
);
URL
realUrl
=
new
URL
(
url
);
URLConnection
conn
=
realUrl
.
openConnection
();
conn
.
setRequestProperty
(
"accept"
,
"*/*"
);
conn
.
setRequestProperty
(
"connection"
,
"Keep-Alive"
);
conn
.
setRequestProperty
(
"user-agent"
,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
);
conn
.
setRequestProperty
(
"Accept-Charset"
,
"utf-8"
);
conn
.
setRequestProperty
(
"contentType"
,
"utf-8"
);
conn
.
setDoOutput
(
true
);
conn
.
setDoInput
(
true
);
out
=
new
PrintWriter
(
conn
.
getOutputStream
());
out
.
print
(
param
);
out
.
flush
();
in
=
new
BufferedReader
(
new
InputStreamReader
(
conn
.
getInputStream
(),
StandardCharsets
.
UTF_8
));
String
line
;
while
((
line
=
in
.
readLine
())
!=
null
)
{
result
.
append
(
line
);
}
log
.
info
(
"recv - {}"
,
result
);
}
catch
(
ConnectException
e
)
{
log
.
error
(
"调用HttpUtils.sendPost ConnectException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
SocketTimeoutException
e
)
{
log
.
error
(
"调用HttpUtils.sendPost SocketTimeoutException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"调用HttpUtils.sendPost IOException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
Exception
e
)
{
log
.
error
(
"调用HttpsUtil.sendPost Exception, url="
+
url
+
",param="
+
param
,
e
);
}
finally
{
try
{
if
(
out
!=
null
)
{
out
.
close
();
}
if
(
in
!=
null
)
{
in
.
close
();
}
}
catch
(
IOException
ex
)
{
log
.
error
(
"调用in.close Exception, url="
+
url
+
",param="
+
param
,
ex
);
}
}
return
result
.
toString
();
}
public
static
String
sendSSLPost
(
String
url
,
String
param
)
{
StringBuilder
result
=
new
StringBuilder
();
String
urlNameString
=
url
+
"?"
+
param
;
try
{
log
.
info
(
"sendSSLPost - {}"
,
urlNameString
);
SSLContext
sc
=
SSLContext
.
getInstance
(
"SSL"
);
sc
.
init
(
null
,
new
TrustManager
[]{
new
TrustAnyTrustManager
()},
new
java
.
security
.
SecureRandom
());
URL
console
=
new
URL
(
urlNameString
);
HttpsURLConnection
conn
=
(
HttpsURLConnection
)
console
.
openConnection
();
conn
.
setRequestProperty
(
"accept"
,
"*/*"
);
conn
.
setRequestProperty
(
"connection"
,
"Keep-Alive"
);
conn
.
setRequestProperty
(
"user-agent"
,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
);
conn
.
setRequestProperty
(
"Accept-Charset"
,
"utf-8"
);
conn
.
setRequestProperty
(
"contentType"
,
"utf-8"
);
conn
.
setDoOutput
(
true
);
conn
.
setDoInput
(
true
);
conn
.
setSSLSocketFactory
(
sc
.
getSocketFactory
());
conn
.
setHostnameVerifier
(
new
TrustAnyHostnameVerifier
());
conn
.
connect
();
InputStream
is
=
conn
.
getInputStream
();
BufferedReader
br
=
new
BufferedReader
(
new
InputStreamReader
(
is
));
String
ret
=
""
;
while
((
ret
=
br
.
readLine
())
!=
null
)
{
if
(
ret
!=
null
&&
!
""
.
equals
(
ret
.
trim
()))
{
result
.
append
(
new
String
(
ret
.
getBytes
(
StandardCharsets
.
ISO_8859_1
),
StandardCharsets
.
UTF_8
));
}
}
log
.
info
(
"recv - {}"
,
result
);
conn
.
disconnect
();
br
.
close
();
}
catch
(
ConnectException
e
)
{
log
.
error
(
"调用HttpUtils.sendSSLPost ConnectException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
SocketTimeoutException
e
)
{
log
.
error
(
"调用HttpUtils.sendSSLPost SocketTimeoutException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"调用HttpUtils.sendSSLPost IOException, url="
+
url
+
",param="
+
param
,
e
);
}
catch
(
Exception
e
)
{
log
.
error
(
"调用HttpsUtil.sendSSLPost Exception, url="
+
url
+
",param="
+
param
,
e
);
}
return
result
.
toString
();
}
private
static
class
TrustAnyTrustManager
implements
X509TrustManager
{
@Override
public
void
checkClientTrusted
(
X509Certificate
[]
chain
,
String
authType
)
{
}
@Override
public
void
checkServerTrusted
(
X509Certificate
[]
chain
,
String
authType
)
{
}
@Override
public
X509Certificate
[]
getAcceptedIssuers
()
{
return
new
X509Certificate
[]{};
}
}
private
static
class
TrustAnyHostnameVerifier
implements
HostnameVerifier
{
@Override
public
boolean
verify
(
String
hostname
,
SSLSession
session
)
{
return
true
;
}
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/ip/IpUtils.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.ip
;
import
com.ewaytek.deepseek.common.utils.ServletUtils
;
import
com.ewaytek.deepseek.common.utils.StringUtils
;
import
javax.servlet.http.HttpServletRequest
;
import
java.net.InetAddress
;
import
java.net.UnknownHostException
;
/**
* 获取IP方法
*
* @author admin
*/
public
class
IpUtils
{
public
final
static
String
REGX_0_255
=
"(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"
;
// 匹配 ip
public
final
static
String
REGX_IP
=
"(("
+
REGX_0_255
+
"\\.){3}"
+
REGX_0_255
+
")"
;
// 匹配网段
public
final
static
String
REGX_IP_SEG
=
"("
+
REGX_IP
+
"\\-"
+
REGX_IP
+
")"
;
public
final
static
String
REGX_IP_WILDCARD
=
"(((\\*\\.){3}\\*)|("
+
REGX_0_255
+
"(\\.\\*){3})|("
+
REGX_0_255
+
"\\."
+
REGX_0_255
+
")(\\.\\*){2}"
+
"|(("
+
REGX_0_255
+
"\\.){3}\\*))"
;
/**
* 获取客户端IP
*
* @return IP地址
*/
public
static
String
getIpAddr
()
{
return
getIpAddr
(
ServletUtils
.
getRequest
());
}
/**
* 获取客户端IP
*
* @param request 请求对象
* @return IP地址
*/
public
static
String
getIpAddr
(
HttpServletRequest
request
)
{
if
(
request
==
null
)
{
return
"unknown"
;
}
String
ip
=
request
.
getHeader
(
"x-forwarded-for"
);
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"X-Forwarded-For"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"X-Real-IP"
);
}
if
(
ip
==
null
||
ip
.
length
()
==
0
||
"unknown"
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getRemoteAddr
();
}
return
"0:0:0:0:0:0:0:1"
.
equals
(
ip
)
?
"127.0.0.1"
:
getMultistageReverseProxyIp
(
ip
);
}
/**
* 检查是否为内部IP地址
*
* @param ip IP地址
* @return 结果
*/
public
static
boolean
internalIp
(
String
ip
)
{
byte
[]
addr
=
textToNumericFormatV4
(
ip
);
return
internalIp
(
addr
)
||
"127.0.0.1"
.
equals
(
ip
);
}
/**
* 检查是否为内部IP地址
*
* @param addr byte地址
* @return 结果
*/
private
static
boolean
internalIp
(
byte
[]
addr
)
{
if
(
StringUtils
.
isNull
(
addr
)
||
addr
.
length
<
2
)
{
return
true
;
}
final
byte
b0
=
addr
[
0
];
final
byte
b1
=
addr
[
1
];
// 10.x.x.x/8
final
byte
SECTION_1
=
0x0A
;
// 172.16.x.x/12
final
byte
SECTION_2
=
(
byte
)
0xAC
;
final
byte
SECTION_3
=
(
byte
)
0x10
;
final
byte
SECTION_4
=
(
byte
)
0x1F
;
// 192.168.x.x/16
final
byte
SECTION_5
=
(
byte
)
0xC0
;
final
byte
SECTION_6
=
(
byte
)
0xA8
;
switch
(
b0
)
{
case
SECTION_1:
return
true
;
case
SECTION_2:
if
(
b1
>=
SECTION_3
&&
b1
<=
SECTION_4
)
{
return
true
;
}
case
SECTION_5:
switch
(
b1
)
{
case
SECTION_6:
return
true
;
}
default
:
return
false
;
}
}
/**
* 将IPv4地址转换成字节
*
* @param text IPv4地址
* @return byte 字节
*/
public
static
byte
[]
textToNumericFormatV4
(
String
text
)
{
if
(
text
.
length
()
==
0
)
{
return
null
;
}
byte
[]
bytes
=
new
byte
[
4
];
String
[]
elements
=
text
.
split
(
"\\."
,
-
1
);
try
{
long
l
;
int
i
;
switch
(
elements
.
length
)
{
case
1
:
l
=
Long
.
parseLong
(
elements
[
0
]);
if
((
l
<
0L
)
||
(
l
>
4294967295L
))
{
return
null
;
}
bytes
[
0
]
=
(
byte
)
(
int
)
(
l
>>
24
&
0xFF
);
bytes
[
1
]
=
(
byte
)
(
int
)
((
l
&
0xFFFFFF
)
>>
16
&
0xFF
);
bytes
[
2
]
=
(
byte
)
(
int
)
((
l
&
0xFFFF
)
>>
8
&
0xFF
);
bytes
[
3
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
break
;
case
2
:
l
=
Integer
.
parseInt
(
elements
[
0
]);
if
((
l
<
0L
)
||
(
l
>
255L
))
{
return
null
;
}
bytes
[
0
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
l
=
Integer
.
parseInt
(
elements
[
1
]);
if
((
l
<
0L
)
||
(
l
>
16777215L
))
{
return
null
;
}
bytes
[
1
]
=
(
byte
)
(
int
)
(
l
>>
16
&
0xFF
);
bytes
[
2
]
=
(
byte
)
(
int
)
((
l
&
0xFFFF
)
>>
8
&
0xFF
);
bytes
[
3
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
break
;
case
3
:
for
(
i
=
0
;
i
<
2
;
++
i
)
{
l
=
Integer
.
parseInt
(
elements
[
i
]);
if
((
l
<
0L
)
||
(
l
>
255L
))
{
return
null
;
}
bytes
[
i
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
}
l
=
Integer
.
parseInt
(
elements
[
2
]);
if
((
l
<
0L
)
||
(
l
>
65535L
))
{
return
null
;
}
bytes
[
2
]
=
(
byte
)
(
int
)
(
l
>>
8
&
0xFF
);
bytes
[
3
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
break
;
case
4
:
for
(
i
=
0
;
i
<
4
;
++
i
)
{
l
=
Integer
.
parseInt
(
elements
[
i
]);
if
((
l
<
0L
)
||
(
l
>
255L
))
{
return
null
;
}
bytes
[
i
]
=
(
byte
)
(
int
)
(
l
&
0xFF
);
}
break
;
default
:
return
null
;
}
}
catch
(
NumberFormatException
e
)
{
return
null
;
}
return
bytes
;
}
/**
* 获取IP地址
*
* @return 本地IP地址
*/
public
static
String
getHostIp
()
{
try
{
return
InetAddress
.
getLocalHost
().
getHostAddress
();
}
catch
(
UnknownHostException
e
)
{
}
return
"127.0.0.1"
;
}
/**
* 获取主机名
*
* @return 本地主机名
*/
public
static
String
getHostName
()
{
try
{
return
InetAddress
.
getLocalHost
().
getHostName
();
}
catch
(
UnknownHostException
e
)
{
}
return
"未知"
;
}
/**
* 从多级反向代理中获得第一个非unknown IP地址
*
* @param ip 获得的IP地址
* @return 第一个非unknown IP地址
*/
public
static
String
getMultistageReverseProxyIp
(
String
ip
)
{
// 多级反向代理检测
if
(
ip
!=
null
&&
ip
.
indexOf
(
","
)
>
0
)
{
final
String
[]
ips
=
ip
.
trim
().
split
(
","
);
for
(
String
subIp
:
ips
)
{
if
(!
isUnknown
(
subIp
))
{
ip
=
subIp
;
break
;
}
}
}
return
StringUtils
.
substring
(
ip
,
0
,
255
);
}
/**
* 检测给定字符串是否为未知,多用于检测HTTP请求相关
*
* @param checkString 被检测的字符串
* @return 是否未知
*/
public
static
boolean
isUnknown
(
String
checkString
)
{
return
StringUtils
.
isBlank
(
checkString
)
||
"unknown"
.
equalsIgnoreCase
(
checkString
);
}
/**
* 是否为IP
*/
public
static
boolean
isIP
(
String
ip
)
{
return
StringUtils
.
isNotBlank
(
ip
)
&&
ip
.
matches
(
REGX_IP
);
}
/**
* 是否为IP,或 *为间隔的通配符地址
*/
public
static
boolean
isIpWildCard
(
String
ip
)
{
return
StringUtils
.
isNotBlank
(
ip
)
&&
ip
.
matches
(
REGX_IP_WILDCARD
);
}
/**
* 检测参数是否在ip通配符里
*/
public
static
boolean
ipIsInWildCardNoCheck
(
String
ipWildCard
,
String
ip
)
{
String
[]
s1
=
ipWildCard
.
split
(
"\\."
);
String
[]
s2
=
ip
.
split
(
"\\."
);
boolean
isMatchedSeg
=
true
;
for
(
int
i
=
0
;
i
<
s1
.
length
&&
!
s1
[
i
].
equals
(
"*"
);
i
++)
{
if
(!
s1
[
i
].
equals
(
s2
[
i
]))
{
isMatchedSeg
=
false
;
break
;
}
}
return
isMatchedSeg
;
}
/**
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
*/
public
static
boolean
isIPSegment
(
String
ipSeg
)
{
return
StringUtils
.
isNotBlank
(
ipSeg
)
&&
ipSeg
.
matches
(
REGX_IP_SEG
);
}
/**
* 判断ip是否在指定网段中
*/
public
static
boolean
ipIsInNetNoCheck
(
String
iparea
,
String
ip
)
{
int
idx
=
iparea
.
indexOf
(
'-'
);
String
[]
sips
=
iparea
.
substring
(
0
,
idx
).
split
(
"\\."
);
String
[]
sipe
=
iparea
.
substring
(
idx
+
1
).
split
(
"\\."
);
String
[]
sipt
=
ip
.
split
(
"\\."
);
long
ips
=
0L
,
ipe
=
0L
,
ipt
=
0L
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
ips
=
ips
<<
8
|
Integer
.
parseInt
(
sips
[
i
]);
ipe
=
ipe
<<
8
|
Integer
.
parseInt
(
sipe
[
i
]);
ipt
=
ipt
<<
8
|
Integer
.
parseInt
(
sipt
[
i
]);
}
if
(
ips
>
ipe
)
{
long
t
=
ips
;
ips
=
ipe
;
ipe
=
t
;
}
return
ips
<=
ipt
&&
ipt
<=
ipe
;
}
/**
* 校验ip是否符合过滤串规则
*
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
* @param ip 校验IP地址
* @return boolean 结果
*/
public
static
boolean
isMatchedIp
(
String
filter
,
String
ip
)
{
if
(
StringUtils
.
isEmpty
(
filter
)
||
StringUtils
.
isEmpty
(
ip
))
{
return
false
;
}
String
[]
ips
=
filter
.
split
(
";"
);
for
(
String
iStr
:
ips
)
{
if
(
isIP
(
iStr
)
&&
iStr
.
equals
(
ip
))
{
return
true
;
}
else
if
(
isIpWildCard
(
iStr
)
&&
ipIsInWildCardNoCheck
(
iStr
,
ip
))
{
return
true
;
}
else
if
(
isIPSegment
(
iStr
)
&&
ipIsInNetNoCheck
(
iStr
,
ip
))
{
return
true
;
}
}
return
false
;
}
}
ewaytek-deepseek-common/src/main/java/com/ewaytek/deepseek/common/utils/poi/ExcelHandlerAdapter.java
0 → 100644
View file @
0487b6d5
package
com.ewaytek.deepseek.common.utils.poi
;
import
org.apache.poi.ss.usermodel.Cell
;
import
org.apache.poi.ss.usermodel.Workbook
;
/**
* Excel数据格式处理适配器
*
* @author ruoyi
*/
public
interface
ExcelHandlerAdapter
{
/**
* 格式化
*
* @param value 单元格数据值
* @param args excel注解args参数组
* @param cell 单元格对象
* @param wb 工作簿对象
*
* @return 处理后的值
*/
Object
format
(
Object
value
,
String
[]
args
,
Cell
cell
,
Workbook
wb
);
}
Prev
1
2
3
4
5
6
7
8
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment