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
Administrator
magic-api
Commits
02897568
Commit
02897568
authored
Dec 18, 2023
by
liang.tang
Browse files
magic-api
parents
Pipeline
#222
failed with stages
in 0 seconds
Changes
320
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2676 additions
and
0 deletions
+2676
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/provider/PascalColumnMapperProvider.java
...icapi/modules/db/provider/PascalColumnMapperProvider.java
+49
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/provider/UpperColumnMapperProvider.java
...gicapi/modules/db/provider/UpperColumnMapperProvider.java
+20
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/table/NamedTable.java
...va/org/ssssssss/magicapi/modules/db/table/NamedTable.java
+706
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/table/Where.java
...in/java/org/ssssssss/magicapi/modules/db/table/Where.java
+498
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/http/HttpModule.java
...n/java/org/ssssssss/magicapi/modules/http/HttpModule.java
+205
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/RequestModule.java
.../org/ssssssss/magicapi/modules/servlet/RequestModule.java
+115
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/ResponseModule.java
...org/ssssssss/magicapi/modules/servlet/ResponseModule.java
+157
-0
magic-api/src/main/java/org/ssssssss/magicapi/modules/spring/EnvModule.java
.../java/org/ssssssss/magicapi/modules/spring/EnvModule.java
+31
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/Assert.java
...api/src/main/java/org/ssssssss/magicapi/utils/Assert.java
+52
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/ClassScanner.java
...c/main/java/org/ssssssss/magicapi/utils/ClassScanner.java
+245
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/IoUtils.java
...pi/src/main/java/org/ssssssss/magicapi/utils/IoUtils.java
+171
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/IpUtils.java
...pi/src/main/java/org/ssssssss/magicapi/utils/IpUtils.java
+48
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/JdbcUtils.java
.../src/main/java/org/ssssssss/magicapi/utils/JdbcUtils.java
+44
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/JsonUtils.java
.../src/main/java/org/ssssssss/magicapi/utils/JsonUtils.java
+105
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/MD5Utils.java
...i/src/main/java/org/ssssssss/magicapi/utils/MD5Utils.java
+40
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/Mapping.java
...pi/src/main/java/org/ssssssss/magicapi/utils/Mapping.java
+92
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/PathUtils.java
.../src/main/java/org/ssssssss/magicapi/utils/PathUtils.java
+20
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/PatternUtils.java
...c/main/java/org/ssssssss/magicapi/utils/PatternUtils.java
+24
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/ScriptManager.java
.../main/java/org/ssssssss/magicapi/utils/ScriptManager.java
+41
-0
magic-api/src/main/java/org/ssssssss/magicapi/utils/SignUtils.java
.../src/main/java/org/ssssssss/magicapi/utils/SignUtils.java
+13
-0
No files found.
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/provider/PascalColumnMapperProvider.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.db.provider
;
/**
* 帕斯卡命名转换
*
* @author mxd
*/
public
class
PascalColumnMapperProvider
implements
ColumnMapperProvider
{
@Override
public
String
name
()
{
return
"pascal"
;
}
@Override
public
String
mapping
(
String
columnName
)
{
if
(
columnName
==
null
)
{
return
null
;
}
columnName
=
columnName
.
toLowerCase
();
boolean
upperCase
=
false
;
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
columnName
.
length
();
i
++)
{
char
ch
=
columnName
.
charAt
(
i
);
if
(
ch
==
'_'
)
{
upperCase
=
true
;
}
else
if
(
upperCase
||
i
==
0
)
{
sb
.
append
(
Character
.
toUpperCase
(
ch
));
upperCase
=
false
;
}
else
{
sb
.
append
(
ch
);
}
}
return
sb
.
toString
();
}
@Override
public
String
unmapping
(
String
name
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
name
.
length
();
i
++)
{
char
ch
=
name
.
charAt
(
i
);
if
(
i
>
0
&&
Character
.
isUpperCase
(
ch
))
{
sb
.
append
(
"_"
);
}
sb
.
append
(
Character
.
toLowerCase
(
ch
));
}
return
sb
.
toString
();
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/provider/UpperColumnMapperProvider.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.db.provider
;
/**
* 全大写命名
*
* @author mxd
*/
public
class
UpperColumnMapperProvider
implements
ColumnMapperProvider
{
@Override
public
String
name
()
{
return
"upper"
;
}
@Override
public
String
mapping
(
String
columnName
)
{
return
columnName
==
null
?
null
:
columnName
.
toUpperCase
();
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/table/NamedTable.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.db.table
;
import
org.apache.commons.lang3.StringUtils
;
import
org.ssssssss.magicapi.core.context.RequestContext
;
import
org.ssssssss.magicapi.core.exception.MagicAPIException
;
import
org.ssssssss.magicapi.core.model.Attributes
;
import
org.ssssssss.magicapi.core.context.RequestEntity
;
import
org.ssssssss.magicapi.modules.db.BoundSql
;
import
org.ssssssss.magicapi.modules.db.inteceptor.NamedTableInterceptor
;
import
org.ssssssss.magicapi.modules.db.SQLModule
;
import
org.ssssssss.magicapi.modules.db.model.Page
;
import
org.ssssssss.magicapi.modules.db.model.SqlMode
;
import
org.ssssssss.script.annotation.Comment
;
import
org.ssssssss.script.runtime.RuntimeContext
;
import
java.beans.Transient
;
import
java.io.Serializable
;
import
java.util.*
;
import
java.util.function.Function
;
import
java.util.function.Supplier
;
import
java.util.stream.Collectors
;
/**
* 单表操作API
*
* @author mxd
*/
public
class
NamedTable
extends
Attributes
<
Object
>
{
String
tableName
;
SQLModule
sqlModule
;
String
primary
;
String
logicDeleteColumn
;
Object
logicDeleteValue
;
Map
<
String
,
Object
>
columns
=
new
HashMap
<>();
List
<
String
>
fields
=
new
ArrayList
<>();
List
<
String
>
groups
=
new
ArrayList
<>();
List
<
String
>
orders
=
new
ArrayList
<>();
Set
<
String
>
excludeColumns
=
new
HashSet
<>();
Function
<
String
,
String
>
rowMapColumnMapper
;
Object
defaultPrimaryValue
;
boolean
useLogic
=
false
;
boolean
withBlank
=
false
;
List
<
NamedTableInterceptor
>
namedTableInterceptors
;
Where
where
=
new
Where
(
this
);
public
NamedTable
(
String
tableName
,
SQLModule
sqlModule
,
Function
<
String
,
String
>
rowMapColumnMapper
,
List
<
NamedTableInterceptor
>
namedTableInterceptors
)
{
this
.
tableName
=
tableName
;
this
.
sqlModule
=
sqlModule
;
this
.
rowMapColumnMapper
=
rowMapColumnMapper
;
this
.
namedTableInterceptors
=
namedTableInterceptors
;
this
.
logicDeleteColumn
=
sqlModule
.
getLogicDeleteColumn
();
String
deleteValue
=
sqlModule
.
getLogicDeleteValue
();
this
.
logicDeleteValue
=
deleteValue
;
if
(
deleteValue
!=
null
)
{
boolean
isString
=
deleteValue
.
startsWith
(
"'"
)
||
deleteValue
.
startsWith
(
"\""
);
if
(
isString
&&
deleteValue
.
length
()
>
2
)
{
this
.
logicDeleteValue
=
deleteValue
.
substring
(
1
,
deleteValue
.
length
()
-
1
);
}
else
{
try
{
this
.
logicDeleteValue
=
Integer
.
parseInt
(
deleteValue
);
}
catch
(
NumberFormatException
e
)
{
this
.
logicDeleteValue
=
deleteValue
;
}
}
}
}
private
NamedTable
()
{
}
@Override
@Comment
(
"克隆"
)
public
NamedTable
clone
()
{
NamedTable
namedTable
=
new
NamedTable
();
namedTable
.
tableName
=
this
.
tableName
;
namedTable
.
sqlModule
=
this
.
sqlModule
;
namedTable
.
primary
=
this
.
primary
;
namedTable
.
logicDeleteValue
=
this
.
logicDeleteValue
;
namedTable
.
logicDeleteColumn
=
this
.
logicDeleteColumn
;
namedTable
.
columns
=
new
HashMap
<>(
this
.
columns
);
namedTable
.
fields
=
new
ArrayList
<>(
fields
);
namedTable
.
groups
=
new
ArrayList
<>(
groups
);
namedTable
.
orders
=
new
ArrayList
<>(
orders
);
namedTable
.
excludeColumns
=
new
HashSet
<>(
excludeColumns
);
namedTable
.
rowMapColumnMapper
=
this
.
rowMapColumnMapper
;
namedTable
.
defaultPrimaryValue
=
this
.
defaultPrimaryValue
;
namedTable
.
useLogic
=
this
.
useLogic
;
namedTable
.
withBlank
=
this
.
withBlank
;
namedTable
.
where
=
this
.
where
==
null
?
null
:
this
.
where
.
clone
();
namedTable
.
namedTableInterceptors
=
this
.
namedTableInterceptors
;
namedTable
.
properties
=
this
.
properties
;
return
namedTable
;
}
@Comment
(
"使用逻辑删除"
)
public
NamedTable
logic
()
{
this
.
useLogic
=
true
;
return
this
;
}
@Comment
(
"更新空值"
)
public
NamedTable
withBlank
()
{
this
.
withBlank
=
true
;
return
this
;
}
@Comment
(
"设置主键名,update时使用"
)
public
NamedTable
primary
(
@Comment
(
name
=
"primary"
,
value
=
"主键列"
)
String
primary
)
{
this
.
primary
=
rowMapColumnMapper
.
apply
(
primary
);
return
this
;
}
@Comment
(
"设置主键名,并设置默认主键值(主要用于insert)"
)
public
NamedTable
primary
(
@Comment
(
name
=
"primary"
,
value
=
"主键列"
)
String
primary
,
@Comment
(
name
=
"defaultPrimaryValue"
,
value
=
"默认值"
)
Serializable
defaultPrimaryValue
)
{
this
.
primary
=
rowMapColumnMapper
.
apply
(
primary
);
this
.
defaultPrimaryValue
=
defaultPrimaryValue
;
return
this
;
}
@Comment
(
"设置主键名,并设置默认主键值(主要用于insert)"
)
public
NamedTable
primary
(
@Comment
(
name
=
"primary"
,
value
=
"主键列"
)
String
primary
,
@Comment
(
name
=
"defaultPrimaryValue"
,
value
=
"默认值"
)
Supplier
<
Object
>
defaultPrimaryValue
)
{
this
.
primary
=
rowMapColumnMapper
.
apply
(
primary
);
this
.
defaultPrimaryValue
=
defaultPrimaryValue
;
return
this
;
}
@Comment
(
"拼接where"
)
public
Where
where
()
{
return
where
;
}
@Comment
(
"设置单列的值"
)
public
NamedTable
column
(
@Comment
(
name
=
"property"
,
value
=
"列名"
)
String
property
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
this
.
columns
.
put
(
rowMapColumnMapper
.
apply
(
property
),
value
);
return
this
;
}
@Comment
(
"设置查询的列,如`columns('a','b','c')`"
)
public
NamedTable
columns
(
@Comment
(
name
=
"properties"
,
value
=
"各项列"
)
String
...
properties
)
{
if
(
properties
!=
null
)
{
for
(
String
property
:
properties
)
{
column
(
property
);
}
}
return
this
;
}
@Comment
(
"设置要排除的列"
)
public
NamedTable
exclude
(
@Comment
(
name
=
"property"
,
value
=
"排除的列"
)
String
property
)
{
if
(
property
!=
null
)
{
excludeColumns
.
add
(
property
);
}
return
this
;
}
@Comment
(
"设置要排除的列"
)
public
NamedTable
excludes
(
@Comment
(
name
=
"properties"
,
value
=
"排除的列"
)
String
...
properties
)
{
if
(
columns
!=
null
)
{
excludeColumns
.
addAll
(
Arrays
.
asList
(
properties
));
}
return
this
;
}
@Comment
(
"设置要排除的列"
)
public
NamedTable
excludes
(
@Comment
(
name
=
"properties"
,
value
=
"排除的列"
)
List
<
String
>
properties
)
{
if
(
columns
!=
null
)
{
excludeColumns
.
addAll
(
properties
);
}
return
this
;
}
@Comment
(
"设置查询的列,如`columns(['a','b','c'])`"
)
public
NamedTable
columns
(
@Comment
(
name
=
"properties"
,
value
=
"查询的列"
)
Collection
<
String
>
properties
)
{
if
(
properties
!=
null
)
{
properties
.
stream
().
filter
(
StringUtils:
:
isNotBlank
).
map
(
rowMapColumnMapper
).
forEach
(
this
.
fields
::
add
);
}
return
this
;
}
@Comment
(
"设置查询的列,如`column('a')`"
)
public
NamedTable
column
(
@Comment
(
name
=
"property"
,
value
=
"查询的列"
)
String
property
)
{
if
(
StringUtils
.
isNotBlank
(
property
))
{
this
.
fields
.
add
(
this
.
rowMapColumnMapper
.
apply
(
property
));
}
return
this
;
}
@Comment
(
"拼接`order by xxx asc/desc`"
)
public
NamedTable
orderBy
(
@Comment
(
name
=
"property"
,
value
=
"要排序的列"
)
String
property
,
@Comment
(
name
=
"sort"
,
value
=
"`asc`或`desc`"
)
String
sort
)
{
this
.
orders
.
add
(
rowMapColumnMapper
.
apply
(
property
)
+
" "
+
sort
);
return
this
;
}
@Comment
(
"拼接`order by xxx asc`"
)
public
NamedTable
orderBy
(
@Comment
(
name
=
"property"
,
value
=
"要排序的列"
)
String
property
)
{
return
orderBy
(
property
,
"asc"
);
}
@Comment
(
"拼接`order by xxx desc`"
)
public
NamedTable
orderByDesc
(
@Comment
(
name
=
"property"
,
value
=
"要排序的列"
)
String
property
)
{
return
orderBy
(
property
,
"desc"
);
}
@Comment
(
"拼接`group by`"
)
public
NamedTable
groupBy
(
@Comment
(
name
=
"properties"
,
value
=
"要分组的列"
)
String
...
properties
)
{
this
.
groups
.
addAll
(
Arrays
.
stream
(
properties
).
map
(
rowMapColumnMapper
).
collect
(
Collectors
.
toList
()));
return
this
;
}
@Comment
(
"执行插入,返回主键"
)
public
Object
insert
(
RuntimeContext
runtimeContext
)
{
return
insert
(
runtimeContext
,
null
);
}
@Comment
(
"执行插入,返回主键"
)
public
Object
insert
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
)
{
if
(
data
!=
null
)
{
data
.
forEach
((
key
,
value
)
->
this
.
columns
.
put
(
rowMapColumnMapper
.
apply
(
key
),
value
));
}
if
(
this
.
defaultPrimaryValue
!=
null
&&
StringUtils
.
isBlank
(
Objects
.
toString
(
this
.
columns
.
getOrDefault
(
this
.
primary
,
""
))))
{
if
(
this
.
defaultPrimaryValue
instanceof
Supplier
)
{
this
.
columns
.
put
(
this
.
primary
,
((
Supplier
<?>)
this
.
defaultPrimaryValue
).
get
());
}
else
{
this
.
columns
.
put
(
this
.
primary
,
this
.
defaultPrimaryValue
);
}
}
preHandle
(
SqlMode
.
INSERT
);
Collection
<
Map
.
Entry
<
String
,
Object
>>
entries
=
filterNotBlanks
();
if
(
entries
.
isEmpty
())
{
throw
new
MagicAPIException
(
"参数不能为空"
);
}
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
"insert into "
);
builder
.
append
(
tableName
);
builder
.
append
(
"("
);
builder
.
append
(
StringUtils
.
join
(
entries
.
stream
().
map
(
Map
.
Entry
::
getKey
).
toArray
(),
","
));
builder
.
append
(
") values ("
);
builder
.
append
(
StringUtils
.
join
(
Collections
.
nCopies
(
entries
.
size
(),
"?"
),
","
));
builder
.
append
(
")"
);
Object
value
=
sqlModule
.
insert
(
new
BoundSql
(
runtimeContext
,
builder
.
toString
(),
entries
.
stream
().
map
(
Map
.
Entry
::
getValue
).
collect
(
Collectors
.
toList
()),
sqlModule
),
this
.
primary
);
if
(
value
==
null
&&
StringUtils
.
isNotBlank
(
this
.
primary
)){
return
this
.
columns
.
get
(
this
.
primary
);
}
return
value
;
}
@Comment
(
"执行delete语句"
)
public
int
delete
(
RuntimeContext
runtimeContext
)
{
preHandle
(
SqlMode
.
DELETE
);
if
(
useLogic
)
{
Map
<
String
,
Object
>
dataMap
=
new
HashMap
<>();
dataMap
.
put
(
logicDeleteColumn
,
logicDeleteValue
);
return
update
(
runtimeContext
,
dataMap
);
}
if
(
where
.
isEmpty
())
{
throw
new
MagicAPIException
(
"delete语句不能没有条件"
);
}
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
"delete from "
);
builder
.
append
(
tableName
);
builder
.
append
(
where
.
getSql
());
return
sqlModule
.
update
(
new
BoundSql
(
runtimeContext
,
builder
.
toString
(),
where
.
getParams
(),
sqlModule
));
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
)
{
return
this
.
save
(
runtimeContext
,
null
,
false
);
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
,
@Comment
(
name
=
"beforeQuery"
,
value
=
"是否根据id查询有没有数据"
)
boolean
beforeQuery
)
{
if
(
StringUtils
.
isBlank
(
this
.
primary
))
{
throw
new
MagicAPIException
(
"请设置主键"
);
}
if
(
data
!=
null
)
{
data
.
forEach
((
key
,
value
)
->
this
.
columns
.
put
(
rowMapColumnMapper
.
apply
(
key
),
value
));
}
String
primaryValue
=
Objects
.
toString
(
this
.
columns
.
get
(
this
.
primary
),
""
);
if
(
StringUtils
.
isBlank
(
primaryValue
)
&&
data
!=
null
)
{
primaryValue
=
Objects
.
toString
(
data
.
get
(
this
.
primary
),
""
);
}
if
(
beforeQuery
)
{
if
(
StringUtils
.
isNotBlank
(
primaryValue
))
{
List
<
Object
>
params
=
new
ArrayList
<>();
params
.
add
(
primaryValue
);
Integer
count
=
sqlModule
.
selectInt
(
new
BoundSql
(
runtimeContext
,
"select count(*) count from "
+
this
.
tableName
+
" where "
+
this
.
primary
+
" = ?"
,
params
,
sqlModule
));
if
(
count
==
0
)
{
return
insert
(
runtimeContext
,
data
);
}
return
update
(
runtimeContext
,
data
);
}
else
{
return
insert
(
runtimeContext
,
data
);
}
}
if
(
StringUtils
.
isNotBlank
(
primaryValue
))
{
return
update
(
runtimeContext
,
data
);
}
return
insert
(
runtimeContext
,
data
);
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"beforeQuery"
,
value
=
"是否根据id查询有没有数据"
)
boolean
beforeQuery
)
{
return
this
.
save
(
runtimeContext
,
null
,
beforeQuery
);
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
)
{
return
this
.
save
(
runtimeContext
,
data
,
false
);
}
@Comment
(
"批量插入"
)
public
int
batchInsert
(
@Comment
(
name
=
"collection"
,
value
=
"各项列和值"
)
Collection
<
Map
<
String
,
Object
>>
collection
,
@Comment
(
"batchSize"
)
int
batchSize
)
{
Set
<
String
>
keys
=
collection
.
stream
().
flatMap
(
it
->
it
.
keySet
().
stream
()).
collect
(
Collectors
.
toSet
());
if
(
keys
.
isEmpty
())
{
throw
new
MagicAPIException
(
"要插入的列不能为空"
);
}
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
"insert into "
);
builder
.
append
(
tableName
);
builder
.
append
(
"("
);
builder
.
append
(
StringUtils
.
join
(
keys
.
stream
().
map
(
rowMapColumnMapper
).
collect
(
Collectors
.
toList
()),
","
));
builder
.
append
(
") values ("
);
builder
.
append
(
StringUtils
.
join
(
Collections
.
nCopies
(
keys
.
size
(),
"?"
),
","
));
builder
.
append
(
")"
);
return
this
.
sqlModule
.
batchUpdate
(
builder
.
toString
(),
batchSize
,
collection
.
stream
()
.
map
(
it
->
keys
.
stream
().
map
(
it:
:
get
).
toArray
())
.
collect
(
Collectors
.
toList
()));
}
@Comment
(
"批量插入"
)
public
int
batchInsert
(
@Comment
(
name
=
"collection"
,
value
=
"各项列和值"
)
Collection
<
Map
<
String
,
Object
>>
collection
)
{
return
batchInsert
(
collection
,
100
);
}
@Comment
(
"执行`select`查询"
)
public
List
<
Map
<
String
,
Object
>>
select
(
RuntimeContext
runtimeContext
)
{
preHandle
(
SqlMode
.
SELECT
);
return
sqlModule
.
select
(
buildSelect
(
runtimeContext
));
}
@Comment
(
"执行`selectOne`查询"
)
public
Map
<
String
,
Object
>
selectOne
(
RuntimeContext
runtimeContext
)
{
preHandle
(
SqlMode
.
SELECT_ONE
);
return
sqlModule
.
selectOne
(
buildSelect
(
runtimeContext
));
}
@Comment
(
"执行分页查询"
)
public
Object
page
(
RuntimeContext
runtimeContext
)
{
preHandle
(
SqlMode
.
PAGE
);
return
sqlModule
.
page
(
buildSelect
(
runtimeContext
));
}
@Comment
(
"执行分页查询,分页条件手动传入"
)
public
Object
page
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"limit"
,
value
=
"限制条数"
)
long
limit
,
@Comment
(
name
=
"offset"
,
value
=
"跳过条数"
)
long
offset
)
{
preHandle
(
SqlMode
.
PAGE
);
return
sqlModule
.
page
(
buildSelect
(
runtimeContext
),
new
Page
(
limit
,
offset
));
}
@Comment
(
"执行update语句"
)
public
int
update
(
RuntimeContext
runtimeContext
)
{
return
update
(
runtimeContext
,
null
);
}
@Comment
(
"执行update语句"
)
public
int
update
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
,
@Comment
(
name
=
"isUpdateBlank"
,
value
=
"是否更新空值字段"
)
boolean
isUpdateBlank
)
{
if
(
null
!=
data
)
{
data
.
forEach
((
key
,
value
)
->
this
.
columns
.
put
(
rowMapColumnMapper
.
apply
(
key
),
value
));
}
preHandle
(
SqlMode
.
UPDATE
);
Object
primaryValue
=
null
;
if
(
StringUtils
.
isNotBlank
(
this
.
primary
))
{
primaryValue
=
this
.
columns
.
remove
(
this
.
primary
);
}
this
.
withBlank
=
isUpdateBlank
;
List
<
Map
.
Entry
<
String
,
Object
>>
entries
=
new
ArrayList
<>(
filterNotBlanks
());
if
(
entries
.
isEmpty
())
{
throw
new
MagicAPIException
(
"要修改的列不能为空"
);
}
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
"update "
);
builder
.
append
(
tableName
);
builder
.
append
(
" set "
);
List
<
Object
>
params
=
new
ArrayList
<>();
for
(
int
i
=
0
,
size
=
entries
.
size
();
i
<
size
;
i
++)
{
Map
.
Entry
<
String
,
Object
>
entry
=
entries
.
get
(
i
);
builder
.
append
(
entry
.
getKey
()).
append
(
" = ?"
);
params
.
add
(
entry
.
getValue
());
if
(
i
+
1
<
size
)
{
builder
.
append
(
","
);
}
}
if
(!
where
.
isEmpty
())
{
builder
.
append
(
where
.
getSql
());
params
.
addAll
(
where
.
getParams
());
}
else
if
(
primaryValue
!=
null
)
{
builder
.
append
(
" where "
).
append
(
this
.
primary
).
append
(
" = ?"
);
params
.
add
(
primaryValue
);
}
else
{
throw
new
MagicAPIException
(
"主键值不能为空"
);
}
return
sqlModule
.
update
(
new
BoundSql
(
runtimeContext
,
builder
.
toString
(),
params
,
sqlModule
));
}
@Comment
(
"执行update语句"
)
public
int
update
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
)
{
return
update
(
runtimeContext
,
data
,
this
.
withBlank
);
}
@Comment
(
"查询条数"
)
public
int
count
(
RuntimeContext
runtimeContext
)
{
preHandle
(
SqlMode
.
COUNT
);
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
"select count(1) from "
).
append
(
tableName
);
List
<
Object
>
params
=
buildWhere
(
builder
);
return
sqlModule
.
selectInt
(
new
BoundSql
(
runtimeContext
,
builder
.
toString
(),
params
,
sqlModule
));
}
@Comment
(
"判断是否存在"
)
public
boolean
exists
(
RuntimeContext
runtimeContext
)
{
return
count
(
runtimeContext
)
>
0
;
}
private
Collection
<
Map
.
Entry
<
String
,
Object
>>
filterNotBlanks
()
{
if
(
this
.
withBlank
)
{
return
this
.
columns
.
entrySet
()
.
stream
()
.
filter
(
it
->
!
excludeColumns
.
contains
(
it
.
getKey
()))
.
collect
(
Collectors
.
toList
());
}
return
this
.
columns
.
entrySet
()
.
stream
()
.
filter
(
it
->
StringUtils
.
isNotBlank
(
Objects
.
toString
(
it
.
getValue
(),
""
)))
.
filter
(
it
->
!
excludeColumns
.
contains
(
it
.
getKey
()))
.
collect
(
Collectors
.
toList
());
}
private
void
preHandle
(
SqlMode
sqlMode
)
{
if
(
this
.
namedTableInterceptors
!=
null
)
{
this
.
namedTableInterceptors
.
forEach
(
interceptor
->
interceptor
.
preHandle
(
sqlMode
,
this
));
}
}
private
BoundSql
buildSelect
(
RuntimeContext
runtimeContext
)
{
StringBuilder
builder
=
new
StringBuilder
();
builder
.
append
(
"select "
);
List
<
String
>
fields
=
this
.
fields
.
stream
()
.
filter
(
it
->
!
excludeColumns
.
contains
(
it
))
.
collect
(
Collectors
.
toList
());
if
(
fields
.
isEmpty
())
{
builder
.
append
(
"*"
);
}
else
{
builder
.
append
(
StringUtils
.
join
(
fields
,
","
));
}
builder
.
append
(
" from "
).
append
(
tableName
);
List
<
Object
>
params
=
buildWhere
(
builder
);
if
(!
groups
.
isEmpty
())
{
builder
.
append
(
" group by "
);
builder
.
append
(
String
.
join
(
","
,
groups
));
}
if
(!
orders
.
isEmpty
())
{
builder
.
append
(
" order by "
);
builder
.
append
(
String
.
join
(
","
,
orders
));
}
BoundSql
boundSql
=
new
BoundSql
(
runtimeContext
,
builder
.
toString
(),
params
,
sqlModule
);
boundSql
.
setExcludeColumns
(
excludeColumns
);
return
boundSql
;
}
private
List
<
Object
>
buildWhere
(
StringBuilder
builder
)
{
List
<
Object
>
params
=
new
ArrayList
<>();
if
(!
where
.
isEmpty
())
{
where
.
and
();
where
.
ne
(
useLogic
,
logicDeleteColumn
,
logicDeleteValue
);
builder
.
append
(
where
.
getSql
());
params
.
addAll
(
where
.
getParams
());
}
else
if
(
useLogic
)
{
where
.
ne
(
logicDeleteColumn
,
logicDeleteValue
);
builder
.
append
(
where
.
getSql
());
params
.
addAll
(
where
.
getParams
());
}
return
params
;
}
/**
* 获取查询的表名
*
* @return 表名
*/
@Transient
public
String
getTableName
()
{
return
tableName
;
}
/**
* 设置表名
*
* @param tableName 表名
*/
@Transient
public
void
setTableName
(
String
tableName
)
{
this
.
tableName
=
tableName
;
}
/**
* 获取SQL模块
*/
@Transient
public
SQLModule
getSqlModule
()
{
return
sqlModule
;
}
/**
* 获取主键列
*/
@Transient
public
String
getPrimary
()
{
return
primary
;
}
/**
* 获取逻辑删除列
*/
@Transient
public
String
getLogicDeleteColumn
()
{
return
logicDeleteColumn
;
}
/**
* 获取逻辑删除值
*/
@Transient
public
Object
getLogicDeleteValue
()
{
return
logicDeleteValue
;
}
/**
* 获取设置的columns
*/
@Transient
public
Map
<
String
,
Object
>
getColumns
()
{
return
columns
;
}
/**
* 设置columns
*/
@Transient
public
void
setColumns
(
Map
<
String
,
Object
>
columns
)
{
this
.
columns
=
columns
;
}
/**
* 获取设置的fields
*/
@Transient
public
List
<
String
>
getFields
()
{
return
fields
;
}
/**
* 设置 fields
*/
@Transient
public
void
setFields
(
List
<
String
>
fields
)
{
this
.
fields
=
fields
;
}
/**
* 获取设置的group
*/
@Transient
public
List
<
String
>
getGroups
()
{
return
groups
;
}
/**
* 设置 group
*/
@Transient
public
void
setGroups
(
List
<
String
>
groups
)
{
this
.
groups
=
groups
;
}
/**
* 获取设置的order
*/
@Transient
public
List
<
String
>
getOrders
()
{
return
orders
;
}
/**
* 设置 order
*/
@Transient
public
void
setOrders
(
List
<
String
>
orders
)
{
this
.
orders
=
orders
;
}
/**
* 获取设置的排除的列
*/
@Transient
public
Set
<
String
>
getExcludeColumns
()
{
return
excludeColumns
;
}
/**
* 设置排除的列
*/
@Transient
public
void
setExcludeColumns
(
Set
<
String
>
excludeColumns
)
{
this
.
excludeColumns
=
excludeColumns
;
}
/**
* 主键默认值
*
* @return
*/
@Transient
public
Object
getDefaultPrimaryValue
()
{
return
defaultPrimaryValue
;
}
/**
* 是否设逻辑了逻辑删除
*/
@Transient
public
boolean
isUseLogic
()
{
return
useLogic
;
}
/**
* 设置是否使用逻辑删除
*/
@Transient
public
void
setUseLogic
(
boolean
useLogic
)
{
this
.
useLogic
=
useLogic
;
}
/**
* 获取是否不过滤空参数
*/
@Transient
public
boolean
isWithBlank
()
{
return
withBlank
;
}
/**
* 设置是否不过滤空参数
*/
@Transient
public
void
setWithBlank
(
boolean
withBlank
)
{
this
.
withBlank
=
withBlank
;
}
/**
* 获取where
*/
@Transient
public
Where
getWhere
()
{
return
where
;
}
/**
* 获取RequestEntity
*/
@Transient
public
RequestEntity
getRequestEntity
()
{
return
RequestContext
.
getRequestEntity
();
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/db/table/Where.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.db.table
;
import
org.apache.commons.lang3.StringUtils
;
import
org.ssssssss.script.annotation.Comment
;
import
org.ssssssss.script.functions.StreamExtension
;
import
org.ssssssss.script.runtime.RuntimeContext
;
import
java.beans.Transient
;
import
java.util.*
;
import
java.util.function.Function
;
/**
* 单表API的Where
*
* @author mxd
*/
public
class
Where
{
private
final
List
<
String
>
tokens
=
new
ArrayList
<>();
private
final
List
<
Object
>
params
=
new
ArrayList
<>();
private
final
NamedTable
namedTable
;
private
final
boolean
needWhere
;
private
boolean
notNull
=
false
;
private
boolean
notBlank
=
false
;
public
Where
(
NamedTable
namedTable
)
{
this
(
namedTable
,
true
);
}
public
Where
(
NamedTable
namedTable
,
boolean
needWhere
)
{
this
.
namedTable
=
namedTable
;
this
.
needWhere
=
needWhere
;
}
@Override
@Comment
(
"克隆"
)
public
Where
clone
()
{
Where
where
=
new
Where
(
this
.
namedTable
,
this
.
needWhere
);
where
.
tokens
.
addAll
(
this
.
tokens
);
where
.
params
.
addAll
(
this
.
params
);
where
.
notNull
=
this
.
notNull
;
where
.
notBlank
=
this
.
notBlank
;
return
where
;
}
@Comment
(
"过滤`null`的参数"
)
public
Where
notNull
()
{
return
notNull
(
true
);
}
@Comment
(
"过滤`blank`的参数"
)
public
Where
notBlank
()
{
return
notBlank
(
true
);
}
@Comment
(
"是否过滤`null`的参数"
)
public
Where
notNull
(
boolean
flag
)
{
this
.
notNull
=
flag
;
return
this
;
}
@Comment
(
"是否过滤`blank`的参数"
)
public
Where
notBlank
(
boolean
flag
)
{
this
.
notBlank
=
flag
;
return
this
;
}
@Comment
(
"等于`=`,如:`eq('name', '老王') ---> name = '老王'`"
)
public
Where
eq
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
eq
(
true
,
column
,
value
);
}
@Comment
(
"等于`=`,如:`eq('name', '老王') ---> name = '老王'`"
)
public
Where
eq
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
if
(
condition
&&
filterNullAndBlank
(
value
))
{
tokens
.
add
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
if
(
value
==
null
)
{
append
(
" is null"
);
}
else
{
params
.
add
(
value
);
append
(
" = ?"
);
}
appendAnd
();
}
return
this
;
}
@Comment
(
"不等于`<>`,如:`ne('name', '老王') ---> name <> '老王'`"
)
public
Where
ne
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
ne
(
true
,
column
,
value
);
}
@Comment
(
"不等于`<>`,如:`ne('name', '老王') ---> name <> '老王'`"
)
public
Where
ne
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
if
(
condition
&&
filterNullAndBlank
(
value
))
{
append
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
if
(
value
==
null
)
{
append
(
"is not null"
);
}
else
{
params
.
add
(
value
);
append
(
"<> ?"
);
}
appendAnd
();
}
return
this
;
}
@Comment
(
"小于`<`,如:`lt('age', 18) ---> age < 18"
)
public
Where
lt
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
lt
(
true
,
column
,
value
);
}
@Comment
(
"小于`<`,如:`lt('age', 18) ---> age < 18"
)
public
Where
lt
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
append
(
condition
,
column
,
" < ?"
,
value
);
}
@Comment
(
"小于等于`<=`,如:`lte('age', 18) ---> age <= 18"
)
public
Where
lte
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
lte
(
true
,
column
,
value
);
}
@Comment
(
"小于等于`<=`,如:`lte('age', 18) ---> age <= 18"
)
public
Where
lte
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
append
(
condition
,
column
,
" <= ?"
,
value
);
}
@Comment
(
"大于`>`,如:`get('age', 18) ---> age > 18"
)
public
Where
gt
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
gt
(
true
,
column
,
value
);
}
@Comment
(
"大于`>`,如:`get('age', 18) ---> age > 18"
)
public
Where
gt
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
append
(
condition
,
column
,
" > ?"
,
value
);
}
@Comment
(
"大于等于`>=`,如:`get('age', 18) ---> age >= 18"
)
public
Where
gte
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
gte
(
true
,
column
,
value
);
}
@Comment
(
"大于等于`>=`,如:`get('age', 18) ---> age >= 18"
)
public
Where
gte
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
append
(
condition
,
column
,
" >= ?"
,
value
);
}
@Comment
(
"`in`,如:`in('age', [1,2,3]) ---> age in (1,2,3)"
)
public
Where
in
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
in
(
true
,
column
,
value
);
}
@Comment
(
"`in`,如:`in('age', [1,2,3]) ---> age in (1,2,3)"
)
public
Where
in
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
if
(
condition
&&
value
!=
null
)
{
List
<
Object
>
objects
=
StreamExtension
.
arrayLikeToList
(
value
);
if
(
objects
.
size
()
>
0
)
{
append
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
append
(
" in ("
);
append
(
String
.
join
(
","
,
Collections
.
nCopies
(
objects
.
size
(),
"?"
)));
append
(
")"
);
appendAnd
();
params
.
addAll
(
objects
);
}
}
return
this
;
}
@Comment
(
"`not in`,如:`notIn('age', [1,2,3]) ---> age not in (1,2,3)"
)
public
Where
notIn
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
notIn
(
true
,
column
,
value
);
}
@Comment
(
"`not in`,如:`notIn('age', [1,2,3]) ---> age not in (1,2,3)"
)
public
Where
notIn
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
if
(
condition
&&
value
!=
null
)
{
List
<
Object
>
objects
=
StreamExtension
.
arrayLikeToList
(
value
);
if
(
objects
.
size
()
>
0
)
{
append
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
append
(
"not in ("
);
append
(
String
.
join
(
","
,
Collections
.
nCopies
(
objects
.
size
(),
"?"
)));
append
(
")"
);
appendAnd
();
params
.
addAll
(
objects
);
}
}
return
this
;
}
@Comment
(
"`like`,如:`like('name', '%王%') ---> name like '%王%'"
)
public
Where
like
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
like
(
true
,
column
,
value
);
}
@Comment
(
"`like`,如:`like('name', '%王%') ---> name like '%王%'"
)
public
Where
like
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
append
(
condition
,
column
,
"like ?"
,
value
);
}
@Comment
(
"`not like`,如:`notLike('name', '%王%') ---> name not like '%王%'"
)
public
Where
notLike
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
notLike
(
true
,
column
,
value
);
}
@Comment
(
"`not like` ,如:`notLike('name', '%王%') ---> name not like '%王%'"
)
public
Where
notLike
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
,
@Comment
(
name
=
"value"
,
value
=
"值"
)
Object
value
)
{
return
append
(
condition
,
column
,
"not like ?"
,
value
);
}
@Comment
(
"`is null`,如:`isNull('name') ---> name is null"
)
public
Where
isNull
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
)
{
return
isNull
(
true
,
column
);
}
@Comment
(
"`is null`,如:`isNull('name') ---> name is null"
)
public
Where
isNull
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
)
{
if
(
condition
)
{
append
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
append
(
"is null"
);
appendAnd
();
}
return
this
;
}
@Comment
(
"`is not null`,如:`isNotNull('name') ---> name is not null"
)
public
Where
isNotNull
(
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
)
{
return
isNotNull
(
true
,
column
);
}
@Comment
(
"`is not null`,如:`isNotNull('name') ---> name is not null"
)
public
Where
isNotNull
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"column"
,
value
=
"数据库中的列名"
)
String
column
)
{
if
(
condition
)
{
append
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
append
(
"is not null"
);
appendAnd
();
}
return
this
;
}
@Comment
(
"拼接`or`"
)
public
Where
or
()
{
appendOr
();
return
this
;
}
@Comment
(
"拼接`and`"
)
public
Where
and
()
{
appendAnd
();
return
this
;
}
@Comment
(
"`and`嵌套,如and(it => it.eq('name','李白').ne('status','正常') --> and (name = '李白' and status <> '正常')"
)
public
Where
and
(
@Comment
(
name
=
"function"
,
value
=
"回调函数"
)
Function
<
Object
[],
Where
>
function
)
{
return
and
(
true
,
function
);
}
@Comment
(
"`and`嵌套,如and(it => it.eq('name','李白').ne('status','正常') --> and (name = '李白' and status <> '正常')"
)
public
Where
and
(
@Comment
(
name
=
"condition"
,
value
=
"判断表达式,当为true时拼接条件"
)
boolean
condition
,
@Comment
(
name
=
"function"
,
value
=
"回调函数"
)
Function
<
Object
[],
Where
>
function
)
{
if
(
condition
)
{
Where
expr
=
function
.
apply
(
new
Object
[]{
new
Where
(
this
.
namedTable
,
false
)});
this
.
params
.
addAll
(
expr
.
params
);
append
(
"("
);
append
(
expr
.
getSql
());
append
(
")"
);
appendAnd
();
}
return
this
;
}
@Comment
(
"拼接`order by xxx asc/desc`"
)
public
Where
orderBy
(
@Comment
(
name
=
"column"
,
value
=
"要排序的列"
)
String
column
,
@Comment
(
name
=
"sort"
,
value
=
"`asc`或`desc`"
)
String
sort
)
{
this
.
namedTable
.
orderBy
(
column
,
sort
);
return
this
;
}
@Comment
(
"拼接`order by xxx asc`"
)
public
Where
orderBy
(
@Comment
(
name
=
"column"
,
value
=
"要排序的列"
)
String
column
)
{
return
orderBy
(
column
,
"asc"
);
}
@Comment
(
"拼接`order by xxx desc`"
)
public
Where
orderByDesc
(
@Comment
(
name
=
"column"
,
value
=
"要排序的列"
)
String
column
)
{
return
orderBy
(
column
,
"desc"
);
}
@Comment
(
"拼接`group by`"
)
public
Where
groupBy
(
@Comment
(
"要分组的列"
)
String
...
columns
)
{
this
.
namedTable
.
groupBy
(
columns
);
return
this
;
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
save
(
runtimeContext
);
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"beforeQuery"
,
value
=
"是否根据id查询有没有数据"
)
boolean
beforeQuery
)
{
return
namedTable
.
save
(
runtimeContext
,
beforeQuery
);
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
)
{
return
namedTable
.
save
(
runtimeContext
,
data
);
}
@Comment
(
"保存到表中,当主键有值时则修改,否则插入"
)
public
Object
save
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
,
@Comment
(
name
=
"beforeQuery"
,
value
=
"是否根据id查询有没有数据"
)
boolean
beforeQuery
)
{
return
namedTable
.
save
(
runtimeContext
,
data
,
beforeQuery
);
}
@Comment
(
"执行插入语句,返回主键"
)
public
Object
insert
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
insert
(
runtimeContext
);
}
@Comment
(
"执行插入语句,返回主键"
)
public
Object
insert
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
)
{
return
namedTable
.
insert
(
runtimeContext
,
data
);
}
@Comment
(
"执行update语句"
)
public
int
update
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
update
(
runtimeContext
);
}
@Comment
(
"执行delete语句"
)
public
int
delete
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
delete
(
runtimeContext
);
}
@Comment
(
"执行update语句"
)
public
int
update
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
)
{
return
namedTable
.
update
(
runtimeContext
,
data
);
}
@Comment
(
"执行update语句"
)
public
int
update
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"data"
,
value
=
"各项列和值"
)
Map
<
String
,
Object
>
data
,
@Comment
(
name
=
"isUpdateBlank"
,
value
=
"是否更新空值字段"
)
boolean
isUpdateBlank
)
{
return
namedTable
.
update
(
runtimeContext
,
data
,
isUpdateBlank
);
}
@Comment
(
"执行分页查询"
)
public
Object
page
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
page
(
runtimeContext
);
}
@Comment
(
"执行分页查询,分页条件手动传入"
)
public
Object
page
(
RuntimeContext
runtimeContext
,
@Comment
(
name
=
"limit"
,
value
=
"限制条数"
)
long
limit
,
@Comment
(
name
=
"offset"
,
value
=
"跳过条数"
)
long
offset
)
{
return
namedTable
.
page
(
runtimeContext
,
limit
,
offset
);
}
@Comment
(
"执行select查询"
)
public
List
<
Map
<
String
,
Object
>>
select
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
select
(
runtimeContext
);
}
@Comment
(
"执行selectOne查询"
)
public
Map
<
String
,
Object
>
selectOne
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
selectOne
(
runtimeContext
);
}
@Comment
(
"查询条数"
)
public
int
count
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
count
(
runtimeContext
);
}
@Comment
(
"查询是否存在"
)
public
boolean
exists
(
RuntimeContext
runtimeContext
)
{
return
namedTable
.
exists
(
runtimeContext
);
}
@Transient
public
void
appendAnd
()
{
remove
();
tokens
.
add
(
"and"
);
}
@Transient
public
void
appendOr
()
{
remove
();
tokens
.
add
(
"or"
);
}
List
<
Object
>
getParams
()
{
return
params
;
}
void
remove
()
{
int
size
=
tokens
.
size
();
while
(
size
>
0
)
{
String
token
=
tokens
.
get
(
size
-
1
);
if
(
"and"
.
equalsIgnoreCase
(
token
)
||
"or"
.
equalsIgnoreCase
(
token
))
{
tokens
.
remove
(
size
-
1
);
size
--;
}
else
{
break
;
}
}
while
(
size
>
0
)
{
String
token
=
tokens
.
get
(
0
);
if
(
"and"
.
equalsIgnoreCase
(
token
)
||
"or"
.
equalsIgnoreCase
(
token
))
{
tokens
.
remove
(
0
);
size
--;
}
else
{
break
;
}
}
}
boolean
isEmpty
()
{
return
tokens
.
isEmpty
();
}
@Transient
public
void
append
(
String
value
)
{
tokens
.
add
(
value
);
}
@Transient
public
void
append
(
String
sql
,
Object
value
)
{
tokens
.
add
(
sql
);
params
.
add
(
value
);
}
String
getSql
()
{
remove
();
if
(
isEmpty
())
{
return
""
;
}
return
(
needWhere
?
" where "
:
""
)
+
String
.
join
(
" "
,
tokens
);
}
boolean
filterNullAndBlank
(
Object
value
)
{
if
(
notNull
&&
value
==
null
)
{
return
false
;
}
return
!
notBlank
||
!
StringUtils
.
isEmpty
(
Objects
.
toString
(
value
,
""
));
}
private
Where
append
(
boolean
append
,
String
column
,
String
condition
,
Object
value
)
{
if
(
append
&&
filterNullAndBlank
(
value
))
{
append
(
namedTable
.
rowMapColumnMapper
.
apply
(
column
));
append
(
condition
);
appendAnd
();
params
.
add
(
value
);
}
return
this
;
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/http/HttpModule.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.http
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.http.*
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.web.client.RestTemplate
;
import
org.ssssssss.magicapi.core.annotation.MagicModule
;
import
org.ssssssss.script.annotation.Comment
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.stream.Collectors
;
/**
* http 模块
*
* @author mxd
* @since 1.1.0
*/
@MagicModule
(
"http"
)
public
class
HttpModule
{
private
final
RestTemplate
template
;
private
final
HttpHeaders
httpHeaders
=
new
HttpHeaders
();
private
Class
<?>
responseType
=
Object
.
class
;
private
final
MultiValueMap
<
String
,
Object
>
params
=
new
LinkedMultiValueMap
<>();
private
final
MultiValueMap
<
String
,
Object
>
data
=
new
LinkedMultiValueMap
<>();
private
final
Map
<
String
,
?>
variables
=
new
HashMap
<>();
private
String
url
;
private
HttpMethod
method
=
HttpMethod
.
GET
;
private
HttpEntity
<
Object
>
entity
=
null
;
private
Object
requestBody
;
public
HttpModule
(
RestTemplate
template
)
{
this
.
template
=
template
;
}
public
HttpModule
(
RestTemplate
template
,
String
url
)
{
this
.
template
=
template
;
this
.
url
=
url
;
}
@Comment
(
"创建连接"
)
public
HttpModule
connect
(
@Comment
(
name
=
"url"
,
value
=
"目标URL"
)
String
url
)
{
return
new
HttpModule
(
template
,
url
);
}
@Comment
(
"设置URL参数"
)
public
HttpModule
param
(
@Comment
(
name
=
"key"
,
value
=
"参数名"
)
String
key
,
@Comment
(
name
=
"values"
,
value
=
"参数值"
)
Object
...
values
)
{
if
(
values
!=
null
)
{
for
(
Object
value
:
values
)
{
this
.
params
.
add
(
key
,
value
);
}
}
return
this
;
}
@Comment
(
"批量设置URL参数"
)
public
HttpModule
param
(
@Comment
(
name
=
"values"
,
value
=
"参数值"
)
Map
<
String
,
Object
>
values
)
{
values
.
forEach
((
key
,
value
)
->
param
(
key
,
Objects
.
toString
(
value
,
""
)));
return
this
;
}
@Comment
(
"设置form参数"
)
public
HttpModule
data
(
@Comment
(
name
=
"key"
,
value
=
"参数名"
)
String
key
,
@Comment
(
name
=
"values"
,
value
=
"参数值"
)
Object
...
values
)
{
if
(
values
!=
null
)
{
for
(
Object
value
:
values
)
{
this
.
data
.
add
(
key
,
value
);
}
}
return
this
;
}
@Comment
(
"批量设置form参数"
)
public
HttpModule
data
(
@Comment
(
name
=
"values"
,
value
=
"参数值"
)
Map
<
String
,
Object
>
values
)
{
values
.
forEach
((
key
,
value
)
->
data
(
key
,
Objects
.
toString
(
value
,
""
)));
return
this
;
}
@Comment
(
"设置header"
)
public
HttpModule
header
(
@Comment
(
name
=
"key"
,
value
=
"header名"
)
String
key
,
@Comment
(
name
=
"value"
,
value
=
"header值"
)
String
value
)
{
httpHeaders
.
add
(
key
,
value
);
return
this
;
}
@Comment
(
"批量设置header"
)
public
HttpModule
header
(
@Comment
(
name
=
"values"
,
value
=
"header值"
)
Map
<
String
,
Object
>
values
)
{
values
.
entrySet
()
.
stream
()
.
filter
(
it
->
it
.
getValue
()
!=
null
)
.
forEach
(
entry
->
header
(
entry
.
getKey
(),
entry
.
getValue
().
toString
()));
return
this
;
}
@Comment
(
"设置请求方法,默认GET"
)
public
HttpModule
method
(
@Comment
(
name
=
"method"
,
value
=
"请求方法"
)
HttpMethod
method
)
{
this
.
method
=
method
;
return
this
;
}
@Comment
(
"设置`RequestBody`"
)
public
HttpModule
body
(
@Comment
(
name
=
"requestBody"
,
value
=
"`RequestBody`"
)
Object
requestBody
)
{
this
.
requestBody
=
requestBody
;
this
.
contentType
(
MediaType
.
APPLICATION_JSON
);
return
this
;
}
@Comment
(
"自定义`HttpEntity`"
)
public
HttpModule
entity
(
@Comment
(
name
=
"entity"
,
value
=
"`HttpEntity`"
)
HttpEntity
<
Object
>
entity
)
{
this
.
entity
=
entity
;
return
this
;
}
@Comment
(
"设置`ContentType`"
)
public
HttpModule
contentType
(
@Comment
(
name
=
"contentType"
,
value
=
"Content-Type值"
)
String
contentType
)
{
return
contentType
(
MediaType
.
parseMediaType
(
contentType
));
}
@Comment
(
"设置`ContentType`"
)
public
HttpModule
contentType
(
@Comment
(
name
=
"mediaType"
,
value
=
"Content-Type值"
)
MediaType
mediaType
)
{
this
.
httpHeaders
.
setContentType
(
mediaType
);
return
this
;
}
@Comment
(
"设置返回值为`byte[]`"
)
public
HttpModule
expectBytes
()
{
this
.
responseType
=
byte
[].
class
;
return
this
;
}
@Comment
(
"发送`POST`请求"
)
public
ResponseEntity
<?>
post
()
{
this
.
method
(
HttpMethod
.
POST
);
return
this
.
execute
();
}
@Comment
(
"发送`GET`请求"
)
public
ResponseEntity
<?>
get
()
{
this
.
method
(
HttpMethod
.
GET
);
return
this
.
execute
();
}
@Comment
(
"发送`PUT`请求"
)
public
ResponseEntity
<?>
put
()
{
this
.
method
(
HttpMethod
.
PUT
);
return
this
.
execute
();
}
@Comment
(
"发送`DELETE`请求"
)
public
ResponseEntity
<?>
delete
()
{
this
.
method
(
HttpMethod
.
DELETE
);
return
this
.
execute
();
}
@Comment
(
"发送`HEAD`请求"
)
public
ResponseEntity
<?>
head
()
{
this
.
method
(
HttpMethod
.
HEAD
);
return
this
.
execute
();
}
@Comment
(
"发送`OPTIONS`请求"
)
public
ResponseEntity
<?>
options
()
{
this
.
method
(
HttpMethod
.
OPTIONS
);
return
this
.
execute
();
}
@Comment
(
"发送`TRACE`请求"
)
public
ResponseEntity
<?>
trace
()
{
this
.
method
(
HttpMethod
.
TRACE
);
return
this
.
execute
();
}
@Comment
(
"发送`PATCH`请求"
)
public
ResponseEntity
<?>
patch
()
{
this
.
method
(
HttpMethod
.
PATCH
);
return
this
.
execute
();
}
@Comment
(
"执行请求"
)
public
ResponseEntity
<?>
execute
()
{
if
(!
this
.
params
.
isEmpty
())
{
String
queryString
=
this
.
params
.
entrySet
().
stream
()
.
map
(
it
->
it
.
getValue
().
stream
()
.
map
(
value
->
it
.
getKey
()
+
"="
+
value
)
.
collect
(
Collectors
.
joining
(
"&"
))
).
collect
(
Collectors
.
joining
(
"&"
));
if
(
StringUtils
.
isNotBlank
(
queryString
))
{
this
.
url
+=
(
this
.
url
.
contains
(
"?"
)
?
"&"
:
"?"
)
+
queryString
;
}
}
if
(!
this
.
data
.
isEmpty
())
{
this
.
entity
=
new
HttpEntity
<>(
this
.
data
,
this
.
httpHeaders
);
}
else
if
(
this
.
entity
==
null
&&
this
.
requestBody
!=
null
)
{
this
.
entity
=
new
HttpEntity
<>(
this
.
requestBody
,
this
.
httpHeaders
);
}
else
{
this
.
entity
=
new
HttpEntity
<>(
null
,
this
.
httpHeaders
);
}
return
template
.
exchange
(
url
,
this
.
method
,
entity
,
responseType
,
variables
);
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/RequestModule.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.servlet
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartRequest
;
import
org.ssssssss.magicapi.core.annotation.MagicModule
;
import
org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest
;
import
org.ssssssss.magicapi.core.servlet.MagicRequestContextHolder
;
import
org.ssssssss.magicapi.utils.IpUtils
;
import
org.ssssssss.script.annotation.Comment
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Enumeration
;
import
java.util.List
;
import
java.util.stream.Collectors
;
/**
* request 模块
*
* @author mxd
*/
@MagicModule
(
"request"
)
public
class
RequestModule
{
private
static
MagicRequestContextHolder
magicRequestContextHolder
;
public
RequestModule
(
MagicRequestContextHolder
magicRequestContextHolder
)
{
RequestModule
.
magicRequestContextHolder
=
magicRequestContextHolder
;
}
/**
* 获取文件信息
*
* @param name 参数名
*/
@Comment
(
"获取文件"
)
public
static
MultipartFile
getFile
(
@Comment
(
name
=
"name"
,
value
=
"参数名"
)
String
name
)
{
MultipartRequest
request
=
getMultipartHttpServletRequest
();
if
(
request
==
null
)
{
return
null
;
}
MultipartFile
file
=
request
.
getFile
(
name
);
return
file
==
null
||
file
.
isEmpty
()
?
null
:
file
;
}
/**
* 获取文件信息
*
* @param name 参数名
*/
@Comment
(
"获取多个文件"
)
public
static
List
<
MultipartFile
>
getFiles
(
@Comment
(
name
=
"name"
,
value
=
"参数名"
)
String
name
)
{
MultipartRequest
request
=
getMultipartHttpServletRequest
();
if
(
request
==
null
)
{
return
null
;
}
return
request
.
getFiles
(
name
).
stream
().
filter
(
it
->
!
it
.
isEmpty
()).
collect
(
Collectors
.
toList
());
}
/**
* 获取原生HttpServletRequest对象
*/
@Comment
(
"获取原生HttpServletRequest对象"
)
public
static
MagicHttpServletRequest
get
()
{
return
magicRequestContextHolder
.
getRequest
();
}
private
static
MultipartRequest
getMultipartHttpServletRequest
()
{
MagicHttpServletRequest
request
=
get
();
if
(
request
!=
null
&&
request
.
isMultipart
())
{
return
request
.
resolveMultipart
();
}
return
null
;
}
/**
* 根据参数名获取参数值集合
*
* @param name 参数名
*/
@Comment
(
"根据请求参数名获取值"
)
public
List
<
String
>
getValues
(
@Comment
(
name
=
"name"
,
value
=
"参数名"
)
String
name
)
{
MagicHttpServletRequest
request
=
get
();
if
(
request
!=
null
)
{
String
[]
values
=
request
.
getParameterValues
(
name
);
return
values
==
null
?
null
:
Arrays
.
asList
(
values
);
}
return
null
;
}
/**
* 根据header名获取header集合
*
* @param name 参数名
*/
@Comment
(
"根据header名获取值"
)
public
List
<
String
>
getHeaders
(
@Comment
(
name
=
"name"
,
value
=
"header名"
)
String
name
)
{
MagicHttpServletRequest
request
=
get
();
if
(
request
!=
null
)
{
Enumeration
<
String
>
headers
=
request
.
getHeaders
(
name
);
return
headers
==
null
?
null
:
Collections
.
list
(
headers
);
}
return
null
;
}
@Comment
(
"获取客户端IP"
)
public
String
getClientIP
(
String
...
otherHeaderNames
)
{
MagicHttpServletRequest
request
=
get
();
if
(
request
==
null
)
{
return
null
;
}
return
IpUtils
.
getRealIP
(
request
.
getRemoteAddr
(),
request:
:
getHeader
,
otherHeaderNames
);
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/servlet/ResponseModule.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.servlet
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.ResponseEntity
;
import
org.ssssssss.magicapi.core.annotation.MagicModule
;
import
org.ssssssss.magicapi.core.context.RequestContext
;
import
org.ssssssss.magicapi.core.interceptor.ResultProvider
;
import
org.ssssssss.magicapi.core.servlet.MagicHttpServletResponse
;
import
org.ssssssss.script.annotation.Comment
;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLEncoder
;
import
java.util.List
;
import
java.util.Map
;
/**
* response模块
*
* @author mxd
*/
@MagicModule
(
"response"
)
public
class
ResponseModule
{
private
final
ResultProvider
resultProvider
;
public
ResponseModule
(
ResultProvider
resultProvider
)
{
this
.
resultProvider
=
resultProvider
;
}
/**
* 文件下载
*
* @param value 文件内容
* @param filename 文件名
*/
@Comment
(
"文件下载"
)
public
static
ResponseEntity
<?>
download
(
@Comment
(
name
=
"value"
,
value
=
"文件内容,如`byte[]`"
)
Object
value
,
@Comment
(
name
=
"filename"
,
value
=
"文件名"
)
String
filename
)
throws
UnsupportedEncodingException
{
return
ResponseEntity
.
ok
().
contentType
(
MediaType
.
APPLICATION_OCTET_STREAM
)
.
header
(
HttpHeaders
.
CONTENT_DISPOSITION
,
"attachment; filename="
+
URLEncoder
.
encode
(
filename
,
"UTF-8"
))
.
body
(
value
);
}
/**
* 自行构建分页结果
*
* @param total 条数
* @param values 数据内容
*/
@Comment
(
"返回自定义分页结果"
)
public
Object
page
(
@Comment
(
name
=
"total"
,
value
=
"总条数"
)
long
total
,
@Comment
(
name
=
"values"
,
value
=
"当前结果集"
)
List
<
Map
<
String
,
Object
>>
values
)
{
return
resultProvider
.
buildPageResult
(
RequestContext
.
getRequestEntity
(),
null
,
total
,
values
);
}
/**
* 自定义json结果
*
* @param value json内容
*/
@Comment
(
"自定义返回json内容"
)
public
ResponseEntity
<
Object
>
json
(
@Comment
(
name
=
"value"
,
value
=
"返回对象"
)
Object
value
)
{
return
ResponseEntity
.
ok
(
value
);
}
/**
* 添加Header
*/
@Comment
(
"添加response header"
)
public
ResponseModule
addHeader
(
@Comment
(
name
=
"key"
,
value
=
"header名"
)
String
key
,
@Comment
(
name
=
"value"
,
value
=
"header值"
)
String
value
)
{
if
(
StringUtils
.
isNotBlank
(
key
))
{
MagicHttpServletResponse
response
=
getResponse
();
if
(
response
!=
null
)
{
response
.
addHeader
(
key
,
value
);
}
}
return
this
;
}
/**
* 设置header
*/
@Comment
(
"设置response header"
)
public
ResponseModule
setHeader
(
@Comment
(
name
=
"key"
,
value
=
"header名"
)
String
key
,
@Comment
(
name
=
"value"
,
value
=
"header值"
)
String
value
)
{
if
(
StringUtils
.
isNotBlank
(
key
))
{
MagicHttpServletResponse
response
=
getResponse
();
if
(
response
!=
null
)
{
response
.
setHeader
(
key
,
value
);
}
}
return
this
;
}
/**
* 获取OutputStream
*
* @since 1.2.3
*/
@Comment
(
"获取OutputStream"
)
public
OutputStream
getOutputStream
()
throws
IOException
{
MagicHttpServletResponse
response
=
getResponse
();
return
response
.
getOutputStream
();
}
@Comment
(
"终止输出,执行此方法后不会对结果进行任何输出及处理"
)
public
NullValue
end
()
{
return
NullValue
.
INSTANCE
;
}
private
MagicHttpServletResponse
getResponse
()
{
return
RequestContext
.
getHttpServletResponse
();
}
/**
* 展示图片
*
* @param value 图片内容
* @param mime 图片类型,image/png,image/jpeg,image/gif
*/
@Comment
(
"输出图片"
)
public
ResponseEntity
image
(
@Comment
(
name
=
"value"
,
value
=
"图片内容,如`byte[]`"
)
Object
value
,
@Comment
(
name
=
"mime"
,
value
=
"图片类型,如`image/png`、`image/jpeg`、`image/gif`"
)
String
mime
)
{
return
ResponseEntity
.
ok
().
header
(
HttpHeaders
.
CONTENT_TYPE
,
mime
).
body
(
value
);
}
/**
* 输出文本
*
* @param text 文本内容
*/
@Comment
(
"输出文本"
)
public
ResponseEntity
text
(
@Comment
(
name
=
"text"
,
value
=
"文本内容"
)
String
text
)
{
return
ResponseEntity
.
ok
().
header
(
HttpHeaders
.
CONTENT_TYPE
,
MediaType
.
TEXT_PLAIN_VALUE
).
body
(
text
);
}
/**
* 重定向
*
* @param url 目标网址
*/
@Comment
(
"重定向"
)
public
NullValue
redirect
(
@Comment
(
name
=
"url"
,
value
=
"目标网址"
)
String
url
)
throws
IOException
{
getResponse
().
sendRedirect
(
url
);
return
NullValue
.
INSTANCE
;
}
public
static
class
NullValue
{
static
final
NullValue
INSTANCE
=
new
NullValue
();
}
}
magic-api/src/main/java/org/ssssssss/magicapi/modules/spring/EnvModule.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.modules.spring
;
import
org.springframework.core.env.Environment
;
import
org.ssssssss.magicapi.core.annotation.MagicModule
;
import
org.ssssssss.script.annotation.Comment
;
/**
* env模块
*
* @author mxd
*/
@MagicModule
(
"env"
)
public
class
EnvModule
{
private
final
Environment
environment
;
@Comment
(
"获取配置"
)
public
String
get
(
@Comment
(
name
=
"key"
,
value
=
"配置项"
)
String
key
)
{
return
environment
.
getProperty
(
key
);
}
public
EnvModule
(
Environment
environment
)
{
this
.
environment
=
environment
;
}
@Comment
(
"获取配置"
)
public
String
get
(
@Comment
(
name
=
"key"
,
value
=
"配置项"
)
String
key
,
@Comment
(
name
=
"defaultValue"
,
value
=
"未配置时的默认值"
)
String
defaultValue
)
{
return
environment
.
getProperty
(
key
,
defaultValue
);
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/Assert.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.ssssssss.magicapi.core.exception.MagicAPIException
;
/**
* 断言辅助类
*
* @author mxd
*/
public
class
Assert
{
/**
* 断言值不能为空
*/
public
static
void
isNotNull
(
Object
value
,
String
message
)
{
if
(
value
==
null
)
{
throw
new
MagicAPIException
(
message
);
}
}
/**
* 验证值必须是true
*/
public
static
void
isTrue
(
boolean
value
,
String
message
)
{
if
(!
value
)
{
throw
new
MagicAPIException
(
message
);
}
}
/**
* 断言值不能为空字符串
*/
public
static
void
isNotBlank
(
String
value
,
String
message
)
{
if
(
StringUtils
.
isBlank
(
value
))
{
throw
new
MagicAPIException
(
message
);
}
}
/**
* 断言值不能为空字符串
*/
public
static
void
isNotBlanks
(
String
message
,
String
...
values
)
{
if
(
values
!=
null
)
{
for
(
String
value
:
values
)
{
isNotBlank
(
value
,
message
);
}
}
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/ClassScanner.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.support.PathMatchingResourcePatternResolver
;
import
org.springframework.core.io.support.ResourcePatternResolver
;
import
org.ssssssss.script.asm.ClassReader
;
import
org.ssssssss.script.functions.ObjectConvertExtension
;
import
java.io.Closeable
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.lang.reflect.Method
;
import
java.net.URISyntaxException
;
import
java.net.URL
;
import
java.net.URLClassLoader
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipInputStream
;
/**
* class 扫描器
*
* @author mxd
*/
public
class
ClassScanner
{
public
static
List
<
String
>
scan
()
throws
URISyntaxException
,
IOException
{
Set
<
String
>
classes
=
new
HashSet
<>();
if
(
Double
.
parseDouble
(
System
.
getProperty
(
"java.specification.version"
))
>=
11
)
{
classes
.
addAll
(
latestJdkScan
());
}
else
{
ClassLoader
loader
=
Thread
.
currentThread
().
getContextClassLoader
();
do
{
if
(
loader
instanceof
URLClassLoader
)
{
classes
.
addAll
(
scan
(((
URLClassLoader
)
loader
).
getURLs
()));
}
}
while
((
loader
=
loader
.
getParent
())
!=
null
);
}
ClassLoader
loader
=
Thread
.
currentThread
().
getContextClassLoader
();
do
{
if
(
loader
instanceof
URLClassLoader
)
{
classes
.
addAll
(
scan
(((
URLClassLoader
)
loader
).
getURLs
()));
}
}
while
((
loader
=
loader
.
getParent
())
!=
null
);
classes
.
addAll
(
addJavaLibrary
());
return
new
ArrayList
<>(
classes
);
}
public
static
List
<
String
>
latestJdkScan
()
throws
IOException
{
ResourcePatternResolver
resourcePatternResolver
=
new
PathMatchingResourcePatternResolver
();
Resource
[]
resources
=
resourcePatternResolver
.
getResources
(
"classpath*:**/**.class"
);
return
Arrays
.
asList
(
resources
).
parallelStream
().
map
(
it
->
{
try
{
if
(
isClass
(
it
.
getURL
().
getPath
()))
{
if
(
"\"classes\""
.
contains
(
it
.
getURL
().
getPath
()))
{
return
it
.
getURL
().
getPath
().
split
(
"classes"
)[
1
].
substring
(
1
).
replace
(
".class"
,
""
).
replaceAll
(
"\\/"
,
"."
);
}
else
if
(
it
.
getURL
().
getPath
().
split
(
"!"
).
length
>
1
)
{
return
it
.
getURL
().
getPath
().
split
(
"!"
)[
1
].
substring
(
1
).
replace
(
".class"
,
""
).
replaceAll
(
"\\/"
,
"."
);
}
else
{
try
(
InputStream
stream
=
it
.
getInputStream
())
{
return
new
ClassReader
(
stream
).
getClassName
().
replace
(
"/"
,
"."
);
}
catch
(
Exception
e
)
{
return
null
;
}
}
}
}
catch
(
Exception
e
)
{
return
null
;
}
return
null
;
}).
filter
(
Objects:
:
nonNull
).
distinct
().
sorted
(
Comparator
.
comparing
(
Objects:
:
toString
)).
collect
(
Collectors
.
toList
());
}
public
static
String
compress
(
List
<
String
>
classes
)
{
Collections
.
sort
(
classes
);
String
currentPackage
=
""
;
StringBuffer
buf
=
new
StringBuffer
();
int
classCount
=
0
;
for
(
String
fullName
:
classes
)
{
String
packageName
=
""
;
String
className
=
fullName
;
if
(
fullName
.
contains
(
"."
))
{
int
index
=
fullName
.
lastIndexOf
(
"."
);
className
=
fullName
.
substring
(
index
+
1
);
packageName
=
fullName
.
substring
(
0
,
index
);
}
if
(
className
.
equals
(
"package-info"
))
{
continue
;
}
if
(
currentPackage
.
equals
(
packageName
))
{
if
(
classCount
>
0
)
{
buf
.
append
(
","
);
}
buf
.
append
(
className
);
classCount
++;
}
else
{
currentPackage
=
packageName
;
if
(
buf
.
length
()
>
0
)
{
buf
.
append
(
"\n"
);
}
buf
.
append
(
packageName
);
buf
.
append
(
":"
);
buf
.
append
(
className
);
classCount
=
1
;
}
}
return
buf
.
toString
();
}
private
static
Set
<
String
>
scan
(
URL
[]
urls
)
throws
URISyntaxException
{
Set
<
String
>
classes
=
new
HashSet
<>();
if
(
urls
!=
null
)
{
for
(
URL
url
:
urls
)
{
String
protocol
=
url
.
getProtocol
();
if
(
"file"
.
equalsIgnoreCase
(
protocol
))
{
String
path
=
url
.
getPath
();
if
(
path
.
toLowerCase
().
endsWith
(
".jar"
))
{
classes
.
addAll
(
scanJarFile
(
url
));
}
else
{
classes
.
addAll
(
scanDirectory
(
new
File
(
url
.
toURI
()),
null
));
}
}
else
if
(
"jar"
.
equalsIgnoreCase
(
protocol
))
{
classes
.
addAll
(
scanJarFile
(
url
));
}
}
}
return
classes
;
}
private
static
Set
<
String
>
addJavaLibrary
()
{
int
version
=
checkJavaVersion
();
if
(
version
>=
9
)
{
return
addJava9PlusLibrary
();
}
return
addJava8Library
();
}
private
static
int
checkJavaVersion
()
{
String
version
=
System
.
getProperty
(
"java.version"
);
int
index
=
version
.
indexOf
(
"."
);
if
(
index
>
-
1
)
{
String
first
=
version
.
substring
(
0
,
index
);
if
(!
"1"
.
equals
(
first
))
{
return
ObjectConvertExtension
.
asInt
(
first
,
-
1
);
}
else
{
int
endIndex
=
version
.
indexOf
(
"."
,
index
+
1
);
return
ObjectConvertExtension
.
asInt
(
version
.
substring
(
index
+
1
,
endIndex
),
-
1
);
}
}
return
-
1
;
}
/**
* jdk 8
*/
private
static
Set
<
String
>
addJava8Library
()
{
try
{
// 直接反射调用..
Object
classpath
=
Class
.
forName
(
"sun.misc.Launcher"
).
getMethod
(
"getBootstrapClassPath"
).
invoke
(
null
);
return
scan
((
URL
[])
classpath
.
getClass
().
getMethod
(
"getURLs"
).
invoke
(
classpath
));
}
catch
(
Exception
ignored
)
{
}
return
Collections
.
emptySet
();
}
/**
* jdk 9+
*/
private
static
Set
<
String
>
addJava9PlusLibrary
()
{
Set
<
String
>
classes
=
new
HashSet
<>();
try
{
Class
<?>
moduleLayer
=
Class
.
forName
(
"java.lang.ModuleLayer"
);
Object
boot
=
moduleLayer
.
getMethod
(
"boot"
).
invoke
(
null
);
Object
configuration
=
moduleLayer
.
getMethod
(
"configuration"
).
invoke
(
boot
);
//Set<ResolvedModule>
Set
<?>
modules
=
(
Set
<?>)
Class
.
forName
(
"java.lang.module.Configuration"
).
getMethod
(
"modules"
).
invoke
(
configuration
);
Method
reference
=
Class
.
forName
(
"java.lang.module.ResolvedModule"
).
getMethod
(
"reference"
);
Method
open
=
Class
.
forName
(
"java.lang.module.ModuleReference"
).
getMethod
(
"open"
);
Method
list
=
Class
.
forName
(
"java.lang.module.ModuleReader"
).
getMethod
(
"list"
);
modules
.
forEach
(
module
->
{
});
for
(
Object
module
:
modules
)
{
Object
ref
=
reference
.
invoke
(
module
);
try
(
Closeable
reader
=
(
Closeable
)
open
.
invoke
(
ref
))
{
@SuppressWarnings
(
"unchecked"
)
Stream
<
String
>
stream
=
(
Stream
<
String
>)
list
.
invoke
(
reader
);
stream
.
filter
(
ClassScanner:
:
isClass
).
forEach
(
className
->
classes
.
add
(
className
.
substring
(
0
,
className
.
length
()
-
6
).
replace
(
"/"
,
"."
)));
}
catch
(
IOException
ignored
)
{
}
}
}
catch
(
Exception
ignored
)
{
}
return
classes
;
}
private
static
List
<
String
>
scanDirectory
(
File
dir
,
String
packageName
)
{
File
[]
files
=
dir
.
listFiles
();
List
<
String
>
classes
=
new
ArrayList
<>();
if
(
files
!=
null
)
{
for
(
File
file
:
files
)
{
String
name
=
file
.
getName
();
if
(
file
.
isDirectory
())
{
classes
.
addAll
(
scanDirectory
(
file
,
packageName
==
null
?
name
:
packageName
+
"."
+
name
));
}
else
if
(
name
.
endsWith
(
".class"
)
&&
!
name
.
contains
(
"$"
))
{
classes
.
add
(
filterFullName
(
packageName
+
"."
+
name
.
substring
(
0
,
name
.
length
()
-
6
)));
}
}
}
return
classes
;
}
private
static
String
filterFullName
(
String
fullName
)
{
if
(
fullName
.
startsWith
(
"BOOT-INF.classes."
))
{
fullName
=
fullName
.
substring
(
17
);
}
return
fullName
;
}
private
static
List
<
String
>
scanJarFile
(
URL
url
)
{
List
<
String
>
classes
=
new
ArrayList
<>();
try
(
ZipInputStream
zis
=
new
ZipInputStream
(
url
.
openStream
()))
{
ZipEntry
entry
;
while
((
entry
=
zis
.
getNextEntry
())
!=
null
)
{
if
(!
entry
.
getName
().
contains
(
"META-INF"
))
{
String
className
=
entry
.
getName
();
if
(
isClass
(
className
))
{
classes
.
add
(
filterFullName
(
className
.
substring
(
0
,
className
.
length
()
-
6
).
replace
(
"/"
,
"."
)));
}
}
}
}
catch
(
IOException
ignored
)
{
}
return
classes
;
}
private
static
boolean
isClass
(
String
className
)
{
return
className
.
endsWith
(
".class"
)
&&
!
className
.
contains
(
"$"
)
&&
!
className
.
contains
(
"module-info"
);
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/IoUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
javax.sql.DataSource
;
import
java.io.*
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Files
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.regex.Pattern
;
import
java.nio.charset.StandardCharsets
;
/**
* IO工具包
*
* @author mxd
*/
public
class
IoUtils
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
IoUtils
.
class
);
private
static
final
Pattern
FILE_NAME_PATTERN
=
Pattern
.
compile
(
"^(?!\\.)[\\u4e00-\\u9fa5_a-zA-Z0-9.\\-()]+$"
);
public
static
boolean
validateFileName
(
String
name
)
{
return
FILE_NAME_PATTERN
.
matcher
(
name
).
matches
();
}
public
static
List
<
File
>
files
(
File
file
,
String
suffix
)
{
List
<
File
>
list
=
new
ArrayList
<>();
if
(
file
.
isDirectory
())
{
File
[]
files
=
file
.
listFiles
((
path
)
->
path
.
isDirectory
()
||
path
.
getName
().
endsWith
(
suffix
));
if
(
files
!=
null
)
{
for
(
int
i
=
files
.
length
-
1
;
i
>=
0
;
i
--)
{
list
.
addAll
(
files
(
files
[
i
],
suffix
));
}
}
}
else
if
(
file
.
exists
())
{
list
.
add
(
file
);
}
return
list
;
}
public
static
List
<
File
>
dirs
(
File
file
)
{
return
subDirs
(
true
,
file
);
}
private
static
List
<
File
>
subDirs
(
boolean
isRoot
,
File
file
)
{
List
<
File
>
list
=
new
ArrayList
<>();
if
(
file
.
isDirectory
())
{
File
[]
files
=
file
.
listFiles
(
File:
:
isDirectory
);
if
(
files
!=
null
)
{
for
(
int
i
=
files
.
length
-
1
;
i
>=
0
;
i
--)
{
list
.
addAll
(
subDirs
(
false
,
files
[
i
]));
}
}
if
(!
isRoot
)
{
list
.
add
(
file
);
}
}
return
list
;
}
public
static
byte
[]
bytes
(
File
file
)
{
try
{
return
Files
.
readAllBytes
(
file
.
toPath
());
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取文件失败"
,
e
);
return
new
byte
[
0
];
}
}
public
static
String
string
(
File
file
)
{
return
new
String
(
bytes
(
file
),
StandardCharsets
.
UTF_8
);
}
public
static
byte
[]
bytes
(
InputStream
inputStream
)
{
try
{
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream
();
byte
[]
buf
=
new
byte
[
4096
];
int
len
;
while
((
len
=
inputStream
.
read
(
buf
,
0
,
buf
.
length
))
!=
-
1
)
{
baos
.
write
(
buf
,
0
,
len
);
}
return
baos
.
toByteArray
();
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取InputStream失败"
,
e
);
return
new
byte
[
0
];
}
}
public
static
String
string
(
InputStream
inputStream
)
{
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
inputStream
)))
{
StringBuilder
result
=
new
StringBuilder
();
String
line
;
boolean
flag
=
false
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
if
(
flag
)
{
result
.
append
(
"\r\n"
);
}
result
.
append
(
line
);
flag
=
true
;
}
return
result
.
toString
();
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取InputStream失败"
,
e
);
return
""
;
}
}
public
static
boolean
write
(
File
file
,
byte
[]
bytes
)
{
try
{
Files
.
write
(
file
.
toPath
(),
bytes
);
return
true
;
}
catch
(
IOException
e
)
{
logger
.
error
(
"写文件失败"
,
e
);
return
false
;
}
}
public
static
boolean
write
(
File
file
,
String
content
)
{
if
(
content
==
null
)
{
return
false
;
}
return
write
(
file
,
content
.
getBytes
(
StandardCharsets
.
UTF_8
));
}
public
static
boolean
delete
(
File
file
)
{
if
(
file
==
null
)
{
return
true
;
}
if
(
file
.
isDirectory
())
{
File
[]
files
=
file
.
listFiles
();
if
(
files
!=
null
)
{
for
(
int
i
=
files
.
length
-
1
;
i
>=
0
;
i
--)
{
if
(!
delete
(
files
[
i
]))
{
return
false
;
}
}
}
}
if
(!
file
.
exists
())
{
return
true
;
}
return
file
.
delete
();
}
public
static
void
closeDataSource
(
DataSource
dataSource
)
{
if
(
dataSource
!=
null
)
{
if
(
dataSource
instanceof
Closeable
)
{
try
{
((
Closeable
)
dataSource
).
close
();
}
catch
(
Exception
e
)
{
logger
.
warn
(
"Close DataSource error"
,
e
);
}
}
else
{
logger
.
warn
(
"DataSource can not close"
);
}
}
}
public
static
void
close
(
Closeable
closeable
){
try
{
if
(
closeable
!=
null
){
closeable
.
close
();
}
}
catch
(
IOException
ignored
)
{
}
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/IpUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.apache.commons.lang3.StringUtils
;
import
java.util.List
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
import
java.util.stream.Stream
;
public
class
IpUtils
{
private
static
final
String
[]
DEFAULT_IP_HEADER
=
new
String
[]{
"X-Forwarded-For"
,
"X-Real-IP"
,
"Proxy-Client-IP"
,
"WL-Proxy-Client-IP"
,
"HTTP_CLIENT_IP"
,
"HTTP_X_FORWARDED_FOR"
};
public
static
String
getRealIP
(
String
remoteAddr
,
Function
<
String
,
String
>
getHeader
,
String
...
otherHeaderNames
)
{
String
ip
=
null
;
List
<
String
>
headers
=
Stream
.
concat
(
Stream
.
of
(
DEFAULT_IP_HEADER
),
Stream
.
of
(
otherHeaderNames
==
null
?
new
String
[
0
]
:
otherHeaderNames
)).
collect
(
Collectors
.
toList
());
for
(
String
header
:
headers
)
{
if
((
ip
=
processIp
(
getHeader
.
apply
(
header
)))
!=
null
)
{
break
;
}
}
return
ip
==
null
?
processIp
(
remoteAddr
)
:
ip
;
}
private
static
String
processIp
(
String
ip
)
{
if
(
ip
!=
null
)
{
ip
=
ip
.
trim
();
if
(
isUnknown
(
ip
))
{
return
null
;
}
if
(
ip
.
contains
(
","
))
{
String
[]
ips
=
ip
.
split
(
","
);
for
(
String
subIp
:
ips
)
{
ip
=
processIp
(
subIp
);
if
(
ip
!=
null
)
{
return
ip
;
}
}
}
return
ip
;
}
return
null
;
}
private
static
boolean
isUnknown
(
String
ip
)
{
return
StringUtils
.
isBlank
(
ip
)
||
"unknown"
.
equalsIgnoreCase
(
ip
.
trim
());
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/JdbcUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.boot.jdbc.DatabaseDriver
;
import
org.ssssssss.magicapi.core.exception.MagicAPIException
;
import
java.sql.Connection
;
import
java.sql.DriverManager
;
import
java.sql.SQLException
;
public
class
JdbcUtils
{
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
JdbcUtils
.
class
);
public
static
Connection
getConnection
(
String
driver
,
String
url
,
String
username
,
String
password
)
{
try
{
if
(
StringUtils
.
isBlank
(
driver
))
{
driver
=
DatabaseDriver
.
fromJdbcUrl
(
url
).
getDriverClassName
();
if
(
StringUtils
.
isBlank
(
driver
))
{
throw
new
MagicAPIException
(
"无法从url中获得驱动类"
);
}
}
Class
.
forName
(
driver
);
}
catch
(
ClassNotFoundException
e
)
{
throw
new
MagicAPIException
(
"找不到驱动:"
+
driver
);
}
try
{
return
DriverManager
.
getConnection
(
url
,
username
,
password
);
}
catch
(
SQLException
e
)
{
logger
.
error
(
"获取Jdbc链接失败"
,
e
);
throw
new
MagicAPIException
(
"获取Jdbc链接失败:"
+
e
.
getMessage
());
}
}
public
static
void
close
(
Connection
connection
)
{
try
{
connection
.
close
();
}
catch
(
Exception
ignored
)
{
}
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/JsonUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
com.fasterxml.jackson.core.JsonGenerator
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.core.type.TypeReference
;
import
com.fasterxml.jackson.databind.*
;
import
com.fasterxml.jackson.databind.module.SimpleModule
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.io.IOException
;
import
java.nio.charset.StandardCharsets
;
/**
* JSON工具包
*
* @author mxd
*/
public
class
JsonUtils
{
private
static
final
ObjectMapper
MAPPER
=
new
ObjectMapper
();
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
JsonUtils
.
class
);
static
{
MAPPER
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
MAPPER
.
disable
(
SerializationFeature
.
FAIL_ON_EMPTY_BEANS
);
SimpleModule
simpleModule
=
new
SimpleModule
();
simpleModule
.
addSerializer
(
Logger
.
class
,
new
JsonSerializer
<
Logger
>()
{
@Override
public
void
serialize
(
Logger
value
,
JsonGenerator
gen
,
SerializerProvider
serializers
)
throws
IOException
{
gen
.
writeString
(
value
.
toString
());
}
});
MAPPER
.
registerModule
(
simpleModule
);
}
public
static
String
toJsonString
(
Object
target
)
{
try
{
return
MAPPER
.
writerWithDefaultPrettyPrinter
().
writeValueAsString
(
target
);
}
catch
(
JsonProcessingException
e
)
{
logger
.
error
(
"json序列化失败"
,
e
);
return
null
;
}
}
public
static
String
toJsonStringWithoutPretty
(
Object
target
)
{
try
{
return
MAPPER
.
writeValueAsString
(
target
);
}
catch
(
JsonProcessingException
e
)
{
logger
.
error
(
"json序列化失败"
,
e
);
return
null
;
}
}
public
static
String
toJsonStringWithoutLog
(
Object
target
)
{
try
{
return
MAPPER
.
writeValueAsString
(
target
);
}
catch
(
Exception
e
)
{
return
target
==
null
?
null
:
target
.
toString
();
}
}
public
static
<
T
>
T
readValue
(
String
json
,
TypeReference
<
T
>
typeReference
)
{
try
{
return
MAPPER
.
readValue
(
json
,
typeReference
);
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取json失败,json:{}"
,
json
,
e
);
return
null
;
}
}
public
static
<
T
>
T
readValue
(
String
json
,
Class
<
T
>
clazz
)
{
try
{
return
MAPPER
.
readValue
(
json
,
clazz
);
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取json失败,json:{}"
,
json
,
e
);
return
null
;
}
}
public
static
<
T
>
T
readValue
(
byte
[]
bytes
,
Class
<
T
>
clazz
)
{
try
{
return
MAPPER
.
readValue
(
bytes
,
clazz
);
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取json失败,json:{}"
,
new
String
(
bytes
),
e
);
return
null
;
}
}
public
static
<
T
>
T
readValue
(
byte
[]
bytes
,
JavaType
javaType
)
{
try
{
return
MAPPER
.
readValue
(
bytes
,
javaType
);
}
catch
(
IOException
e
)
{
logger
.
error
(
"读取json失败,json:{}"
,
new
String
(
bytes
),
e
);
return
null
;
}
}
public
static
byte
[]
toJsonBytes
(
Object
target
)
{
String
json
=
toJsonString
(
target
);
return
json
==
null
?
new
byte
[
0
]
:
json
.
getBytes
(
StandardCharsets
.
UTF_8
);
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/MD5Utils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.ssssssss.magicapi.core.exception.MagicAPIException
;
import
java.security.MessageDigest
;
/**
* MD5加密类
*
* @author mxd
*/
public
class
MD5Utils
{
private
static
final
char
[]
HEX_CHARS
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
};
/**
* MD5加密
*/
public
static
String
encrypt
(
String
value
)
{
return
encrypt
(
value
.
getBytes
());
}
/**
* MD5加密
*/
public
static
String
encrypt
(
byte
[]
value
)
{
try
{
byte
[]
bytes
=
MessageDigest
.
getInstance
(
"MD5"
).
digest
(
value
);
char
[]
chars
=
new
char
[
32
];
for
(
int
i
=
0
;
i
<
chars
.
length
;
i
=
i
+
2
)
{
byte
b
=
bytes
[
i
/
2
];
chars
[
i
]
=
HEX_CHARS
[(
b
>>>
0x4
)
&
0xf
];
chars
[
i
+
1
]
=
HEX_CHARS
[
b
&
0xf
];
}
return
new
String
(
chars
);
}
catch
(
Exception
e
)
{
throw
new
MagicAPIException
(
"md5 encrypt error"
,
e
);
}
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/Mapping.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.core.annotation.AnnotatedElementUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.method.HandlerMethod
;
import
org.springframework.web.servlet.handler.AbstractHandlerMethodMapping
;
import
org.springframework.web.servlet.mvc.method.RequestMappingInfo
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
;
import
org.ssssssss.script.reflection.JavaReflection
;
import
java.lang.reflect.Method
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.stream.Stream
;
public
class
Mapping
{
private
final
AbstractHandlerMethodMapping
<
RequestMappingInfo
>
methodMapping
;
private
final
String
base
;
private
final
RequestMappingInfo
.
BuilderConfiguration
config
;
private
static
final
boolean
HAS_GET_PATTERN_PARSER
=
JavaReflection
.
getMethod
(
RequestMappingHandlerMapping
.
class
,
"getPatternParser"
)
!=
null
;
private
Mapping
(
AbstractHandlerMethodMapping
<
RequestMappingInfo
>
methodMapping
,
RequestMappingInfo
.
BuilderConfiguration
config
,
String
base
)
{
this
.
methodMapping
=
methodMapping
;
this
.
config
=
config
;
this
.
base
=
StringUtils
.
defaultIfBlank
(
base
,
""
);
}
public
static
Mapping
create
(
RequestMappingHandlerMapping
mapping
)
{
return
create
(
mapping
,
null
);
}
public
static
Mapping
create
(
RequestMappingHandlerMapping
mapping
,
String
base
)
{
if
(
HAS_GET_PATTERN_PARSER
)
{
RequestMappingInfo
.
BuilderConfiguration
config
=
new
RequestMappingInfo
.
BuilderConfiguration
();
config
.
setTrailingSlashMatch
(
mapping
.
useTrailingSlashMatch
());
config
.
setContentNegotiationManager
(
mapping
.
getContentNegotiationManager
());
if
(
mapping
.
getPatternParser
()
!=
null
)
{
config
.
setPatternParser
(
mapping
.
getPatternParser
());
}
else
{
config
.
setPathMatcher
(
mapping
.
getPathMatcher
());
}
return
new
Mapping
(
mapping
,
config
,
base
);
}
return
new
Mapping
(
mapping
,
null
,
base
);
}
public
RequestMappingInfo
.
Builder
paths
(
String
...
paths
){
RequestMappingInfo
.
Builder
builder
=
RequestMappingInfo
.
paths
(
paths
);
if
(
this
.
config
!=
null
){
return
builder
.
options
(
this
.
config
);
}
return
builder
;
}
public
Mapping
register
(
RequestMappingInfo
requestMappingInfo
,
Object
handler
,
Method
method
)
{
this
.
methodMapping
.
registerMapping
(
requestMappingInfo
,
handler
,
method
);
return
this
;
}
public
RequestMappingInfo
register
(
String
requestMethod
,
String
path
,
Object
handler
,
Method
method
)
{
RequestMappingInfo
info
=
paths
(
path
).
methods
(
RequestMethod
.
valueOf
(
requestMethod
.
toUpperCase
())).
build
();
register
(
info
,
handler
,
method
);
return
info
;
}
public
Map
<
RequestMappingInfo
,
HandlerMethod
>
getHandlerMethods
()
{
return
this
.
methodMapping
.
getHandlerMethods
();
}
public
Mapping
unregister
(
RequestMappingInfo
info
)
{
this
.
methodMapping
.
unregisterMapping
(
info
);
return
this
;
}
public
Mapping
registerController
(
Object
target
)
{
Method
[]
methods
=
target
.
getClass
().
getDeclaredMethods
();
for
(
Method
method
:
methods
)
{
RequestMapping
requestMapping
=
AnnotatedElementUtils
.
findMergedAnnotation
(
method
,
RequestMapping
.
class
);
if
(
requestMapping
!=
null
)
{
String
[]
paths
=
Stream
.
of
(
requestMapping
.
value
()).
map
(
value
->
PathUtils
.
replaceSlash
(
base
+
value
)).
toArray
(
String
[]::
new
);
this
.
register
(
paths
(
paths
).
build
(),
target
,
method
);
}
}
return
this
;
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/PathUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
java.util.regex.Pattern
;
/**
* 路径处理工具包
*
* @author mxd
*/
public
class
PathUtils
{
private
static
final
Pattern
REPLACE_SLASH_REGX
=
Pattern
.
compile
(
"/+"
);
/**
* 将多个/替换为一个/
*/
public
static
String
replaceSlash
(
String
path
)
{
return
REPLACE_SLASH_REGX
.
matcher
(
path
).
replaceAll
(
"/"
);
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/PatternUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.regex.Pattern
;
/**
* 正则相关工具包
*
* @author mxd
*/
public
class
PatternUtils
{
private
static
final
Map
<
String
,
Pattern
>
CACHED_PATTERNS
=
new
ConcurrentHashMap
<>();
public
static
boolean
match
(
String
content
,
String
regex
)
{
Pattern
pattern
=
CACHED_PATTERNS
.
get
(
regex
);
if
(
pattern
==
null
)
{
pattern
=
Pattern
.
compile
(
regex
);
CACHED_PATTERNS
.
put
(
regex
,
pattern
);
}
return
pattern
.
matcher
(
content
).
find
();
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/ScriptManager.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
import
org.ssssssss.script.MagicScript
;
import
org.ssssssss.script.MagicScriptContext
;
import
org.ssssssss.script.MagicScriptDebugContext
;
import
java.util.Map
;
/**
* 脚本管理
*
* @author mxd
*/
public
class
ScriptManager
{
private
static
final
String
EXPRESSION_PREFIX
=
"/* generated by execute expression */ return "
;
/**
* 执行脚本
*/
public
static
Object
executeScript
(
String
script
,
MagicScriptContext
context
)
{
script
=
(
context
instanceof
MagicScriptDebugContext
?
MagicScript
.
DEBUG_MARK
:
""
)
+
script
;
MagicScript
magicScript
=
MagicScript
.
create
(
script
,
null
);
// 执行脚本
return
magicScript
.
execute
(
context
);
}
/**
* 执行脚本
*/
public
static
Object
executeExpression
(
String
script
,
MagicScriptContext
context
)
{
return
executeScript
(
EXPRESSION_PREFIX
+
script
,
context
);
}
/**
* 执行脚本
*/
public
static
Object
executeExpression
(
String
script
,
Map
<
String
,
Object
>
paramMap
)
{
return
executeExpression
(
script
,
new
MagicScriptContext
(
paramMap
));
}
}
magic-api/src/main/java/org/ssssssss/magicapi/utils/SignUtils.java
0 → 100644
View file @
02897568
package
org.ssssssss.magicapi.utils
;
/**
* 签名工具类
*
* @author mxd
*/
public
class
SignUtils
{
public
static
String
sign
(
Long
timestamp
,
String
secretKey
,
String
mode
,
byte
[]
bytes
)
{
return
MD5Utils
.
encrypt
(
String
.
format
(
"%s|%s|%s|%s"
,
timestamp
,
mode
,
MD5Utils
.
encrypt
(
bytes
),
secretKey
));
}
}
Prev
1
…
11
12
13
14
15
16
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