Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wecloud_im_server
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
hewei
wecloud_im_server
Commits
a7892caa
Commit
a7892caa
authored
Jan 26, 2022
by
lixiaozhong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加actionMapping,将websocket的服务写法模仿springmvc。
parent
49239792
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
52 changed files
with
2669 additions
and
6 deletions
+2669
-6
config/src/main/resources/config/application-dev.yml
+8
-6
config/src/main/resources/config/application.yml
+3
-0
core/src/main/java/com/wecloud/dispatch/ActionContext.java
+97
-0
core/src/main/java/com/wecloud/dispatch/ActionDispatcher.java
+305
-0
core/src/main/java/com/wecloud/dispatch/WsTestAction.java
+50
-0
core/src/main/java/com/wecloud/dispatch/annotation/ActionMapping.java
+26
-0
core/src/main/java/com/wecloud/dispatch/common/ActionMethod.java
+67
-0
core/src/main/java/com/wecloud/dispatch/common/ApplyInfo.java
+28
-0
core/src/main/java/com/wecloud/dispatch/common/RequestVO.java
+40
-0
core/src/main/java/com/wecloud/dispatch/config/ActionConfigurer.java
+16
-0
core/src/main/java/com/wecloud/dispatch/exception/ActionNotFoundException.java
+17
-0
core/src/main/java/com/wecloud/dispatch/exception/MappingException.java
+17
-0
core/src/main/java/com/wecloud/dispatch/extend/ActionBox.java
+21
-0
core/src/main/java/com/wecloud/dispatch/extend/ActionInterceptor.java
+21
-0
core/src/main/java/com/wecloud/dispatch/extend/ActionMessage.java
+17
-0
core/src/main/java/com/wecloud/dispatch/extend/ActionMethodInterceptor.java
+29
-0
core/src/main/java/com/wecloud/dispatch/extend/ActionRequest.java
+18
-0
core/src/main/java/com/wecloud/dispatch/extend/ActionResponse.java
+9
-0
core/src/main/java/com/wecloud/dispatch/extend/ArgumentBox.java
+15
-0
core/src/main/java/com/wecloud/dispatch/extend/ArgumentDefaultValueBuilder.java
+16
-0
core/src/main/java/com/wecloud/dispatch/extend/MethodArgumentResolver.java
+31
-0
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultActionBox.java
+41
-0
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultActionMessage.java
+42
-0
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultArgumentBox.java
+31
-0
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultArgumentDefaultValueBuilder.java
+84
-0
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultMethodArgumentResolver.java
+60
-0
core/src/main/java/com/wecloud/dispatch/factory/AbstractFactory.java
+107
-0
core/src/main/java/com/wecloud/dispatch/factory/ObjectFactory.java
+74
-0
core/src/main/java/com/wecloud/dispatch/general/GeneralMessageHandler.java
+54
-0
core/src/main/java/com/wecloud/dispatch/general/config/DispatcherConfig.java
+46
-0
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionConfigurerAdapter.java
+15
-0
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionDefaultConfigurer.java
+17
-0
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionDispatcher.java
+56
-0
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionDispatcherProperties.java
+0
-0
core/src/main/java/com/wecloud/dispatch/general/extend/ActionMessageResolver.java
+21
-0
core/src/main/java/com/wecloud/dispatch/general/extend/impl/ActionMessageResolverImpl.java
+33
-0
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralActionBox.java
+37
-0
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralActionInterceptor.java
+22
-0
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralActionMethodValidInterceptor.java
+124
-0
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralMethodArgumentResolver.java
+213
-0
core/src/main/java/com/wecloud/dispatch/registry/ActionBoxRegistry.java
+29
-0
core/src/main/java/com/wecloud/dispatch/registry/ActionInterceptorRegistry.java
+22
-0
core/src/main/java/com/wecloud/dispatch/registry/ActionMethodInterceptorRegistry.java
+22
-0
core/src/main/java/com/wecloud/dispatch/registry/ActionRegistry.java
+317
-0
core/src/main/java/com/wecloud/dispatch/registry/ArgumentDefaultValueBuilderRegistry.java
+33
-0
core/src/main/java/com/wecloud/dispatch/registry/MethodArgumentResolverRegistry.java
+45
-0
core/src/main/java/com/wecloud/dispatch/util/ClassScaner.java
+167
-0
core/src/main/java/com/wecloud/dispatch/util/ClassUtil.java
+32
-0
core/src/main/java/com/wecloud/im/netty/core/WsReadHandler.java
+6
-0
core/src/main/java/com/wecloud/im/ws/ImConstant.java
+2
-0
core/src/main/java/com/wecloud/im/ws/sender/ChannelSender.java
+14
-0
core/src/main/java/com/wecloud/utils/JsonUtils.java
+52
-0
No files found.
config/src/main/resources/config/application-dev.yml
View file @
a7892caa
...
...
@@ -15,9 +15,9 @@ spring-boot-plus:
spring
:
datasource
:
url
:
jdbc:mysql://
localhost:3306/wecloud_
im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username
:
root
password
:
123
url
:
jdbc:mysql://
192.168.1.51:3306/wecloud-
im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username
:
mysql
password
:
mysql
#//测试外网
# url: jdbc:mysql://18.136.207.16:3306/wecloud_im?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
...
...
@@ -27,14 +27,14 @@ spring:
# Redis配置
redis
:
database
:
0
host
:
localhost
host
:
192.168.1.51
password
:
port
:
6379
cloud
:
nacos
:
discovery
:
server-addr
:
localhost
:8848
server-addr
:
192.168.1.51
:8848
dubbo
:
...
...
@@ -42,7 +42,9 @@ dubbo:
port
:
20881
name
:
dubbo
registry
:
address
:
nacos://localhost:8848?username=nacos&password=nacos
address
:
nacos://192.168.1.51:8848?username=nacos&password=nacos
provider
:
cluster
:
channelRouterCluster
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus
:
...
...
config/src/main/resources/config/application.yml
View file @
a7892caa
...
...
@@ -396,3 +396,6 @@ info:
project-knife4j
:
http://${spring-boot-plus.server-ip}:${server.port}${server.servlet.context-path}/doc.html
############################## Spring boot admin end ###############################
websocket
:
action
:
scan-package
:
com.wecloud
core/src/main/java/com/wecloud/dispatch/ActionContext.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
;
import
com.wecloud.dispatch.annotation.ActionMapping
;
import
com.wecloud.dispatch.config.ActionConfigurer
;
import
com.wecloud.dispatch.extend.ActionBox
;
import
com.wecloud.dispatch.extend.impl.DefaultActionBox
;
import
com.wecloud.dispatch.registry.ActionBoxRegistry
;
import
com.wecloud.dispatch.registry.ActionInterceptorRegistry
;
import
com.wecloud.dispatch.registry.ActionMethodInterceptorRegistry
;
import
com.wecloud.dispatch.registry.ActionRegistry
;
import
com.wecloud.dispatch.registry.ArgumentDefaultValueBuilderRegistry
;
import
com.wecloud.dispatch.registry.MethodArgumentResolverRegistry
;
import
com.wecloud.dispatch.util.ClassScaner
;
import
lombok.extern.slf4j.Slf4j
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
@Slf4j
public
class
ActionContext
{
private
final
ActionRegistry
actionRegistry
=
new
ActionRegistry
();
private
final
ActionBoxRegistry
actionBoxRegistry
=
new
ActionBoxRegistry
();
private
final
ActionMethodInterceptorRegistry
actionMethodInterceptorRegistry
=
new
ActionMethodInterceptorRegistry
();
private
final
MethodArgumentResolverRegistry
methodArgumentResolverRegistry
=
new
MethodArgumentResolverRegistry
();
private
final
ActionInterceptorRegistry
actionInterceptorRegistry
=
new
ActionInterceptorRegistry
();
private
final
ActionBox
actionBox
=
new
DefaultActionBox
();
private
final
ArgumentDefaultValueBuilderRegistry
argumentDefaultValueBuilderRegistry
=
new
ArgumentDefaultValueBuilderRegistry
();
private
final
ActionDispatcher
actionDispatcher
;
public
ActionContext
(
ActionDispatcher
actionDispatcher
)
{
super
();
this
.
actionDispatcher
=
actionDispatcher
;
}
@SuppressWarnings
(
"unchecked"
)
public
void
scan
(
String
...
path
)
{
// 扫描包下面的所有被注解ActionMapping的类
Set
<
Class
<?>>
classSet
=
ClassScaner
.
scan
(
path
,
ActionMapping
.
class
);
for
(
Class
<?>
classType
:
classSet
)
{
log
.
info
(
"ActionMapping scan, find: {}"
,
classType
.
getTypeName
());
actionRegistry
.
add
(
classType
);
}
}
@SuppressWarnings
(
"unchecked"
)
public
void
cover
(
String
...
path
)
{
// 扫描xxx包下面的所有被注解ActionMapping的类
Set
<
Class
<?>>
classSet
=
ClassScaner
.
scan
(
path
,
ActionMapping
.
class
);
for
(
Class
<?>
classType
:
classSet
)
{
actionRegistry
.
cover
(
classType
);
}
}
public
void
cover
(
Class
<?>
classType
)
{
actionRegistry
.
cover
(
classType
);
}
public
void
addConfig
(
ActionConfigurer
actionConfigurer
)
{
actionConfigurer
.
addConfig
(
this
);
}
public
ActionRegistry
getActionRegistry
()
{
return
actionRegistry
;
}
public
ActionBoxRegistry
getActionBoxRegistry
()
{
return
actionBoxRegistry
;
}
public
MethodArgumentResolverRegistry
getMethodArgumentResolverRegistry
()
{
return
methodArgumentResolverRegistry
;
}
public
ActionInterceptorRegistry
getActionInterceptorRegistry
()
{
return
actionInterceptorRegistry
;
}
public
ActionBox
getActionBox
()
{
return
actionBox
;
}
public
ActionMethodInterceptorRegistry
getActionMethodInterceptorRegistry
()
{
return
actionMethodInterceptorRegistry
;
}
public
ArgumentDefaultValueBuilderRegistry
getArgumentDefaultValueBuilderRegistry
()
{
return
argumentDefaultValueBuilderRegistry
;
}
public
ActionDispatcher
getActionDispatcher
()
{
return
actionDispatcher
;
}
}
core/src/main/java/com/wecloud/dispatch/ActionDispatcher.java
0 → 100644
View file @
a7892caa
This diff is collapsed.
Click to expand it.
core/src/main/java/com/wecloud/dispatch/WsTestAction.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
;
import
com.wecloud.dispatch.annotation.ActionMapping
;
import
com.wecloud.im.ws.model.WsResponse
;
import
com.wecloud.im.ws.model.request.PushVO
;
import
com.wecloud.utils.JsonUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
@Component
@ActionMapping
(
value
=
"sendtest"
)
@Slf4j
public
class
WsTestAction
{
/**
* test
* @param reqId
* @param nihao
* @param push
* @param pList
* @param pSet
* @param pMap
*/
@ActionMapping
(
value
=
"gogo"
)
public
WsResponse
<
Boolean
>
groupChat
(
String
reqId
,
@RequestParam
(
"hello"
)
String
nihao
,
PushVO
push
,
ArrayList
<
PushVO
>
pList
,
Set
<
PushVO
>
pSet
,
Map
<
String
,
String
>
pMap
)
{
log
.
info
(
reqId
);
log
.
info
(
nihao
);
log
.
info
(
JsonUtils
.
encodeJson
(
push
));
log
.
info
(
JsonUtils
.
encodeJson
(
pList
));
log
.
info
(
JsonUtils
.
encodeJson
(
pSet
));
log
.
info
(
JsonUtils
.
encodeJson
(
pMap
));
WsResponse
<
Boolean
>
wsResponse
=
new
WsResponse
<>();
wsResponse
.
setCmd
(
0
).
setData
(
true
).
setCode
(
0
).
setMsg
(
"msg"
).
setReqId
(
reqId
);
return
wsResponse
;
}
}
core/src/main/java/com/wecloud/dispatch/annotation/ActionMapping.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
annotation
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* @author lixiaozhong
*/
@Target
({
ElementType
.
METHOD
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
ActionMapping
{
/**
* Mapping映射字段
* @return
*/
String
[]
value
()
default
""
;
/**
*
* @return
*/
int
order
()
default
10
;
}
core/src/main/java/com/wecloud/dispatch/common/ActionMethod.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
common
;
import
org.springframework.core.DefaultParameterNameDiscoverer
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.annotation.SynthesizingMethodParameter
;
import
java.lang.reflect.Method
;
/**
* @author lixiaozhong
*/
public
class
ActionMethod
{
private
Class
<?>
actionClass
;
private
Method
method
;
private
MethodParameter
[]
methodParameters
;
private
String
methodPath
;
// public ActionMethod(Class<?> actionClass, Method method) {
// this.actionClass = actionClass;
// this.method = method;
// initialize(method);
// }
public
ActionMethod
(
Method
method
,
String
methodPath
)
{
this
.
actionClass
=
method
.
getDeclaringClass
();
this
.
method
=
method
;
this
.
methodPath
=
methodPath
;
initialize
(
method
);
}
private
void
initialize
(
Method
method
)
{
methodParameters
=
initMethodParameters
(
method
);
}
private
MethodParameter
[]
initMethodParameters
(
Method
method
)
{
int
count
=
method
.
getParameterCount
();
MethodParameter
[]
result
=
new
MethodParameter
[
count
];
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
SynthesizingMethodParameter
parameter
=
SynthesizingMethodParameter
.
forExecutable
(
method
,
i
);
parameter
.
withContainingClass
(
this
.
actionClass
);
parameter
.
initParameterNameDiscovery
(
new
DefaultParameterNameDiscoverer
());
result
[
i
]
=
parameter
;
}
return
result
;
}
public
Class
<?>
getActionClass
()
{
return
actionClass
;
}
public
Method
getMethod
()
{
return
method
;
}
public
MethodParameter
[]
getMethodParameters
()
{
return
methodParameters
;
}
public
String
getMethodPath
()
{
return
methodPath
;
}
public
void
setMethodPath
(
String
methodPath
)
{
this
.
methodPath
=
methodPath
;
}
}
core/src/main/java/com/wecloud/dispatch/common/ApplyInfo.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
common
;
/**
* @author lixiaozhong
*/
public
class
ApplyInfo
{
private
boolean
approve
;
private
Object
value
;
public
boolean
isApprove
()
{
return
approve
;
}
public
void
setApprove
(
boolean
approve
)
{
this
.
approve
=
approve
;
}
public
Object
getValue
()
{
return
value
;
}
public
void
setValue
(
Object
value
)
{
this
.
value
=
value
;
}
}
core/src/main/java/com/wecloud/dispatch/common/RequestVO.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
common
;
import
lombok.NoArgsConstructor
;
import
java.util.HashMap
;
/**
* @author lixiaozhong
*/
@NoArgsConstructor
public
class
RequestVO
extends
HashMap
<
String
,
Object
>
{
/**
* 请求的参数 action,用来寻找action类的path
*/
private
String
action
;
/**
* 请求id, 以判空是否请求成功, 服务端处理完成后 返回此id
* 由前端生成,可以用uuid,也可以用时间戳
*/
private
String
reqId
;
public
String
getAction
()
{
return
(
String
)
this
.
get
(
"action"
);
}
public
void
setAction
(
String
action
)
{
this
.
put
(
"action"
,
action
);
}
public
String
getReqId
()
{
return
(
String
)
this
.
get
(
"reqId"
);
}
public
void
setReqId
(
String
reqId
)
{
this
.
put
(
"reqId"
,
reqId
);
}
}
core/src/main/java/com/wecloud/dispatch/config/ActionConfigurer.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
config
;
import
com.wecloud.dispatch.ActionContext
;
/**
* @author lixiaozhong
*/
public
interface
ActionConfigurer
{
/**
* 为了方便将配置项写入actionContext
* @param actionContext
*/
public
void
addConfig
(
ActionContext
actionContext
);
}
core/src/main/java/com/wecloud/dispatch/exception/ActionNotFoundException.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
exception
;
/**
* @author lixiaozhong
*/
public
class
ActionNotFoundException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
1L
;
public
ActionNotFoundException
()
{
super
();
}
public
ActionNotFoundException
(
String
message
)
{
super
(
message
);
}
}
core/src/main/java/com/wecloud/dispatch/exception/MappingException.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
exception
;
/**
* @author lixiaozhong
*/
public
class
MappingException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
1L
;
public
MappingException
()
{
super
();
}
public
MappingException
(
String
message
)
{
super
(
message
);
}
}
core/src/main/java/com/wecloud/dispatch/extend/ActionBox.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
/**
* @author lixiaozhong
*/
public
interface
ActionBox
{
/**
* 获取action对象
* @param type
* @return
*/
public
Object
getAction
(
Class
<?>
type
);
/**
* 获取action对象
* @param className
* @return
*/
public
Object
getAction
(
String
className
);
}
core/src/main/java/com/wecloud/dispatch/extend/ActionInterceptor.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.common.ApplyInfo
;
/**
* @author lixiaozhong
*/
public
interface
ActionInterceptor
{
/**
*
* 执行前拦截
*
* @param actionContext
* @param request
* @param argumentBox
* @return
*/
public
ApplyInfo
previous
(
ActionContext
actionContext
,
ActionRequest
request
,
ArgumentBox
argumentBox
);
}
core/src/main/java/com/wecloud/dispatch/extend/ActionMessage.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
import
com.wecloud.dispatch.common.RequestVO
;
/**
* @author lixiaozhong
*/
public
interface
ActionMessage
{
void
setMessage
(
RequestVO
message
);
RequestVO
getMessage
();
String
getAction
();
void
setAction
(
String
action
);
}
core/src/main/java/com/wecloud/dispatch/extend/ActionMethodInterceptor.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.common.ApplyInfo
;
import
org.springframework.core.MethodParameter
;
import
java.lang.reflect.Method
;
/**
* 切面
* @author lixiaozhong
*/
public
interface
ActionMethodInterceptor
{
/**
*
* 方法切面
*
* @param actionContext
* @param object
* @param method
* @param array
* @param parameter
* @param request
* @param argumentBox
* @return
*/
ApplyInfo
intercept
(
ActionContext
actionContext
,
Object
object
,
Method
method
,
Object
[]
array
,
MethodParameter
[]
parameter
,
ActionRequest
request
,
ArgumentBox
argumentBox
);
}
core/src/main/java/com/wecloud/dispatch/extend/ActionRequest.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
import
com.wecloud.dispatch.common.ActionMethod
;
import
com.wecloud.dispatch.common.RequestVO
;
/**
* @author lixiaozhong
*/
public
interface
ActionRequest
{
String
getPath
();
Object
getAction
();
RequestVO
getData
();
ActionMethod
getActionMethod
();
}
core/src/main/java/com/wecloud/dispatch/extend/ActionResponse.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
/**
* @author lixiaozhong
*/
public
interface
ActionResponse
{
void
write
(
Object
data
);
}
core/src/main/java/com/wecloud/dispatch/extend/ArgumentBox.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
interface
ArgumentBox
{
<
T
>
T
get
(
Object
key
);
void
put
(
Object
key
,
Object
object
);
Set
<
Object
>
keySet
();
}
core/src/main/java/com/wecloud/dispatch/extend/ArgumentDefaultValueBuilder.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
/**
* @author lixiaozhong
*/
public
interface
ArgumentDefaultValueBuilder
{
/**
*
* 参数默认值创建
*
* @param classType
* @return
*/
Object
build
(
Class
<?>
classType
);
}
core/src/main/java/com/wecloud/dispatch/extend/MethodArgumentResolver.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
;
import
com.wecloud.dispatch.ActionContext
;
import
org.springframework.core.MethodParameter
;
/**
* @author lixiaozhong
*/
public
interface
MethodArgumentResolver
{
/**
*
* 是否支持<br>
*
* @param parameter
* @return
*/
boolean
supportsParameter
(
MethodParameter
parameter
);
/**
*
* 解析参数<br>
*
* @param actionContext
* @param parameter
* @param request
* @param argumentBox
* @return
*/
Object
resolveArgument
(
ActionContext
actionContext
,
MethodParameter
parameter
,
ActionRequest
request
,
ArgumentBox
argumentBox
);
}
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultActionBox.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
.
impl
;
import
com.wecloud.dispatch.extend.ActionBox
;
import
com.wecloud.dispatch.factory.ObjectFactory
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @author lixiaozhong
*/
public
class
DefaultActionBox
implements
ActionBox
{
Map
<
String
,
Class
<?>>
classMap
=
new
HashMap
<>();
ObjectFactory
objectFactory
=
new
ObjectFactory
();
@Override
public
Object
getAction
(
Class
<?>
type
)
{
return
objectFactory
.
getObject
(
type
);
}
@Override
public
Object
getAction
(
String
className
)
{
Class
<?>
type
=
null
;
if
(
classMap
.
containsKey
(
className
))
{
type
=
classMap
.
get
(
className
);
}
else
{
try
{
type
=
Class
.
forName
(
className
);
classMap
.
put
(
className
,
type
);
}
catch
(
Exception
e
)
{
classMap
.
put
(
className
,
null
);
}
}
if
(
null
==
type
)
{
return
null
;
}
else
{
return
getAction
(
type
);
}
}
}
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultActionMessage.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
.
impl
;
import
com.wecloud.dispatch.common.RequestVO
;
import
com.wecloud.dispatch.extend.ActionMessage
;
/**
* @author lixiaozhong
*/
public
class
DefaultActionMessage
implements
ActionMessage
{
String
action
;
RequestVO
message
;
public
DefaultActionMessage
()
{
}
public
DefaultActionMessage
(
String
action
,
RequestVO
message
)
{
this
.
message
=
message
;
this
.
action
=
action
;
}
@Override
public
RequestVO
getMessage
()
{
return
message
;
}
@Override
public
void
setMessage
(
RequestVO
message
)
{
this
.
message
=
message
;
}
@Override
public
String
getAction
()
{
return
action
;
}
@Override
public
void
setAction
(
String
action
)
{
this
.
action
=
action
;
}
}
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultArgumentBox.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
.
impl
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
class
DefaultArgumentBox
implements
ArgumentBox
{
Map
<
Object
,
Object
>
map
=
new
HashMap
<>();
@SuppressWarnings
(
"unchecked"
)
@Override
public
<
T
>
T
get
(
Object
key
)
{
return
(
T
)
map
.
get
(
key
);
}
@Override
public
void
put
(
Object
key
,
Object
object
)
{
map
.
put
(
key
,
object
);
}
@Override
public
Set
<
Object
>
keySet
()
{
return
map
.
keySet
();
}
}
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultArgumentDefaultValueBuilder.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
.
impl
;
import
com.wecloud.dispatch.extend.ArgumentDefaultValueBuilder
;
import
com.wecloud.dispatch.util.ClassUtil
;
import
java.lang.reflect.Array
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
class
DefaultArgumentDefaultValueBuilder
implements
ArgumentDefaultValueBuilder
{
Map
<
Class
<?>,
Boolean
>
canNotInstanceMap
=
new
HashMap
<>();
@Override
public
Object
build
(
Class
<?>
classType
)
{
return
getValue
(
classType
);
}
private
Object
getValue
(
Class
<?>
clazz
)
{
Object
value
=
null
;
if
(
null
==
value
)
{
value
=
getDefaultValue
(
clazz
);
}
if
(
null
==
value
&&
ClassUtil
.
isCanInstance
(
clazz
)
&&
!
canNotInstanceMap
.
containsKey
(
clazz
))
{
value
=
getObject
(
clazz
);
}
return
value
;
}
private
<
T
>
Object
getObject
(
Class
<
T
>
clazz
)
{
Object
object
=
null
;
if
(
ClassUtil
.
isCanInstance
(
clazz
)
&&
!
canNotInstanceMap
.
containsKey
(
clazz
))
{
try
{
object
=
clazz
.
newInstance
();
}
catch
(
InstantiationException
|
IllegalAccessException
e
)
{
canNotInstanceMap
.
put
(
clazz
,
false
);
}
}
return
object
;
}
/**
* 对象给默认值
*
*/
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getDefaultValue
(
Class
<
T
>
clazz
)
{
Object
object
=
null
;
if
(
List
.
class
.
isAssignableFrom
(
clazz
))
{
object
=
new
ArrayList
<
Object
>(
0
);
}
else
if
(
Map
.
class
.
isAssignableFrom
(
clazz
))
{
object
=
new
HashMap
<
Object
,
Object
>(
0
);
}
else
if
(
Set
.
class
.
isAssignableFrom
(
clazz
))
{
object
=
new
HashSet
<
Object
>(
0
);
}
else
if
(
clazz
.
isArray
())
{
Class
<?>
componentType
=
clazz
.
getComponentType
();
object
=
Array
.
newInstance
(
componentType
,
0
);
}
else
if
(
clazz
==
int
.
class
)
{
object
=
0
;
}
else
if
(
clazz
==
long
.
class
)
{
object
=
0L
;
}
else
if
(
clazz
==
float
.
class
)
{
object
=
0.0
F
;
}
else
if
(
clazz
==
double
.
class
)
{
object
=
0.00
D
;
}
else
if
(
clazz
==
byte
.
class
)
{
object
=
(
byte
)
0
;
}
else
if
(
clazz
==
char
.
class
)
{
object
=
'\u0000'
;
}
else
if
(
clazz
==
short
.
class
)
{
object
=
0
;
}
else
if
(
clazz
==
boolean
.
class
)
{
object
=
false
;
}
return
((
T
)
object
);
}
}
core/src/main/java/com/wecloud/dispatch/extend/impl/DefaultMethodArgumentResolver.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
extend
.
impl
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.extend.ActionRequest
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
import
com.wecloud.dispatch.extend.MethodArgumentResolver
;
import
org.springframework.core.MethodParameter
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
class
DefaultMethodArgumentResolver
implements
MethodArgumentResolver
{
@Override
public
boolean
supportsParameter
(
MethodParameter
parameter
)
{
return
true
;
}
@Override
public
Object
resolveArgument
(
ActionContext
actionContext
,
MethodParameter
parameter
,
ActionRequest
request
,
ArgumentBox
argumentBox
)
{
// Type type = parameter.getGenericParameterType();
Class
<?>
clazz
=
parameter
.
getParameterType
();
Object
data
=
null
;
if
(
null
!=
clazz
)
{
if
(
clazz
.
isAssignableFrom
(
ActionContext
.
class
))
{
data
=
actionContext
;
}
else
if
(
clazz
.
isAssignableFrom
(
ActionRequest
.
class
))
{
data
=
request
;
}
else
if
(
clazz
.
isAssignableFrom
(
ArgumentBox
.
class
))
{
data
=
argumentBox
;
}
else
{
data
=
argumentBox
.
get
(
clazz
);
if
(
null
==
data
)
{
Set
<
Object
>
keys
=
argumentBox
.
keySet
();
if
(
null
!=
keys
)
{
for
(
Object
o
:
keys
)
{
if
(
o
instanceof
Class
)
{
Class
<?>
classKey
=
(
Class
<?>)
o
;
if
(
clazz
.
isAssignableFrom
(
classKey
))
{
data
=
argumentBox
.
get
(
o
);
break
;
}
}
}
}
}
if
(
null
==
data
)
{
data
=
getValue
(
actionContext
,
clazz
);
}
}
}
return
data
;
}
private
Object
getValue
(
ActionContext
actionContext
,
Class
<?>
clazz
)
{
return
actionContext
.
getArgumentDefaultValueBuilderRegistry
().
getValue
(
clazz
);
}
}
core/src/main/java/com/wecloud/dispatch/factory/AbstractFactory.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
factory
;
import
com.wecloud.dispatch.util.ClassUtil
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
java.lang.reflect.Array
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.locks.ReentrantLock
;
/**
* @author lixiaozhong
*/
public
abstract
class
AbstractFactory
{
protected
final
Logger
logger
=
LoggerFactory
.
getLogger
(
this
.
getClass
());
private
Map
<
Class
<?>,
Object
>
objectMap
=
new
ConcurrentHashMap
<>();
private
Map
<
Class
<?>,
Boolean
>
canNotInstanceMap
=
new
ConcurrentHashMap
<>();
private
ReentrantLock
lock
=
new
ReentrantLock
();
public
<
T
>
void
put
(
Class
<
T
>
defineClass
,
T
object
)
{
objectMap
.
put
(
defineClass
,
object
);
}
/**
* 根据class获取对象,均为单列(有待验证😂)
*
* @param classType
* @return T
*/
public
<
T
>
T
getObject
(
Class
<
T
>
classType
)
{
return
getObject
(
classType
,
false
,
false
);
}
/**
*
* @param classType
* @param createNew
* @return T
*/
public
<
T
>
T
getObject
(
Class
<
T
>
classType
,
boolean
createNew
)
{
return
getObject
(
classType
,
createNew
,
false
);
}
/**
*
* @param classType :被实例化的class对象
* @param createNew :true:不管对象是否存在,都新创建对象;false:如果对象已经存在就不新建对象
* @param cover :true:如果新建了对象,则覆盖原来的对象。false:不执行覆盖操作
* @return T
*/
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getObject
(
Class
<
T
>
classType
,
boolean
createNew
,
boolean
cover
)
{
Object
object
=
null
;
if
(
null
!=
classType
)
{
object
=
objectMap
.
get
(
classType
);
if
(
createNew
)
{
object
=
createObject
(
classType
);
if
((
cover
)
&&
null
!=
object
)
{
objectMap
.
put
(
classType
,
object
);
}
}
else
if
(
null
==
object
)
{
final
ReentrantLock
lock
=
this
.
lock
;
lock
.
lock
();
try
{
boolean
has
=
objectMap
.
containsKey
(
classType
);
object
=
objectMap
.
get
(
classType
);
if
(!
has
)
{
object
=
createObject
(
classType
);
// 原来对象不存在,或者覆盖,并且新创建的对象不能为空
if
((
cover
)
&&
null
!=
object
)
{
objectMap
.
put
(
classType
,
object
);
}
}
}
finally
{
lock
.
unlock
();
}
}
}
return
(
T
)
object
;
}
/**
* 根据class反射创建对象
*
* @param clazz
* @return
*/
public
Object
createObject
(
Class
<?>
clazz
)
{
Object
object
=
null
;
if
(!
canNotInstanceMap
.
containsKey
(
clazz
))
{
try
{
if
(
ClassUtil
.
isCanInstance
(
clazz
))
{
object
=
clazz
.
newInstance
();
}
else
if
(
clazz
.
isArray
())
{
Class
<?>
componentType
=
clazz
.
getComponentType
();
object
=
Array
.
newInstance
(
componentType
,
0
);
}
}
catch
(
Exception
e
)
{
canNotInstanceMap
.
put
(
clazz
,
false
);
logger
.
error
(
"初始化对象失败!"
,
e
);
}
}
return
object
;
}
}
core/src/main/java/com/wecloud/dispatch/factory/ObjectFactory.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
factory
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.locks.Lock
;
import
java.util.concurrent.locks.ReentrantLock
;
/**
* 管理存放系统对象
*
* @author lixiaozhong
*/
public
class
ObjectFactory
extends
AbstractFactory
{
private
Map
<
Class
<?>,
Class
<?>>
map
=
new
ConcurrentHashMap
<
Class
<?>,
Class
<?>>();
private
Map
<
Class
<?>,
Map
<
String
,
Object
>>
multipleMap
=
new
ConcurrentHashMap
<
Class
<?>,
Map
<
String
,
Object
>>();
private
Lock
lock
=
new
ReentrantLock
();
/**
* 注册定义类和实现类的关系<br>
*
* @param defineClass
* @param instanceClass
*/
public
<
T
>
void
register
(
Class
<
T
>
defineClass
,
Class
<?
extends
T
>
instanceClass
)
{
map
.
put
(
defineClass
,
instanceClass
);
}
@Override
public
<
T
>
T
getObject
(
Class
<
T
>
classType
)
{
return
getObject
(
classType
,
false
,
false
);
}
@Override
public
<
T
>
T
getObject
(
Class
<
T
>
classType
,
boolean
createNew
)
{
return
getObject
(
classType
,
createNew
,
false
);
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getObject
(
Class
<
T
>
classType
,
boolean
createNew
,
boolean
cover
)
{
T
o
=
null
;
Class
<
T
>
clazz
=
(
Class
<
T
>)
map
.
get
(
classType
);
if
(
null
!=
clazz
)
{
o
=
super
.
getObject
(
clazz
,
createNew
,
cover
);
}
else
{
o
=
super
.
getObject
(
classType
,
createNew
,
cover
);
}
return
o
;
}
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getObject
(
String
key
,
Class
<
T
>
classType
)
{
Object
o
=
null
;
lock
.
lock
();
try
{
Map
<
String
,
Object
>
objectMap
=
multipleMap
.
get
(
classType
);
if
(
null
==
objectMap
)
{
objectMap
=
new
ConcurrentHashMap
<
String
,
Object
>(
16
);
multipleMap
.
put
(
classType
,
objectMap
);
}
o
=
objectMap
.
get
(
key
);
if
(
null
==
o
)
{
o
=
super
.
createObject
(
classType
);
if
(
null
!=
o
)
{
objectMap
.
put
(
key
,
o
);
}
}
}
finally
{
lock
.
unlock
();
}
return
(
T
)
o
;
}
}
core/src/main/java/com/wecloud/dispatch/general/GeneralMessageHandler.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
;
import
com.wecloud.dispatch.common.RequestVO
;
import
com.wecloud.dispatch.extend.ActionMessage
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
import
com.wecloud.dispatch.extend.impl.DefaultArgumentBox
;
import
com.wecloud.dispatch.general.config.GeneralActionDispatcher
;
import
com.wecloud.dispatch.general.extend.ActionMessageResolver
;
import
com.wecloud.im.ws.sender.ChannelSender
;
import
com.wecloud.utils.JsonUtils
;
import
io.geekidea.springbootplus.framework.common.exception.BusinessException
;
import
io.netty.channel.ChannelHandlerContext
;
import
io.netty.channel.socket.nio.NioSocketChannel
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
/**
* @author lixiaozhong
*/
@Component
@Slf4j
public
class
GeneralMessageHandler
{
@Autowired
private
GeneralActionDispatcher
generalActionDispatcher
;
@Autowired
private
ActionMessageResolver
actionMessageResolver
;
@Autowired
private
ChannelSender
channelSender
;
public
void
doMessage
(
Long
senderClientId
,
ChannelHandlerContext
ctx
,
String
data
)
{
if
(
log
.
isDebugEnabled
())
{
log
.
debug
(
"appWS收到data: {}\n senderClientId:{}, channelId:{}"
,
data
,
senderClientId
,
ctx
.
channel
().
id
().
asLongText
());
}
// 解析jsonO
RequestVO
requestVO
=
JsonUtils
.
decodeJson
(
data
,
RequestVO
.
class
);
if
(
null
==
requestVO
||
null
==
requestVO
.
getAction
())
{
throw
new
BusinessException
(
"null == requestVO || null == requestVO.getAction()"
);
}
ActionMessage
am
=
actionMessageResolver
.
resolver
(
generalActionDispatcher
,
requestVO
);
Object
res
=
generalActionDispatcher
.
action
(
am
);
channelSender
.
sendMsgLocal
((
NioSocketChannel
)
ctx
.
channel
(),
res
);
}
public
ArgumentBox
getArgumentBox
()
{
ArgumentBox
beanBox
=
new
DefaultArgumentBox
();
return
beanBox
;
}
}
core/src/main/java/com/wecloud/dispatch/general/config/DispatcherConfig.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
config
;
import
com.wecloud.dispatch.general.impl.GeneralActionBox
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
@Configuration
@EnableConfigurationProperties
(
GeneralActionDispatcherProperties
.
class
)
public
class
DispatcherConfig
{
@Autowired
private
GeneralActionDispatcherProperties
generalActionDispatcherProperties
;
@Bean
public
GeneralActionDispatcher
generalActionDispatcher
(
GeneralActionBox
generalActionBox
)
{
Set
<
String
>
actionPackages
=
generalActionDispatcherProperties
.
getScanPackage
();
GeneralActionDispatcher
bean
=
new
GeneralActionDispatcher
();
bean
.
add
(
generalActionBox
);
if
(
null
!=
actionPackages
&&
!
actionPackages
.
isEmpty
())
{
for
(
String
path
:
actionPackages
)
{
bean
.
scan
(
path
);
}
}
else
{
bean
.
scan
(
"com.wecloud"
);
}
return
bean
;
}
@Bean
public
GeneralActionBox
generalActionBox
()
{
GeneralActionBox
bean
=
new
GeneralActionBox
();
return
bean
;
}
}
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionConfigurerAdapter.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
config
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.config.ActionConfigurer
;
/**
* @author lixiaozhong
*/
public
class
GeneralActionConfigurerAdapter
implements
ActionConfigurer
{
@Override
public
void
addConfig
(
ActionContext
actionContext
)
{
// TODO Auto-generated method stub
}
}
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionDefaultConfigurer.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
config
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.general.impl.GeneralActionMethodValidInterceptor
;
import
com.wecloud.dispatch.general.impl.GeneralMethodArgumentResolver
;
/**
* @author lixiaozhong
*/
public
class
GeneralActionDefaultConfigurer
extends
GeneralActionConfigurerAdapter
{
@Override
public
void
addConfig
(
ActionContext
actionContext
)
{
actionContext
.
getMethodArgumentResolverRegistry
().
add
(
new
GeneralMethodArgumentResolver
());
actionContext
.
getActionMethodInterceptorRegistry
().
add
(
new
GeneralActionMethodValidInterceptor
());
}
}
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionDispatcher.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
config
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.ActionDispatcher
;
import
com.wecloud.dispatch.config.ActionConfigurer
;
import
com.wecloud.dispatch.extend.ActionBox
;
import
com.wecloud.dispatch.general.impl.GeneralActionInterceptor
;
/**
* @author lixiaozhong
*/
public
class
GeneralActionDispatcher
extends
ActionDispatcher
{
private
GeneralActionDefaultConfigurer
handlerActionConfigurer
=
new
GeneralActionDefaultConfigurer
();
private
GeneralActionInterceptor
handlerActionInterceptor
=
new
GeneralActionInterceptor
();
public
GeneralActionDispatcher
()
{
this
.
initialize
();
}
public
GeneralActionDispatcher
(
ActionBox
actionBox
)
{
this
.
initialize
();
this
.
add
(
actionBox
);
}
public
GeneralActionDispatcher
(
ActionBox
actionBox
,
String
...
actionLocations
)
{
this
.
initialize
();
this
.
add
(
actionBox
);
this
.
scan
(
actionLocations
);
}
@Override
public
void
addConfig
(
ActionConfigurer
actionConfigurer
)
{
super
.
addConfig
(
actionConfigurer
);
}
private
void
initialize
()
{
this
.
addConfig
(
handlerActionConfigurer
);
this
.
addConfig
(
new
GeneralActionConfigurerAdapter
()
{
@Override
public
void
addConfig
(
ActionContext
actionContext
)
{
actionContext
.
getActionInterceptorRegistry
().
add
(
handlerActionInterceptor
);
}
});
}
public
void
add
(
ActionBox
actionBox
)
{
// "com.*.action"
this
.
addConfig
(
new
GeneralActionConfigurerAdapter
()
{
@Override
public
void
addConfig
(
ActionContext
actionContext
)
{
actionContext
.
getActionBoxRegistry
().
add
(
actionBox
);
}
});
}
}
core/src/main/java/com/wecloud/dispatch/general/config/GeneralActionDispatcherProperties.java
0 → 100644
View file @
a7892caa
This diff is collapsed.
Click to expand it.
core/src/main/java/com/wecloud/dispatch/general/extend/ActionMessageResolver.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
extend
;
import
com.wecloud.dispatch.ActionDispatcher
;
import
com.wecloud.dispatch.common.RequestVO
;
import
com.wecloud.dispatch.extend.ActionMessage
;
/**
* @author lixiaozhong
*/
public
interface
ActionMessageResolver
{
/**
*
* 解析消息<br>
*
* @param actionDispatcher
* @param data
* @return
*/
ActionMessage
resolver
(
ActionDispatcher
actionDispatcher
,
RequestVO
data
);
}
core/src/main/java/com/wecloud/dispatch/general/extend/impl/ActionMessageResolverImpl.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
extend
.
impl
;
import
com.wecloud.dispatch.ActionDispatcher
;
import
com.wecloud.dispatch.common.RequestVO
;
import
com.wecloud.dispatch.extend.ActionMessage
;
import
com.wecloud.dispatch.extend.impl.DefaultActionMessage
;
import
com.wecloud.dispatch.general.extend.ActionMessageResolver
;
import
org.springframework.stereotype.Component
;
/**
* @author lixiaozhong
*/
@Component
public
class
ActionMessageResolverImpl
implements
ActionMessageResolver
{
@Override
public
ActionMessage
resolver
(
ActionDispatcher
actionDispatcher
,
RequestVO
data
)
{
ActionMessage
am
=
new
DefaultActionMessage
();
am
.
setAction
(
""
);
if
(
data
==
null
)
{
return
am
;
}
String
action
=
data
.
getAction
();
String
path
=
actionDispatcher
.
getActionRegistry
().
getPath
(
action
,
null
);
am
.
setMessage
(
data
);
am
.
setAction
(
path
);
return
am
;
}
}
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralActionBox.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
impl
;
import
com.wecloud.dispatch.extend.ActionBox
;
import
org.springframework.beans.BeansException
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
/**
* @author lixiaozhong
*/
public
class
GeneralActionBox
implements
ActionBox
,
ApplicationContextAware
{
private
ApplicationContext
applicationContext
=
null
;
@Override
public
Object
getAction
(
Class
<?>
type
)
{
Object
o
=
null
;
if
(
null
!=
applicationContext
)
{
o
=
applicationContext
.
getBean
(
type
);
}
return
o
;
}
@Override
public
Object
getAction
(
String
className
)
{
Object
o
=
null
;
if
(
null
!=
applicationContext
)
{
o
=
applicationContext
.
getBean
(
className
);
}
return
o
;
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
throws
BeansException
{
this
.
applicationContext
=
applicationContext
;
}
}
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralActionInterceptor.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
impl
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.common.ApplyInfo
;
import
com.wecloud.dispatch.extend.ActionInterceptor
;
import
com.wecloud.dispatch.extend.ActionRequest
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
/**
* @author lixiaozhong
*/
public
class
GeneralActionInterceptor
implements
ActionInterceptor
{
@Override
public
ApplyInfo
previous
(
ActionContext
actionContext
,
ActionRequest
request
,
ArgumentBox
argumentBox
)
{
ApplyInfo
applyInfo
=
new
ApplyInfo
();
applyInfo
.
setApprove
(
true
);
return
applyInfo
;
}
}
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralActionMethodValidInterceptor.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
impl
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.common.ApplyInfo
;
import
com.wecloud.dispatch.extend.ActionMethodInterceptor
;
import
com.wecloud.dispatch.extend.ActionRequest
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
import
org.springframework.beans.factory.FactoryBean
;
import
org.springframework.beans.factory.SmartFactoryBean
;
import
org.springframework.context.support.ReloadableResourceBundleMessageSource
;
import
org.springframework.core.BridgeMethodResolver
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.annotation.AnnotationUtils
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean
;
import
javax.validation.ConstraintViolation
;
import
javax.validation.ConstraintViolationException
;
import
javax.validation.Validator
;
import
javax.validation.executable.ExecutableValidator
;
import
java.lang.reflect.Method
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
class
GeneralActionMethodValidInterceptor
implements
ActionMethodInterceptor
{
Validator
validator
;
public
GeneralActionMethodValidInterceptor
()
{
ReloadableResourceBundleMessageSource
messageSource
=
new
ReloadableResourceBundleMessageSource
();
// messageSource.setBasename("classpath:i18n/ValidationMessages");
OptionalValidatorFactoryBean
optionalValidatorFactoryBean
=
new
OptionalValidatorFactoryBean
();
optionalValidatorFactoryBean
.
setValidationMessageSource
(
messageSource
);
optionalValidatorFactoryBean
.
afterPropertiesSet
();
validator
=
optionalValidatorFactoryBean
;
}
@Override
public
ApplyInfo
intercept
(
ActionContext
actionContext
,
Object
object
,
Method
method
,
Object
[]
array
,
MethodParameter
[]
parameter
,
ActionRequest
request
,
ArgumentBox
argumentBox
)
{
// TODO Auto-generated method stub
boolean
approve
=
true
;
Object
value
=
null
;
if
(!
isFactoryBeanMetadataMethod
(
method
))
{
Class
<?>[]
groups
=
determineValidationGroups
(
object
,
method
);
// Standard Bean Validation 1.1 API
ExecutableValidator
execVal
=
this
.
validator
.
forExecutables
();
Method
methodToValidate
=
method
;
Set
<
ConstraintViolation
<
Object
>>
result
;
try
{
result
=
execVal
.
validateParameters
(
object
,
methodToValidate
,
array
,
groups
);
}
catch
(
IllegalArgumentException
ex
)
{
// Probably a generic type mismatch between interface and impl as reported in
// SPR-12237 / HV-1011
// Let's try to find the bridged method on the implementation class...
methodToValidate
=
BridgeMethodResolver
.
findBridgedMethod
(
ClassUtils
.
getMostSpecificMethod
(
method
,
object
.
getClass
()));
result
=
execVal
.
validateParameters
(
object
,
methodToValidate
,
array
,
groups
);
}
if
(!
result
.
isEmpty
())
{
throw
new
ConstraintViolationException
(
result
);
}
if
(
null
!=
array
)
{
int
size
=
array
.
length
;
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Validated
validatedAnn
=
parameter
[
i
].
getParameterAnnotation
(
Validated
.
class
);
if
(
validatedAnn
!=
null
)
{
Class
<?>[]
gs
=
validatedAnn
.
value
();
result
=
validator
.
validate
(
array
[
i
],
gs
);
if
(!
result
.
isEmpty
())
{
throw
new
ConstraintViolationException
(
result
);
}
}
}
}
}
ApplyInfo
applyInfo
=
new
ApplyInfo
();
applyInfo
.
setApprove
(
approve
);
applyInfo
.
setValue
(
value
);
return
applyInfo
;
}
private
boolean
isFactoryBeanMetadataMethod
(
Method
method
)
{
Class
<?>
clazz
=
method
.
getDeclaringClass
();
// Call from interface-based proxy handle, allowing for an efficient check?
if
(
clazz
.
isInterface
())
{
return
((
clazz
==
FactoryBean
.
class
||
clazz
==
SmartFactoryBean
.
class
)
&&
!
"getObject"
.
equals
(
method
.
getName
()));
}
// Call from CGLIB proxy handle, potentially implementing a FactoryBean method?
Class
<?>
factoryBeanType
=
null
;
if
(
SmartFactoryBean
.
class
.
isAssignableFrom
(
clazz
))
{
factoryBeanType
=
SmartFactoryBean
.
class
;
}
else
if
(
FactoryBean
.
class
.
isAssignableFrom
(
clazz
))
{
factoryBeanType
=
FactoryBean
.
class
;
}
return
(
factoryBeanType
!=
null
&&
!
method
.
getName
().
equals
(
"getObject"
)
&&
ClassUtils
.
hasMethod
(
factoryBeanType
,
method
.
getName
(),
method
.
getParameterTypes
()));
}
/**
* Determine the validation groups to validate against for the given method
* invocation.
* <p>
* Default are the validation groups as specified in the {@link Validated}
* annotation on the containing target class of the method.
*
* @param method the current MethodInvocation
* @return the applicable validation groups as a Class array
*/
protected
Class
<?>[]
determineValidationGroups
(
Object
bean
,
Method
method
)
{
Validated
validatedAnn
=
AnnotationUtils
.
findAnnotation
(
method
,
Validated
.
class
);
if
(
validatedAnn
==
null
)
{
validatedAnn
=
AnnotationUtils
.
findAnnotation
(
bean
.
getClass
(),
Validated
.
class
);
}
return
(
validatedAnn
!=
null
?
validatedAnn
.
value
()
:
new
Class
<?>[
0
]);
}
}
core/src/main/java/com/wecloud/dispatch/general/impl/GeneralMethodArgumentResolver.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
general
.
impl
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.extend.ActionRequest
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
import
com.wecloud.dispatch.extend.MethodArgumentResolver
;
import
com.wecloud.utils.JsonUtils
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.convert.support.DefaultConversionService
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
class
GeneralMethodArgumentResolver
implements
MethodArgumentResolver
{
protected
final
DefaultConversionService
conversionService
=
new
DefaultConversionService
();
Map
<
Class
<?>,
Boolean
>
canNotInstanceMap
=
new
HashMap
<>();
@Override
public
boolean
supportsParameter
(
MethodParameter
parameter
)
{
// return parameter.hasParameterAnnotation(RequestParam.class);
return
true
;
}
@Override
public
Object
resolveArgument
(
ActionContext
actionContext
,
MethodParameter
parameter
,
ActionRequest
request
,
ArgumentBox
argumentBox
)
{
Object
object
=
null
;
RequestParam
define
=
parameter
.
getParameterAnnotation
(
RequestParam
.
class
);
// 获取属定义的名称
String
name
=
null
==
define
?
parameter
.
getParameterName
()
:
define
.
value
();
Type
t
=
parameter
.
getGenericParameterType
();
Class
<?>
clazz
=
parameter
.
getParameterType
();
Object
value
=
request
.
getData
().
get
(
name
);
if
(
value
instanceof
JSONObject
)
{
JSONObject
jo
=
(
JSONObject
)
value
;
if
(
isCustomMap
(
clazz
))
{
object
=
JSONObject
.
parseObject
(
jo
.
toJSONString
(),
clazz
);
}
else
{
object
=
jo
.
toJavaObject
(
t
);
}
}
else
if
(
value
instanceof
JSONArray
)
{
JSONArray
ja
=
(
JSONArray
)
value
;
object
=
ja
.
toJavaObject
(
t
);
}
else
if
(
value
instanceof
Map
)
{
if
(
clazz
.
isInstance
(
value
))
{
object
=
value
;
}
else
{
object
=
JsonUtils
.
mapToBean
((
Map
)
value
,
getObject
(
clazz
));
}
}
else
if
(
value
instanceof
List
)
{
if
(
clazz
.
isInstance
(
value
))
{
object
=
value
;
}
else
if
(
Set
.
class
.
isAssignableFrom
(
clazz
))
{
Set
objectSet
=
new
HashSet
();
Type
actualTypeArgument
=
((
ParameterizedType
)
parameter
.
getGenericParameterType
()).
getActualTypeArguments
()[
0
];
((
List
<
Map
<
String
,
Object
>>)
value
).
forEach
(
p
->
objectSet
.
add
(
JsonUtils
.
mapToBean
(
p
,
getObject
((
Class
)
actualTypeArgument
))));
object
=
objectSet
;
}
else
{
List
objectList
=
new
ArrayList
();
Type
actualTypeArgument
=
((
ParameterizedType
)
parameter
.
getGenericParameterType
()).
getActualTypeArguments
()[
0
];
((
List
<
Map
<
String
,
Object
>>)
value
).
forEach
(
p
->
objectList
.
add
(
JsonUtils
.
mapToBean
(
p
,
getObject
((
Class
)
actualTypeArgument
))));
object
=
objectList
;
}
}
else
if
(
null
!=
value
)
{
if
(
clazz
.
isInstance
(
value
))
{
object
=
value
;
}
else
{
if
(
conversionService
.
canConvert
(
value
.
getClass
(),
clazz
))
{
object
=
conversionService
.
convert
(
value
,
clazz
);
}
}
}
if
(
null
==
object
)
{
object
=
getDefaultValue
(
clazz
);
}
if
(
null
==
object
&&
isCanInstance
(
clazz
)
&&
!
canNotInstanceMap
.
containsKey
(
clazz
))
{
object
=
getObject
(
clazz
);
}
return
object
;
}
/**
*
* 是否可以被实例化
*
* @param classType
* @return
*/
private
boolean
isCanInstance
(
Class
<?>
classType
)
{
boolean
isAbstract
=
Modifier
.
isAbstract
(
classType
.
getModifiers
());
boolean
can
=
true
;
if
(
classType
.
isAnnotation
())
{
can
=
false
;
}
else
if
(
classType
.
isArray
())
{
can
=
false
;
}
else
if
(
classType
.
isEnum
())
{
can
=
false
;
}
else
if
(
classType
.
isInterface
())
{
can
=
false
;
}
else
if
(
isAbstract
)
{
can
=
false
;
}
return
can
;
}
private
<
T
>
Object
getObject
(
Class
<
T
>
clazz
)
{
Object
object
=
null
;
if
(
isCanInstance
(
clazz
)
&&
!
canNotInstanceMap
.
containsKey
(
clazz
))
{
try
{
object
=
clazz
.
newInstance
();
}
catch
(
InstantiationException
|
IllegalAccessException
e
)
{
canNotInstanceMap
.
put
(
clazz
,
false
);
}
}
return
object
;
}
/**
* @param clazz
* @return
*/
@SuppressWarnings
(
"unchecked"
)
public
<
T
>
T
getDefaultValue
(
Class
<
T
>
clazz
)
{
Object
object
=
null
;
if
(
List
.
class
.
isAssignableFrom
(
clazz
))
{
if
(
isCanInstance
(
clazz
))
{
object
=
getObject
(
clazz
);
}
else
{
object
=
new
ArrayList
<
Object
>(
0
);
}
}
else
if
(
Map
.
class
.
isAssignableFrom
(
clazz
))
{
if
(
isCanInstance
(
clazz
))
{
object
=
getObject
(
clazz
);
}
else
{
object
=
new
HashMap
<
Object
,
Object
>(
0
);
}
}
else
if
(
Set
.
class
.
isAssignableFrom
(
clazz
))
{
if
(
isCanInstance
(
clazz
))
{
object
=
getObject
(
clazz
);
}
else
{
object
=
new
HashSet
<
Object
>(
0
);
}
}
else
if
(
clazz
.
isArray
())
{
Class
<?>
componentType
=
clazz
.
getComponentType
();
object
=
Array
.
newInstance
(
componentType
,
0
);
}
else
if
(
clazz
==
int
.
class
)
{
object
=
0
;
}
else
if
(
clazz
==
long
.
class
)
{
object
=
0L
;
}
else
if
(
clazz
==
float
.
class
)
{
object
=
0.0
F
;
}
else
if
(
clazz
==
double
.
class
)
{
object
=
0.00
D
;
}
else
if
(
clazz
==
byte
.
class
)
{
object
=
(
byte
)
0
;
}
else
if
(
clazz
==
char
.
class
)
{
object
=
'\u0000'
;
}
else
if
(
clazz
==
short
.
class
)
{
object
=
0
;
}
else
if
(
clazz
==
boolean
.
class
)
{
object
=
false
;
}
return
((
T
)
object
);
}
/**
* 是否自定义实现Map
*
* @param clazz
* @return
*/
boolean
isCustomMap
(
Class
<?>
clazz
)
{
boolean
isMap
=
Map
.
class
.
isAssignableFrom
(
clazz
);
boolean
isSubMap
=
java
.
util
.
HashMap
.
class
==
clazz
||
java
.
util
.
Hashtable
.
class
==
clazz
||
java
.
util
.
TreeMap
.
class
==
clazz
||
java
.
util
.
IdentityHashMap
.
class
==
clazz
||
java
.
util
.
WeakHashMap
.
class
==
clazz
||
java
.
util
.
LinkedHashMap
.
class
==
clazz
;
return
isMap
&&
!
isSubMap
;
}
boolean
isCollection
(
Class
<?>
clazz
)
{
return
Collection
.
class
.
isAssignableFrom
(
clazz
);
}
}
core/src/main/java/com/wecloud/dispatch/registry/ActionBoxRegistry.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
registry
;
import
com.wecloud.dispatch.extend.ActionBox
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author lixiaozhong
*/
public
class
ActionBoxRegistry
{
List
<
ActionBox
>
list
=
new
ArrayList
<>();
public
void
add
(
ActionBox
actionBox
)
{
list
.
add
(
actionBox
);
}
public
Object
getAction
(
Class
<?>
type
)
{
Object
o
=
null
;
for
(
ActionBox
ab
:
list
)
{
o
=
ab
.
getAction
(
type
);
if
(
null
!=
o
)
{
return
o
;
}
}
return
null
;
}
}
core/src/main/java/com/wecloud/dispatch/registry/ActionInterceptorRegistry.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
registry
;
import
com.wecloud.dispatch.extend.ActionInterceptor
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author lixiaozhong
*/
public
class
ActionInterceptorRegistry
{
List
<
ActionInterceptor
>
list
=
new
ArrayList
<>();
public
void
add
(
ActionInterceptor
actionInterceptor
)
{
list
.
add
(
actionInterceptor
);
}
public
List
<
ActionInterceptor
>
getActionInterceptorList
()
{
return
list
;
};
}
core/src/main/java/com/wecloud/dispatch/registry/ActionMethodInterceptorRegistry.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
registry
;
import
com.wecloud.dispatch.extend.ActionMethodInterceptor
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author lixiaozhong
*/
public
class
ActionMethodInterceptorRegistry
{
List
<
ActionMethodInterceptor
>
list
=
new
ArrayList
<>();
public
void
add
(
ActionMethodInterceptor
actionInterceptor
)
{
list
.
add
(
actionInterceptor
);
}
public
List
<
ActionMethodInterceptor
>
getList
()
{
return
list
;
};
}
core/src/main/java/com/wecloud/dispatch/registry/ActionRegistry.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
registry
;
import
com.wecloud.dispatch.annotation.ActionMapping
;
import
com.wecloud.dispatch.common.ActionMethod
;
import
com.wecloud.dispatch.exception.MappingException
;
import
org.springframework.http.server.PathContainer
;
import
org.springframework.util.AntPathMatcher
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.util.pattern.PathPattern
;
import
org.springframework.web.util.pattern.PathPatternParser
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.stream.Collectors
;
/**
* @author lixiaozhong
*/
public
class
ActionRegistry
{
private
final
Map
<
PathPattern
,
ActionMethod
>
actionMethodMap
=
new
ConcurrentHashMap
<>(
16
);
private
String
separator
=
AntPathMatcher
.
DEFAULT_PATH_SEPARATOR
;
private
AntPathMatcher
pathMatcher
=
new
AntPathMatcher
();
private
final
PathPatternParser
patternParser
=
new
PathPatternParser
();;
/**
* 为了更快获取要执行的action,将要执行的action加入Map进行缓存
*
* @param classType
* @throws MappingException
*/
public
void
add
(
Class
<?>
classType
)
{
Annotation
[]
as
=
classType
.
getAnnotations
();
ActionMapping
am
=
null
;
for
(
Annotation
annotation
:
as
)
{
if
(
annotation
instanceof
ActionMapping
)
{
am
=
((
ActionMapping
)
annotation
);
break
;
}
}
String
[]
codes
=
null
==
am
?
new
String
[]
{
""
}
:
am
.
value
();
add
(
codes
,
classType
);
}
/**
* 获取要执行的action的方法,并且缓存
*
* @param classType
* @return
* @throws MappingException
*/
public
void
add
(
String
[]
codes
,
Class
<?>
classType
)
{
Method
[]
methods
=
classType
.
getMethods
();
if
(
null
!=
methods
&&
methods
.
length
>
0
)
{
for
(
Method
method
:
methods
)
{
add
(
codes
,
method
);
}
}
}
public
void
add
(
Method
method
)
{
if
(
null
!=
method
)
{
Annotation
[]
as
=
method
.
getDeclaringClass
().
getAnnotations
();
ActionMapping
am
=
null
;
for
(
Annotation
annotation
:
as
)
{
if
(
annotation
instanceof
ActionMapping
)
{
am
=
((
ActionMapping
)
annotation
);
break
;
}
}
String
[]
codes
=
null
==
am
?
new
String
[]
{
""
}
:
am
.
value
();
add
(
codes
,
method
);
}
}
public
void
add
(
String
[]
codes
,
Method
method
)
{
if
(
null
!=
method
)
{
codes
=
(
null
==
codes
)
?
new
String
[]
{
""
}
:
codes
;
Annotation
[]
as
=
method
.
getAnnotations
();
for
(
Annotation
a
:
as
)
{
if
(
a
instanceof
ActionMapping
)
{
ActionMapping
actionMapping
=
(
ActionMapping
)
a
;
String
[]
values
=
actionMapping
.
value
();
int
order
=
actionMapping
.
order
();
List
<
String
>
paths
=
getPaths
(
codes
,
values
);
if
(
null
!=
paths
)
{
for
(
String
path
:
paths
)
{
ActionMethod
am
=
getActionMethod
(
path
);
boolean
equals
=
false
;
if
(
null
!=
am
)
{
equals
=
null
!=
am
.
getMethodPath
()
&&
am
.
getMethodPath
().
equals
(
path
);
}
if
(
null
!=
am
&&
equals
)
{
Method
lastMethod
=
am
.
getMethod
();
if
(
method
.
equals
(
lastMethod
))
{
continue
;
}
ActionMapping
lastMapping
=
am
.
getMethod
().
getAnnotation
(
ActionMapping
.
class
);
int
lastOrder
=
lastMapping
.
order
();
if
(
order
==
lastOrder
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"\n"
);
sb
.
append
(
"ActionMapping:"
);
sb
.
append
(
"\n"
);
sb
.
append
(
"["
);
sb
.
append
(
am
.
getActionClass
().
getName
());
sb
.
append
(
"]"
);
sb
.
append
(
"."
);
sb
.
append
(
"["
);
sb
.
append
(
am
.
getMethod
().
getName
());
sb
.
append
(
"]"
);
sb
.
append
(
"\n"
);
sb
.
append
(
"与"
);
sb
.
append
(
"\n"
);
sb
.
append
(
"["
);
sb
.
append
(
method
.
getDeclaringClass
().
getName
());
sb
.
append
(
"]"
);
sb
.
append
(
"."
);
sb
.
append
(
"["
);
sb
.
append
(
method
.
getName
());
sb
.
append
(
"]"
);
sb
.
append
(
"\n"
);
sb
.
append
(
"存在重复"
);
sb
.
append
(
"["
);
sb
.
append
(
path
);
sb
.
append
(
"]!"
);
throw
new
MappingException
(
sb
.
toString
());
}
else
if
(
order
<
lastOrder
)
{
put
(
path
,
new
ActionMethod
(
method
,
path
));
}
}
else
{
put
(
path
,
new
ActionMethod
(
method
,
path
));
}
}
}
break
;
}
}
}
}
public
void
cover
(
Class
<?>
classType
)
{
Annotation
[]
as
=
classType
.
getAnnotations
();
ActionMapping
am
=
null
;
for
(
Annotation
annotation
:
as
)
{
if
(
annotation
instanceof
ActionMapping
)
{
am
=
((
ActionMapping
)
annotation
);
break
;
}
}
String
[]
value
=
null
==
am
?
new
String
[]
{
""
}
:
am
.
value
();
cover
(
value
,
classType
);
}
public
void
cover
(
String
[]
codes
,
Class
<?>
classType
)
{
Method
[]
methods
=
classType
.
getMethods
();
if
(
null
!=
methods
&&
methods
.
length
>
0
)
{
for
(
Method
method
:
methods
)
{
Annotation
[]
as
=
method
.
getAnnotations
();
for
(
Annotation
a
:
as
)
{
if
(
a
instanceof
ActionMapping
)
{
String
[]
values
=
((
ActionMapping
)
a
).
value
();
List
<
String
>
paths
=
getPaths
(
codes
,
values
);
cover
(
paths
,
method
);
break
;
}
}
}
}
}
public
void
cover
(
List
<
String
>
paths
,
Method
method
)
{
if
(
null
!=
paths
&&
null
!=
method
)
{
for
(
String
path
:
paths
)
{
cover
(
path
,
method
);
}
}
}
public
void
cover
(
String
path
,
Method
method
)
{
if
(
null
!=
path
&&
null
!=
method
)
{
put
(
path
,
new
ActionMethod
(
method
,
path
));
}
}
public
void
put
(
String
path
,
ActionMethod
am
)
{
PathPattern
pattern
=
patternParser
.
parse
(
path
);
actionMethodMap
.
put
(
pattern
,
am
);
}
public
boolean
has
(
String
path
)
{
ActionMethod
method
=
path
==
null
||
path
.
isEmpty
()
?
null
:
lookupHandler
(
PathContainer
.
parsePath
(
path
));
return
null
!=
method
;
}
public
ActionMethod
lookupHandler
(
PathContainer
lookupPath
)
{
ActionMethod
am
=
null
;
List
<
PathPattern
>
matches
=
this
.
actionMethodMap
.
keySet
().
stream
()
.
filter
(
key
->
key
.
matches
(
lookupPath
))
.
collect
(
Collectors
.
toList
());
if
(
matches
.
isEmpty
())
{
return
null
;
}
if
(
matches
.
size
()
>
1
)
{
matches
.
sort
(
PathPattern
.
SPECIFICITY_COMPARATOR
);
}
PathPattern
pattern
=
matches
.
get
(
0
);
am
=
this
.
actionMethodMap
.
get
(
pattern
);
return
am
;
}
/**
* 截取不包含包名,和小写首字母的类名
*
* @param classType
* @return
*/
public
String
getSimpleNameAsProperty
(
Class
<?>
classType
)
{
String
valueName
=
classType
.
getSimpleName
();
return
valueName
=
valueName
.
substring
(
0
,
1
).
toLowerCase
()
+
valueName
.
substring
(
1
);
}
public
Class
<?>
getClass
(
String
path
)
{
ActionMethod
am
=
getActionMethod
(
path
);
return
null
==
am
?
null
:
am
.
getActionClass
();
}
public
ActionMethod
getActionMethod
(
String
path
)
{
// ActionMethod method = actionMethodMap.get(path == null ? "" : path);
ActionMethod
method
=
path
==
null
||
path
.
isEmpty
()
?
null
:
lookupHandler
(
PathContainer
.
parsePath
(
path
));
return
method
;
}
public
ActionMethod
getActionMethod
(
String
classCode
,
String
methodCode
)
{
String
path
=
getPath
(
classCode
,
methodCode
);
return
getActionMethod
(
path
);
}
public
List
<
String
>
getPaths
(
String
[]
classCodes
,
String
[]
methodCodes
)
{
classCodes
=
(
null
==
classCodes
||
classCodes
.
length
==
0
)
?
new
String
[]
{
""
}
:
classCodes
;
methodCodes
=
(
null
==
methodCodes
||
methodCodes
.
length
==
0
)
?
new
String
[]
{
""
}
:
methodCodes
;
List
<
String
>
list
=
new
ArrayList
<>();
for
(
String
classCode
:
classCodes
)
{
for
(
String
methodCode
:
methodCodes
)
{
list
.
add
(
getPath
(
classCode
,
methodCode
));
}
}
return
list
;
}
public
String
getPath
(
String
classCode
,
String
methodCode
)
{
// StringBuilder sb = new StringBuilder();
String
path
=
pathMatcher
.
combine
(
classCode
,
methodCode
);
// if (isSeparateAlways()) {
// sb.append(getSeparator());
// } else if (null != classCode && !classCode.isEmpty() && !classCode.startsWith(getSeparator())) {
// sb.append(getSeparator());
// }
// sb.append(classCode);
// if (isSeparateAlways()) {
// sb.append(getSeparator());
// } else if (!methodCode.startsWith(getSeparator())) {
// sb.append(getSeparator());
// }
// sb.append(methodCode);
path
=
prependLeadingSlash
(
path
);
return
path
;
}
private
static
String
prependLeadingSlash
(
String
pattern
)
{
String
pre
=
"/"
;
if
(
StringUtils
.
hasLength
(
pattern
)
&&
!
pattern
.
startsWith
(
pre
))
{
return
pre
+
pattern
;
}
else
{
return
pattern
;
}
}
public
Map
<
PathPattern
,
ActionMethod
>
getActionMethodMap
()
{
return
actionMethodMap
;
}
public
String
getSeparator
()
{
return
separator
;
}
public
void
setSeparator
(
String
separator
)
{
this
.
separator
=
separator
;
pathMatcher
.
setPathSeparator
(
separator
);
}
// public boolean isSeparateAlways() {
// return separateAlways;
// }
//
// public void setSeparateAlways(boolean separateAlways) {
// this.separateAlways = separateAlways;
// }
//
// public void setSeparator(String separator, boolean separateAlways) {
// this.separator = separator;
// this.separateAlways = separateAlways;
// pathMatcher.setPathSeparator(separator);
// }
}
core/src/main/java/com/wecloud/dispatch/registry/ArgumentDefaultValueBuilderRegistry.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
registry
;
import
com.wecloud.dispatch.extend.ArgumentDefaultValueBuilder
;
import
com.wecloud.dispatch.extend.impl.DefaultArgumentDefaultValueBuilder
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author lixiaozhong
*/
public
class
ArgumentDefaultValueBuilderRegistry
{
List
<
ArgumentDefaultValueBuilder
>
list
=
new
ArrayList
<>();
ArgumentDefaultValueBuilder
b
=
new
DefaultArgumentDefaultValueBuilder
();
public
void
add
(
ArgumentDefaultValueBuilder
builder
)
{
list
.
add
(
builder
);
}
public
Object
getValue
(
Class
<?>
type
)
{
Object
o
=
null
;
for
(
ArgumentDefaultValueBuilder
ab
:
list
)
{
o
=
ab
.
build
(
type
);
if
(
null
!=
o
)
{
return
o
;
}
}
o
=
b
.
build
(
type
);
return
o
;
}
}
core/src/main/java/com/wecloud/dispatch/registry/MethodArgumentResolverRegistry.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
registry
;
import
com.wecloud.dispatch.ActionContext
;
import
com.wecloud.dispatch.extend.ActionRequest
;
import
com.wecloud.dispatch.extend.ArgumentBox
;
import
com.wecloud.dispatch.extend.MethodArgumentResolver
;
import
org.springframework.core.MethodParameter
;
import
java.util.LinkedList
;
import
java.util.List
;
/**
* @author lixiaozhong
*/
public
class
MethodArgumentResolverRegistry
{
List
<
MethodArgumentResolver
>
list
=
new
LinkedList
<>();
public
void
add
(
MethodArgumentResolver
mar
)
{
list
.
add
(
mar
);
}
public
boolean
supportsParameter
(
MethodParameter
parameter
)
{
return
(
getArgumentResolver
(
parameter
)
!=
null
);
}
public
Object
resolveArgument
(
ActionContext
actionContext
,
MethodParameter
parameter
,
ActionRequest
request
,
ArgumentBox
argumentBox
)
{
MethodArgumentResolver
resolver
=
getArgumentResolver
(
parameter
);
if
(
resolver
==
null
)
{
throw
new
IllegalArgumentException
(
"Unknown parameter type ["
+
parameter
.
getParameterType
().
getName
()
+
"]"
);
}
return
resolver
.
resolveArgument
(
actionContext
,
parameter
,
request
,
argumentBox
);
}
private
MethodArgumentResolver
getArgumentResolver
(
MethodParameter
parameter
)
{
MethodArgumentResolver
result
=
null
;
for
(
MethodArgumentResolver
methodArgumentResolver
:
this
.
list
)
{
if
(
methodArgumentResolver
.
supportsParameter
(
parameter
))
{
result
=
methodArgumentResolver
;
break
;
}
}
return
result
;
}
}
core/src/main/java/com/wecloud/dispatch/util/ClassScaner.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
util
;
import
org.springframework.core.io.Resource
;
import
org.springframework.core.io.ResourceLoader
;
import
org.springframework.core.io.support.PathMatchingResourcePatternResolver
;
import
org.springframework.core.io.support.ResourcePatternResolver
;
import
org.springframework.core.type.classreading.CachingMetadataReaderFactory
;
import
org.springframework.core.type.classreading.MetadataReader
;
import
org.springframework.core.type.classreading.MetadataReaderFactory
;
import
org.springframework.core.type.filter.AnnotationTypeFilter
;
import
org.springframework.core.type.filter.TypeFilter
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.SystemPropertyUtils
;
import
java.io.IOException
;
import
java.lang.annotation.Annotation
;
import
java.util.HashSet
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Set
;
/**
* @author lixiaozhong
*/
public
class
ClassScaner
{
private
ResourcePatternResolver
resourcePatternResolver
=
new
PathMatchingResourcePatternResolver
();
private
final
List
<
TypeFilter
>
includeFilters
=
new
LinkedList
<
TypeFilter
>();
private
final
List
<
TypeFilter
>
excludeFilters
=
new
LinkedList
<
TypeFilter
>();
private
MetadataReaderFactory
metadataReaderFactory
=
new
CachingMetadataReaderFactory
(
this
.
resourcePatternResolver
);
public
ClassScaner
()
{
}
public
final
ResourceLoader
getResourceLoader
()
{
return
this
.
resourcePatternResolver
;
}
public
void
addIncludeFilter
(
TypeFilter
includeFilter
)
{
this
.
includeFilters
.
add
(
includeFilter
);
}
public
void
addExcludeFilter
(
TypeFilter
excludeFilter
)
{
this
.
excludeFilters
.
add
(
0
,
excludeFilter
);
}
public
void
resetFilters
()
{
this
.
includeFilters
.
clear
();
this
.
excludeFilters
.
clear
();
}
public
Set
<
Class
<?>>
doScan
(
String
basePackage
)
{
Set
<
Class
<?>>
classes
=
new
HashSet
<
Class
<?>>();
try
{
String
packageSearchPath
=
ResourcePatternResolver
.
CLASSPATH_ALL_URL_PREFIX
+
org
.
springframework
.
util
.
ClassUtils
.
convertClassNameToResourcePath
(
SystemPropertyUtils
.
resolvePlaceholders
(
basePackage
))
+
"/**/*.class"
;
Resource
[]
resources
=
this
.
resourcePatternResolver
.
getResources
(
packageSearchPath
);
for
(
int
i
=
0
;
i
<
resources
.
length
;
i
++)
{
Resource
resource
=
resources
[
i
];
if
(
resource
.
isReadable
())
{
MetadataReader
metadataReader
=
this
.
metadataReaderFactory
.
getMetadataReader
(
resource
);
// boolean isEmpty = (includeFilters.size() == 0 && excludeFilters.size() == 0);
// if (isEmpty || matches(metadataReader)) {
if
(
matches
(
metadataReader
))
{
String
className
=
metadataReader
.
getClassMetadata
().
getClassName
();
boolean
isPresent
=
ClassUtils
.
isPresent
(
className
,
ClassScaner
.
class
.
getClassLoader
());
if
(
isPresent
)
{
Class
<?>
classType
=
getClassByName
(
className
);
if
(
null
!=
classType
)
{
classes
.
add
(
classType
);
}
}
}
}
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
return
classes
;
}
public
Class
<?>
getClassByName
(
String
className
)
{
try
{
return
Class
.
forName
(
className
);
}
catch
(
ClassNotFoundException
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
public
boolean
matches
(
MetadataReader
metadataReader
)
{
for
(
TypeFilter
tf
:
this
.
excludeFilters
)
{
try
{
if
(
tf
.
match
(
metadataReader
,
this
.
metadataReaderFactory
))
{
return
false
;
}
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
if
(
includeFilters
.
isEmpty
())
{
return
true
;
}
for
(
TypeFilter
tf
:
this
.
includeFilters
)
{
try
{
if
(
tf
.
match
(
metadataReader
,
this
.
metadataReaderFactory
))
{
return
true
;
}
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
}
return
false
;
}
public
static
Set
<
Class
<?>>
scan
(
String
...
basePackages
)
{
ClassScaner
cs
=
new
ClassScaner
();
Set
<
Class
<?>>
classes
=
new
HashSet
<
Class
<?>>();
for
(
String
s
:
basePackages
)
{
classes
.
addAll
(
cs
.
doScan
(
s
));
}
return
classes
;
}
public
static
Set
<
Class
<?>>
scan
(
List
<
String
>
basePackages
)
{
ClassScaner
cs
=
new
ClassScaner
();
Set
<
Class
<?>>
classes
=
new
HashSet
<
Class
<?>>();
for
(
String
s
:
basePackages
)
{
classes
.
addAll
(
cs
.
doScan
(
s
));
}
return
classes
;
}
public
static
Set
<
Class
<?>>
scan
(
String
basePackage
)
{
ClassScaner
cs
=
new
ClassScaner
();
return
cs
.
doScan
(
basePackage
);
}
@SuppressWarnings
(
"unchecked"
)
public
static
Set
<
Class
<?>>
scan
(
String
basePackage
,
Class
<?
extends
Annotation
>...
annotations
)
{
ClassScaner
cs
=
new
ClassScaner
();
for
(
Class
<?
extends
Annotation
>
anno
:
annotations
)
{
cs
.
addIncludeFilter
(
new
AnnotationTypeFilter
(
anno
));
}
return
cs
.
doScan
(
basePackage
);
}
@SuppressWarnings
({
"unchecked"
})
public
static
Set
<
Class
<?>>
scan
(
String
[]
basePackages
,
Class
<?
extends
Annotation
>...
annotations
)
{
ClassScaner
cs
=
new
ClassScaner
();
for
(
Class
<?
extends
Annotation
>
anno
:
annotations
)
{
cs
.
addIncludeFilter
(
new
AnnotationTypeFilter
(
anno
));
}
Set
<
Class
<?>>
classes
=
new
HashSet
<
Class
<?>>();
for
(
String
s
:
basePackages
)
{
classes
.
addAll
(
cs
.
doScan
(
s
));
}
return
classes
;
}
}
core/src/main/java/com/wecloud/dispatch/util/ClassUtil.java
0 → 100644
View file @
a7892caa
package
com
.
wecloud
.
dispatch
.
util
;
import
java.lang.reflect.Modifier
;
/**
* @author lixiaozhong
*/
public
class
ClassUtil
{
/**
* 是否可被实例化
*
* @param classType
* @return
*/
public
static
boolean
isCanInstance
(
Class
<?>
classType
)
{
boolean
can
=
true
;
boolean
isAbstract
=
Modifier
.
isAbstract
(
classType
.
getModifiers
());
if
(
classType
.
isAnnotation
())
{
can
=
false
;
}
else
if
(
classType
.
isEnum
())
{
can
=
false
;
}
else
if
(
classType
.
isInterface
())
{
can
=
false
;
}
else
if
(
isAbstract
)
{
can
=
false
;
}
else
if
(
classType
.
isArray
())
{
can
=
false
;
}
return
can
;
}
}
core/src/main/java/com/wecloud/im/netty/core/WsReadHandler.java
View file @
a7892caa
package
com
.
wecloud
.
im
.
netty
.
core
;
import
com.wecloud.dispatch.general.GeneralMessageHandler
;
import
com.wecloud.im.executor.BusinessThreadPool
;
import
com.wecloud.im.ws.manager.ChannelManager
;
import
com.wecloud.im.ws.strategy.AbstractImCmdStrategy
;
...
...
@@ -30,6 +31,9 @@ public class WsReadHandler extends SimpleChannelInboundHandler<TextWebSocketFram
@Resource
private
ChannelManager
channelManager
;
@Resource
private
GeneralMessageHandler
generalMessageHandler
;
@Override
protected
void
channelRead0
(
ChannelHandlerContext
ctx
,
TextWebSocketFrame
msg
)
{
// 读空闲的计数清零
...
...
@@ -70,6 +74,8 @@ public class WsReadHandler extends SimpleChannelInboundHandler<TextWebSocketFram
}
AbstractImCmdStrategy
.
process
(
clientId
,
ctx
,
data
);
generalMessageHandler
.
doMessage
(
clientId
,
ctx
,
data
);
}
catch
(
Exception
e
)
{
log
.
error
(
"系统繁忙data:"
+
data
+
",clientId:"
+
clientId
+
...
...
core/src/main/java/com/wecloud/im/ws/ImConstant.java
View file @
a7892caa
...
...
@@ -64,4 +64,6 @@ public class ImConstant implements Serializable {
*/
public
static
final
String
MSG_TYPE
=
"type"
;
public
static
final
String
CMD
=
"cmd"
;
}
core/src/main/java/com/wecloud/im/ws/sender/ChannelSender.java
View file @
a7892caa
...
...
@@ -153,6 +153,20 @@ public class ChannelSender {
* @param nioSocketChannel
* @param responseModel
*/
public
void
sendMsgLocal
(
NioSocketChannel
nioSocketChannel
,
Object
responseModel
)
{
String
msgJson
=
JsonUtils
.
encodeJson
(
responseModel
);
// 本地直接下发
nioSocketChannel
.
writeAndFlush
(
new
TextWebSocketFrame
(
msgJson
));
}
/**
* 本地直接下发,限定本机有的channel
*
* @param nioSocketChannel
* @param responseModel
*/
public
void
sendMsgLocal
(
NioSocketChannel
nioSocketChannel
,
WsResponse
responseModel
)
{
String
msgJson
=
JsonUtils
.
encodeJson
(
responseModel
);
...
...
core/src/main/java/com/wecloud/utils/JsonUtils.java
View file @
a7892caa
package
com
.
wecloud
.
utils
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.DeserializationFeature
;
import
com.fasterxml.jackson.databind.JavaType
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.wecloud.im.ws.model.request.ReceiveVO
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.cglib.beans.BeanMap
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* fasterxml 的json工具类
...
...
@@ -21,6 +25,9 @@ import java.util.List;
public
class
JsonUtils
{
private
static
final
ObjectMapper
OBJECT_MAPPER
=
new
ObjectMapper
();
static
{
OBJECT_MAPPER
.
configure
(
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
,
false
);
}
/**
* Json格式的字符串向JavaBean转换,传入空串将返回null
...
...
@@ -179,4 +186,49 @@ public class JsonUtils {
return
null
;
}
}
/**
* 判断字符也许是JSON
*
* @param string
* @return
*/
public
static
boolean
maybeJson
(
String
string
)
{
return
maybeJsonArray
(
string
)
||
maybeJsonObject
(
string
);
}
/**
* 判断字符也许是JSONArray
*
* @param string
* @return
*/
public
static
boolean
maybeJsonArray
(
String
string
)
{
string
=
(
null
==
string
)
?
string
:
string
.
trim
();
return
string
!=
null
&&
(
"null"
.
equals
(
string
)
||
(
string
.
startsWith
(
"["
)
&&
string
.
endsWith
(
"]"
)));
}
/**
* 判断字符也许是JSONObject
*
* @param string
* @return
*/
public
static
boolean
maybeJsonObject
(
String
string
)
{
string
=
(
null
==
string
)
?
string
:
string
.
trim
();
return
string
!=
null
&&
(
"null"
.
equals
(
string
)
||
(
string
.
startsWith
(
"{"
)
&&
string
.
endsWith
(
"}"
)));
}
/**
* 将map装换为javabean对象
*
* @param map
* @param bean
* @return
*/
public
static
<
T
>
T
mapToBean
(
Map
<
String
,
Object
>
map
,
T
bean
)
{
BeanMap
beanMap
=
BeanMap
.
create
(
bean
);
beanMap
.
putAll
(
map
);
return
bean
;
}
}
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