Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
8c838071
S
spring-framework
项目概览
爱吃血肠
/
spring-framework
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
spring-framework
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
8c838071
编写于
12月 14, 2015
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Polishing (backported from master)
上级
b64d7529
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
237 addition
and
213 deletion
+237
-213
spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
...ngframework/expression/spel/ast/ConstructorReference.java
+6
-7
spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
...pringframework/expression/spel/ast/FunctionReference.java
+15
-14
spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
...java/org/springframework/expression/spel/ast/Indexer.java
+16
-15
spring-expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java
...org/springframework/expression/spel/ast/SpelNodeImpl.java
+12
-12
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java
...ngframework/expression/spel/support/ReflectionHelper.java
+5
-3
spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/AbstractPromiseToListenableFutureAdapter.java
...tcp/reactor/AbstractPromiseToListenableFutureAdapter.java
+7
-5
spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/Reactor11TcpClient.java
...ngframework/messaging/tcp/reactor/Reactor11TcpClient.java
+5
-18
spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java
...eb/servlet/config/ViewControllerBeanDefinitionParser.java
+9
-6
spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java
...eb/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java
+16
-15
spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapter.java
...ket/adapter/standard/StandardWebSocketHandlerAdapter.java
+17
-17
spring-websocket/src/main/java/org/springframework/web/socket/handler/ExceptionWebSocketHandlerDecorator.java
...eb/socket/handler/ExceptionWebSocketHandlerDecorator.java
+24
-21
spring-websocket/src/main/java/org/springframework/web/socket/handler/PerConnectionWebSocketHandler.java
...ork/web/socket/handler/PerConnectionWebSocketHandler.java
+24
-18
spring-websocket/src/main/java/org/springframework/web/socket/messaging/SubProtocolWebSocketHandler.java
...ork/web/socket/messaging/SubProtocolWebSocketHandler.java
+81
-62
未找到文件。
spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -445,15 +445,14 @@ public class ConstructorReference extends SpelNodeImpl {
public
void
generateCode
(
MethodVisitor
mv
,
CodeFlow
cf
)
{
ReflectiveConstructorExecutor
executor
=
((
ReflectiveConstructorExecutor
)
this
.
cachedExecutor
);
Constructor
<?>
constructor
=
executor
.
getConstructor
();
String
class
SlashedDescriptor
=
constructor
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
mv
.
visitTypeInsn
(
NEW
,
class
SlashedDescriptor
);
String
class
Desc
=
constructor
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
mv
.
visitTypeInsn
(
NEW
,
class
Desc
);
mv
.
visitInsn
(
DUP
);
// children[0] is the type of the constructor, don't want to include that in argument processing
SpelNodeImpl
[]
arguments
=
new
SpelNodeImpl
[
children
.
length
-
1
];
System
.
arraycopy
(
children
,
1
,
arguments
,
0
,
children
.
length
-
1
);
SpelNodeImpl
[]
arguments
=
new
SpelNodeImpl
[
children
.
length
-
1
];
System
.
arraycopy
(
children
,
1
,
arguments
,
0
,
children
.
length
-
1
);
generateCodeForArguments
(
mv
,
cf
,
constructor
,
arguments
);
mv
.
visitMethodInsn
(
INVOKESPECIAL
,
classSlashedDescriptor
,
"<init>"
,
CodeFlow
.
createSignatureDescriptor
(
constructor
),
false
);
mv
.
visitMethodInsn
(
INVOKESPECIAL
,
classDesc
,
"<init>"
,
CodeFlow
.
createSignatureDescriptor
(
constructor
),
false
);
cf
.
pushDescriptor
(
this
.
exitTypeDescriptor
);
}
...
...
spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -33,15 +33,15 @@ import org.springframework.expression.spel.support.ReflectionHelper;
import
org.springframework.util.ReflectionUtils
;
/**
* A function reference is of the form "#someFunction(a,b,c)". Functions may be defined
in
* the context prior to the expression being evaluated or within the expression itself
* A function reference is of the form "#someFunction(a,b,c)". Functions may be defined
*
in
the context prior to the expression being evaluated or within the expression itself
* using a lambda function definition. For example: Lambda function definition in an
* expression: "(#max = {|x,y|$x>$y?$x:$y};max(2,3))" Calling context defined function:
* "#isEven(37)". Functions may also be static java methods, registered in the context
* prior to invocation of the expression.
*
* <p>Functions are very simplistic, the arguments are not part of the definition
(right
* now), so the names must be unique.
* <p>Functions are very simplistic, the arguments are not part of the definition
*
(right
now), so the names must be unique.
*
* @author Andy Clement
* @since 3.0
...
...
@@ -72,7 +72,8 @@ public class FunctionReference extends SpelNodeImpl {
// Two possibilities: a lambda function or a Java static method registered as a function
if
(!(
value
.
getValue
()
instanceof
Method
))
{
throw
new
SpelEvaluationException
(
SpelMessage
.
FUNCTION_REFERENCE_CANNOT_BE_INVOKED
,
this
.
name
,
value
.
getClass
());
throw
new
SpelEvaluationException
(
SpelMessage
.
FUNCTION_REFERENCE_CANNOT_BE_INVOKED
,
this
.
name
,
value
.
getClass
());
}
try
{
...
...
@@ -113,7 +114,8 @@ public class FunctionReference extends SpelNodeImpl {
argumentConversionOccurred
=
ReflectionHelper
.
convertAllArguments
(
converter
,
functionArgs
,
method
);
}
if
(
method
.
isVarArgs
())
{
functionArgs
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
method
.
getParameterTypes
(),
functionArgs
);
functionArgs
=
ReflectionHelper
.
setupArgumentsForVarargsInvocation
(
method
.
getParameterTypes
(),
functionArgs
);
}
try
{
...
...
@@ -160,13 +162,12 @@ public class FunctionReference extends SpelNodeImpl {
@Override
public
boolean
isCompilable
()
{
if
(
this
.
method
==
null
||
argumentConversionOccurred
)
{
if
(
this
.
method
==
null
||
this
.
argumentConversionOccurred
)
{
return
false
;
}
int
methodModifiers
=
this
.
method
.
getModifiers
();
if
(!
Modifier
.
isStatic
(
methodModifiers
)
||
!
Modifier
.
isPublic
(
methodModifiers
)
||
!
Modifier
.
isPublic
(
method
.
getDeclaringClass
().
getModifiers
()))
{
if
(!
Modifier
.
isStatic
(
methodModifiers
)
||
!
Modifier
.
isPublic
(
methodModifiers
)
||
!
Modifier
.
isPublic
(
this
.
method
.
getDeclaringClass
().
getModifiers
()))
{
return
false
;
}
for
(
SpelNodeImpl
child
:
this
.
children
)
{
...
...
@@ -179,9 +180,9 @@ public class FunctionReference extends SpelNodeImpl {
@Override
public
void
generateCode
(
MethodVisitor
mv
,
CodeFlow
cf
)
{
String
methodDeclaringClassSlashedDescriptor
=
this
.
method
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
generateCodeForArguments
(
mv
,
cf
,
method
,
this
.
children
);
mv
.
visitMethodInsn
(
INVOKESTATIC
,
methodDeclaringClassSlashedDescriptor
,
this
.
method
.
getName
(),
String
classDesc
=
this
.
method
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
generateCodeForArguments
(
mv
,
cf
,
this
.
method
,
this
.
children
);
mv
.
visitMethodInsn
(
INVOKESTATIC
,
classDesc
,
this
.
method
.
getName
(),
CodeFlow
.
createSignatureDescriptor
(
this
.
method
),
false
);
cf
.
pushDescriptor
(
this
.
exitTypeDescriptor
);
}
...
...
spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -248,6 +248,7 @@ public class Indexer extends SpelNodeImpl {
cf
.
exitCompilationScope
();
mv
.
visitInsn
(
insn
);
}
else
if
(
this
.
indexedType
==
IndexedType
.
LIST
)
{
mv
.
visitTypeInsn
(
CHECKCAST
,
"java/util/List"
);
cf
.
enterCompilationScope
();
...
...
@@ -255,6 +256,7 @@ public class Indexer extends SpelNodeImpl {
cf
.
exitCompilationScope
();
mv
.
visitMethodInsn
(
INVOKEINTERFACE
,
"java/util/List"
,
"get"
,
"(I)Ljava/lang/Object;"
,
true
);
}
else
if
(
this
.
indexedType
==
IndexedType
.
MAP
)
{
mv
.
visitTypeInsn
(
CHECKCAST
,
"java/util/Map"
);
// Special case when the key is an unquoted string literal that will be parsed as
...
...
@@ -271,27 +273,30 @@ public class Indexer extends SpelNodeImpl {
}
mv
.
visitMethodInsn
(
INVOKEINTERFACE
,
"java/util/Map"
,
"get"
,
"(Ljava/lang/Object;)Ljava/lang/Object;"
,
true
);
}
else
if
(
this
.
indexedType
==
IndexedType
.
OBJECT
)
{
ReflectivePropertyAccessor
.
OptimalPropertyAccessor
accessor
=
(
ReflectivePropertyAccessor
.
OptimalPropertyAccessor
)
this
.
cachedReadAccessor
;
Member
member
=
accessor
.
member
;
boolean
isStatic
=
Modifier
.
isStatic
(
member
.
getModifiers
());
String
memberDeclaringClassSlashedDescriptor
=
member
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
String
classDesc
=
member
.
getDeclaringClass
().
getName
().
replace
(
'.'
,
'/'
);
if
(!
isStatic
)
{
if
(
descriptor
==
null
)
{
cf
.
loadTarget
(
mv
);
}
if
(
descriptor
==
null
||
!
memberDeclaringClassSlashedDescriptor
.
equals
(
descriptor
.
substring
(
1
)))
{
mv
.
visitTypeInsn
(
CHECKCAST
,
memberDeclaringClassSlashedDescriptor
);
if
(
descriptor
==
null
||
!
classDesc
.
equals
(
descriptor
.
substring
(
1
)))
{
mv
.
visitTypeInsn
(
CHECKCAST
,
classDesc
);
}
}
if
(
member
instanceof
Field
)
{
mv
.
visitFieldInsn
(
isStatic
?
GETSTATIC
:
GETFIELD
,
memberDeclaringClassSlashedDescriptor
,
member
.
getName
(),
CodeFlow
.
toJvmDescriptor
(((
Field
)
member
).
getType
()));
if
(
member
instanceof
Method
)
{
mv
.
visitMethodInsn
((
isStatic
?
INVOKESTATIC
:
INVOKEVIRTUAL
),
classDesc
,
member
.
getName
(),
CodeFlow
.
createSignatureDescriptor
((
Method
)
member
),
false
);
}
else
{
mv
.
visit
MethodInsn
(
isStatic
?
INVOKESTATIC
:
INVOKEVIRTUAL
,
memberDeclaringClassSlashedDescriptor
,
member
.
getName
(),
CodeFlow
.
createSignatureDescriptor
((
Method
)
member
),
false
);
mv
.
visit
FieldInsn
((
isStatic
?
GETSTATIC
:
GETFIELD
),
classDesc
,
member
.
getName
()
,
CodeFlow
.
toJvmDescriptor
(((
Field
)
member
).
getType
())
);
}
}
...
...
@@ -555,12 +560,8 @@ public class Indexer extends SpelNodeImpl {
ReflectivePropertyAccessor
.
OptimalPropertyAccessor
optimalAccessor
=
(
ReflectivePropertyAccessor
.
OptimalPropertyAccessor
)
accessor
;
Member
member
=
optimalAccessor
.
member
;
if
(
member
instanceof
Field
)
{
Indexer
.
this
.
exitTypeDescriptor
=
CodeFlow
.
toDescriptor
(((
Field
)
member
).
getType
());
}
else
{
Indexer
.
this
.
exitTypeDescriptor
=
CodeFlow
.
toDescriptor
(((
Method
)
member
).
getReturnType
());
}
Indexer
.
this
.
exitTypeDescriptor
=
CodeFlow
.
toDescriptor
(
member
instanceof
Method
?
((
Method
)
member
).
getReturnType
()
:
((
Field
)
member
).
getType
());
}
return
accessor
.
read
(
this
.
evaluationContext
,
this
.
targetObject
,
this
.
name
);
}
...
...
spring-expression/src/main/java/org/springframework/expression/spel/ast/SpelNodeImpl.java
浏览文件 @
8c838071
...
...
@@ -239,15 +239,15 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
// The final parameter may or may not need packaging into an array, or nothing may
// have been passed to satisfy the varargs and so something needs to be built.
int
p
=
0
;
// Current supplied argument being processed
int
child
c
ount
=
arguments
.
length
;
int
child
C
ount
=
arguments
.
length
;
// Fulfill all the parameter requirements except the last one
for
(
p
=
0
;
p
<
paramDescriptors
.
length
-
1
;
p
++)
{
for
(
p
=
0
;
p
<
paramDescriptors
.
length
-
1
;
p
++)
{
generateCodeForArgument
(
mv
,
cf
,
arguments
[
p
],
paramDescriptors
[
p
]);
}
SpelNodeImpl
lastchild
=
(
child
count
==
0
?
null
:
arguments
[
childcount
-
1
]);
String
arraytype
=
paramDescriptors
[
paramDescriptors
.
length
-
1
];
SpelNodeImpl
lastchild
=
(
child
Count
==
0
?
null
:
arguments
[
childCount
-
1
]);
String
arraytype
=
paramDescriptors
[
paramDescriptors
.
length
-
1
];
// Determine if the final passed argument is already suitably packaged in array
// form to be passed to the method
if
(
lastchild
!=
null
&&
lastchild
.
getExitDescriptor
().
equals
(
arraytype
))
{
...
...
@@ -256,10 +256,10 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
else
{
arraytype
=
arraytype
.
substring
(
1
);
// trim the leading '[', may leave other '['
// build array big enough to hold remaining arguments
CodeFlow
.
insertNewArrayCode
(
mv
,
child
count
-
p
,
arraytype
);
CodeFlow
.
insertNewArrayCode
(
mv
,
child
Count
-
p
,
arraytype
);
// Package up the remaining arguments into the array
int
arrayindex
=
0
;
while
(
p
<
child
c
ount
)
{
while
(
p
<
child
C
ount
)
{
SpelNodeImpl
child
=
arguments
[
p
];
mv
.
visitInsn
(
DUP
);
CodeFlow
.
insertOptimalLoad
(
mv
,
arrayindex
++);
...
...
@@ -280,20 +280,20 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
* Ask an argument to generate its bytecode and then follow it up
* with any boxing/unboxing/checkcasting to ensure it matches the expected parameter descriptor.
*/
protected
static
void
generateCodeForArgument
(
MethodVisitor
mv
,
CodeFlow
cf
,
SpelNodeImpl
argument
,
String
paramDesc
riptor
)
{
protected
static
void
generateCodeForArgument
(
MethodVisitor
mv
,
CodeFlow
cf
,
SpelNodeImpl
argument
,
String
paramDesc
)
{
cf
.
enterCompilationScope
();
argument
.
generateCode
(
mv
,
cf
);
boolean
primitiveOnStack
=
CodeFlow
.
isPrimitive
(
cf
.
lastDescriptor
());
// Check if need to box it for the method reference?
if
(
primitiveOnStack
&&
paramDesc
riptor
.
charAt
(
0
)
==
'L'
)
{
if
(
primitiveOnStack
&&
paramDesc
.
charAt
(
0
)
==
'L'
)
{
CodeFlow
.
insertBoxIfNecessary
(
mv
,
cf
.
lastDescriptor
().
charAt
(
0
));
}
else
if
(
paramDesc
riptor
.
length
()
==
1
&&
!
primitiveOnStack
)
{
CodeFlow
.
insertUnboxInsns
(
mv
,
paramDesc
riptor
.
charAt
(
0
),
cf
.
lastDescriptor
());
else
if
(
paramDesc
.
length
()
==
1
&&
!
primitiveOnStack
)
{
CodeFlow
.
insertUnboxInsns
(
mv
,
paramDesc
.
charAt
(
0
),
cf
.
lastDescriptor
());
}
else
if
(!
cf
.
lastDescriptor
().
equals
(
paramDesc
riptor
))
{
else
if
(!
cf
.
lastDescriptor
().
equals
(
paramDesc
))
{
// This would be unnecessary in the case of subtyping (e.g. method takes Number but Integer passed in)
CodeFlow
.
insertCheckCast
(
mv
,
paramDesc
riptor
);
CodeFlow
.
insertCheckCast
(
mv
,
paramDesc
);
}
cf
.
exitCompilationScope
();
}
...
...
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java
浏览文件 @
8c838071
...
...
@@ -238,11 +238,13 @@ public class ReflectionHelper {
* @return true if some kind of conversion occurred on the argument
* @throws SpelEvaluationException if there is a problem with conversion
*/
public
static
boolean
convertAllArguments
(
TypeConverter
converter
,
Object
[]
arguments
,
Method
method
)
throws
SpelEvaluationException
{
Integer
varargsPosition
=
method
.
isVarArgs
()
?
method
.
getParameterTypes
().
length
-
1
:
null
;
public
static
boolean
convertAllArguments
(
TypeConverter
converter
,
Object
[]
arguments
,
Method
method
)
throws
SpelEvaluationException
{
Integer
varargsPosition
=
(
method
.
isVarArgs
()
?
method
.
getParameterTypes
().
length
-
1
:
null
);
return
convertArguments
(
converter
,
arguments
,
method
,
varargsPosition
);
}
/**
* Takes an input set of argument values and converts them to the types specified as the
* required parameter types. The arguments are converted 'in-place' in the input array.
...
...
spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/AbstractPromiseToListenableFutureAdapter.java
浏览文件 @
8c838071
...
...
@@ -56,21 +56,20 @@ abstract class AbstractPromiseToListenableFutureAdapter<S, T> implements Listena
try
{
registry
.
success
(
adapt
(
result
));
}
catch
(
Throwable
t
)
{
registry
.
failure
(
t
);
catch
(
Throwable
ex
)
{
registry
.
failure
(
ex
);
}
}
});
this
.
promise
.
onError
(
new
Consumer
<
Throwable
>()
{
@Override
public
void
accept
(
Throwable
t
)
{
registry
.
failure
(
t
);
public
void
accept
(
Throwable
ex
)
{
registry
.
failure
(
ex
);
}
});
}
protected
abstract
T
adapt
(
S
result
);
@Override
public
T
get
()
throws
InterruptedException
{
...
...
@@ -113,4 +112,7 @@ abstract class AbstractPromiseToListenableFutureAdapter<S, T> implements Listena
this
.
registry
.
addFailureCallback
(
failureCallback
);
}
protected
abstract
T
adapt
(
S
result
);
}
spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/Reactor11TcpClient.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -47,7 +47,6 @@ import org.springframework.messaging.tcp.TcpOperations;
import
org.springframework.util.Assert
;
import
org.springframework.util.concurrent.ListenableFuture
;
/**
* An implementation of {@link org.springframework.messaging.tcp.TcpOperations}
* based on the TCP client support of the Reactor project.
...
...
@@ -70,33 +69,23 @@ public class Reactor11TcpClient<P> implements TcpOperations<P> {
* A constructor that creates a {@link reactor.net.netty.tcp.NettyTcpClient} with
* a {@link reactor.event.dispatch.SynchronousDispatcher} as a result of which
* network I/O is handled in Netty threads.
*
* <p>Also see the constructor accepting a pre-configured Reactor
* {@link reactor.net.tcp.TcpClient}.
*
* @param host the host to connect to
* @param port the port to connect to
* @param codec the codec to use for encoding and decoding the TCP stream
*/
public
Reactor11TcpClient
(
String
host
,
int
port
,
Codec
<
Buffer
,
Message
<
P
>,
Message
<
P
>>
codec
)
{
// Revisit in 1.1: is Environment still required w/ sync dispatcher?
this
.
environment
=
new
Environment
(
new
SynchronousDispatcherConfigReader
());
this
.
tcpClient
=
new
TcpClientSpec
<
Message
<
P
>,
Message
<
P
>>(
REACTOR_TCP_CLIENT_TYPE
)
.
env
(
this
.
environment
)
.
codec
(
codec
)
.
connect
(
host
,
port
)
.
get
();
.
env
(
this
.
environment
).
codec
(
codec
).
connect
(
host
,
port
).
get
();
}
/**
* A constructor with a pre-configured {@link reactor.net.tcp.TcpClient}.
*
* <p><strong>NOTE:</strong> if the client is configured with a thread-creating
* dispatcher, you are responsible for shutting down the {@link reactor.core.Environment}
* instance with which the client is configured.
*
* @param tcpClient the TcpClient to use
*/
public
Reactor11TcpClient
(
TcpClient
<
Message
<
P
>,
Message
<
P
>>
tcpClient
)
{
...
...
@@ -108,7 +97,6 @@ public class Reactor11TcpClient<P> implements TcpOperations<P> {
@Override
public
ListenableFuture
<
Void
>
connect
(
TcpConnectionHandler
<
P
>
connectionHandler
)
{
Promise
<
NetChannel
<
Message
<
P
>,
Message
<
P
>>>
promise
=
this
.
tcpClient
.
open
();
composeConnectionHandling
(
promise
,
connectionHandler
);
...
...
@@ -125,7 +113,6 @@ public class Reactor11TcpClient<P> implements TcpOperations<P> {
final
ReconnectStrategy
reconnectStrategy
)
{
Assert
.
notNull
(
reconnectStrategy
,
"ReconnectStrategy must not be null"
);
Reconnect
reconnect
=
new
Reconnect
()
{
@Override
public
Tuple2
<
InetSocketAddress
,
Long
>
reconnect
(
InetSocketAddress
address
,
int
attempt
)
{
...
...
@@ -162,8 +149,8 @@ public class Reactor11TcpClient<P> implements TcpOperations<P> {
connection
.
when
(
Throwable
.
class
,
new
Consumer
<
Throwable
>()
{
@Override
public
void
accept
(
Throwable
t
)
{
connectionHandler
.
handleFailure
(
t
);
public
void
accept
(
Throwable
ex
)
{
connectionHandler
.
handleFailure
(
ex
);
}
})
.
consume
(
new
Consumer
<
Message
<
P
>>()
{
...
...
@@ -201,9 +188,9 @@ public class Reactor11TcpClient<P> implements TcpOperations<P> {
}
}
/**
* A ConfigurationReader that enforces the use of a SynchronousDispatcher.
*
* <p>The {@link reactor.core.configuration.PropertiesConfigurationReader} used by
* default automatically creates other dispatchers with thread pools that are
* not needed.
...
...
spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -21,7 +21,6 @@ import java.util.Map;
import
org.w3c.dom.Element
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.ConstructorArgumentValues
;
import
org.springframework.beans.factory.parsing.BeanComponentDefinition
;
import
org.springframework.beans.factory.support.ManagedMap
;
import
org.springframework.beans.factory.support.RootBeanDefinition
;
...
...
@@ -131,21 +130,25 @@ class ViewControllerBeanDefinitionParser implements BeanDefinitionParser {
}
private
RootBeanDefinition
getRedirectView
(
Element
element
,
HttpStatus
status
,
Object
source
)
{
ConstructorArgumentValues
cavs
=
new
ConstructorArgumentValues
();
cavs
.
addIndexedArgumentValue
(
0
,
element
.
getAttribute
(
"redirect-url"
));
RootBeanDefinition
redirectView
=
new
RootBeanDefinition
(
RedirectView
.
class
,
cavs
,
null
);
RootBeanDefinition
redirectView
=
new
RootBeanDefinition
(
RedirectView
.
class
);
redirectView
.
setSource
(
source
);
redirectView
.
getConstructorArgumentValues
().
addIndexedArgumentValue
(
0
,
element
.
getAttribute
(
"redirect-url"
));
if
(
status
!=
null
)
{
redirectView
.
getPropertyValues
().
add
(
"statusCode"
,
status
);
}
if
(
element
.
hasAttribute
(
"context-relative"
))
{
redirectView
.
getPropertyValues
().
add
(
"contextRelative"
,
element
.
getAttribute
(
"context-relative"
));
}
else
{
}
else
{
redirectView
.
getPropertyValues
().
add
(
"contextRelative"
,
true
);
}
if
(
element
.
hasAttribute
(
"keep-query-params"
))
{
redirectView
.
getPropertyValues
().
add
(
"propagateQueryParams"
,
element
.
getAttribute
(
"keep-query-params"
));
}
return
redirectView
;
}
...
...
spring-websocket/src/main/java/org/springframework/web/socket/adapter/jetty/JettyWebSocketHandlerAdapter.java
浏览文件 @
8c838071
...
...
@@ -38,7 +38,6 @@ import org.springframework.web.socket.TextMessage;
import
org.springframework.web.socket.WebSocketHandler
;
import
org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator
;
/**
* Adapts {@link WebSocketHandler} to the Jetty 9 WebSocket API.
*
...
...
@@ -59,8 +58,8 @@ public class JettyWebSocketHandlerAdapter {
public
JettyWebSocketHandlerAdapter
(
WebSocketHandler
webSocketHandler
,
JettyWebSocketSession
wsSession
)
{
Assert
.
notNull
(
webSocketHandler
,
"
w
ebSocketHandler must not be null"
);
Assert
.
notNull
(
wsSession
,
"
ws
Session must not be null"
);
Assert
.
notNull
(
webSocketHandler
,
"
W
ebSocketHandler must not be null"
);
Assert
.
notNull
(
wsSession
,
"
WebSocket
Session must not be null"
);
this
.
webSocketHandler
=
webSocketHandler
;
this
.
wsSession
=
wsSession
;
}
...
...
@@ -72,8 +71,8 @@ public class JettyWebSocketHandlerAdapter {
this
.
wsSession
.
initializeNativeSession
(
session
);
this
.
webSocketHandler
.
afterConnectionEstablished
(
this
.
wsSession
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -83,8 +82,8 @@ public class JettyWebSocketHandlerAdapter {
try
{
this
.
webSocketHandler
.
handleMessage
(
this
.
wsSession
,
message
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -94,8 +93,8 @@ public class JettyWebSocketHandlerAdapter {
try
{
this
.
webSocketHandler
.
handleMessage
(
this
.
wsSession
,
message
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -107,8 +106,8 @@ public class JettyWebSocketHandlerAdapter {
try
{
this
.
webSocketHandler
.
handleMessage
(
this
.
wsSession
,
message
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
}
...
...
@@ -119,8 +118,10 @@ public class JettyWebSocketHandlerAdapter {
try
{
this
.
webSocketHandler
.
afterConnectionClosed
(
this
.
wsSession
,
closeStatus
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Unhandled error for "
+
this
.
wsSession
,
t
);
catch
(
Throwable
ex
)
{
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"Unhandled error for "
+
this
.
wsSession
,
ex
);
}
}
}
...
...
@@ -129,8 +130,8 @@ public class JettyWebSocketHandlerAdapter {
try
{
this
.
webSocketHandler
.
handleTransportError
(
this
.
wsSession
,
cause
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketHandlerAdapter.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -49,8 +49,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
public
StandardWebSocketHandlerAdapter
(
WebSocketHandler
handler
,
StandardWebSocketSession
wsSession
)
{
Assert
.
notNull
(
handler
,
"
h
andler must not be null"
);
Assert
.
notNull
(
wsSession
,
"
ws
Session must not be null"
);
Assert
.
notNull
(
handler
,
"
WebSocketH
andler must not be null"
);
Assert
.
notNull
(
wsSession
,
"
WebSocket
Session must not be null"
);
this
.
handler
=
handler
;
this
.
wsSession
=
wsSession
;
}
...
...
@@ -58,7 +58,6 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
@Override
public
void
onOpen
(
final
javax
.
websocket
.
Session
session
,
EndpointConfig
config
)
{
this
.
wsSession
.
initializeNativeSession
(
session
);
if
(
this
.
handler
.
supportsPartialMessages
())
{
...
...
@@ -100,9 +99,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
try
{
this
.
handler
.
afterConnectionEstablished
(
this
.
wsSession
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
return
;
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -111,8 +109,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
try
{
this
.
handler
.
handleMessage
(
this
.
wsSession
,
textMessage
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -121,8 +119,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
try
{
this
.
handler
.
handleMessage
(
this
.
wsSession
,
binaryMessage
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -131,8 +129,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
try
{
this
.
handler
.
handleMessage
(
this
.
wsSession
,
pongMessage
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
@@ -142,8 +140,10 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
try
{
this
.
handler
.
afterConnectionClosed
(
this
.
wsSession
,
closeStatus
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Unhandled error for "
+
this
.
wsSession
,
t
);
catch
(
Throwable
ex
)
{
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"Unhandled error for "
+
this
.
wsSession
,
ex
);
}
}
}
...
...
@@ -152,8 +152,8 @@ public class StandardWebSocketHandlerAdapter extends Endpoint {
try
{
this
.
handler
.
handleTransportError
(
this
.
wsSession
,
exception
);
}
catch
(
Throwable
t
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
t
,
logger
);
catch
(
Throwable
ex
)
{
ExceptionWebSocketHandlerDecorator
.
tryCloseWithError
(
this
.
wsSession
,
ex
,
logger
);
}
}
...
...
spring-websocket/src/main/java/org/springframework/web/socket/handler/ExceptionWebSocketHandlerDecorator.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -25,16 +25,16 @@ import org.springframework.web.socket.WebSocketMessage;
import
org.springframework.web.socket.WebSocketSession
;
/**
* An exception handling {@link WebSocketHandlerDecorator}.
Traps all {@link Throwable}
*
instances that escape from the decorated handler and closes the session with
* {@link CloseStatus#SERVER_ERROR}.
* An exception handling {@link WebSocketHandlerDecorator}.
*
Traps all {@link Throwable} instances that escape from the decorated
*
handler and closes the session with
{@link CloseStatus#SERVER_ERROR}.
*
* @author Rossen Stoyanchev
* @since 4.0
*/
public
class
ExceptionWebSocketHandlerDecorator
extends
WebSocketHandlerDecorator
{
private
final
Log
logger
=
LogFactory
.
getLog
(
ExceptionWebSocketHandlerDecorator
.
class
);
private
static
final
Log
logger
=
LogFactory
.
getLog
(
ExceptionWebSocketHandlerDecorator
.
class
);
public
ExceptionWebSocketHandlerDecorator
(
WebSocketHandler
delegate
)
{
...
...
@@ -52,20 +52,6 @@ public class ExceptionWebSocketHandlerDecorator extends WebSocketHandlerDecorato
}
}
public
static
void
tryCloseWithError
(
WebSocketSession
session
,
Throwable
exception
,
Log
logger
)
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Closing due to exception for "
+
session
,
exception
);
}
if
(
session
.
isOpen
())
{
try
{
session
.
close
(
CloseStatus
.
SERVER_ERROR
);
}
catch
(
Throwable
t
)
{
// ignore
}
}
}
@Override
public
void
handleMessage
(
WebSocketSession
session
,
WebSocketMessage
<?>
message
)
{
try
{
...
...
@@ -91,8 +77,25 @@ public class ExceptionWebSocketHandlerDecorator extends WebSocketHandlerDecorato
try
{
getDelegate
().
afterConnectionClosed
(
session
,
closeStatus
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Unhandled error for "
+
this
,
t
);
catch
(
Throwable
ex
)
{
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"Unhandled error for "
+
this
,
ex
);
}
}
}
public
static
void
tryCloseWithError
(
WebSocketSession
session
,
Throwable
exception
,
Log
logger
)
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Closing due to exception for "
+
session
,
exception
);
}
if
(
session
.
isOpen
())
{
try
{
session
.
close
(
CloseStatus
.
SERVER_ERROR
);
}
catch
(
Throwable
ex
)
{
// ignore
}
}
}
...
...
spring-websocket/src/main/java/org/springframework/web/socket/handler/PerConnectionWebSocketHandler.java
浏览文件 @
8c838071
/*
* Copyright 2002-201
4
the original author or authors.
* Copyright 2002-201
5
the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
...
...
@@ -22,10 +22,8 @@ import java.util.concurrent.ConcurrentHashMap;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.beans.BeansException
;
import
org.springframework.beans.factory.BeanFactory
;
import
org.springframework.beans.factory.BeanFactoryAware
;
import
org.springframework.util.Assert
;
import
org.springframework.web.socket.CloseStatus
;
import
org.springframework.web.socket.WebSocketHandler
;
import
org.springframework.web.socket.WebSocketMessage
;
...
...
@@ -69,11 +67,13 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
this
.
supportsPartialMessages
=
supportsPartialMessages
;
}
@Override
public
void
setBeanFactory
(
BeanFactory
beanFactory
)
throws
BeansException
{
public
void
setBeanFactory
(
BeanFactory
beanFactory
)
{
this
.
provider
.
setBeanFactory
(
beanFactory
);
}
@Override
public
void
afterConnectionEstablished
(
WebSocketSession
session
)
throws
Exception
{
WebSocketHandler
handler
=
this
.
provider
.
getHandler
();
...
...
@@ -86,12 +86,6 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
getHandler
(
session
).
handleMessage
(
session
,
message
);
}
private
WebSocketHandler
getHandler
(
WebSocketSession
session
)
{
WebSocketHandler
handler
=
this
.
handlers
.
get
(
session
);
Assert
.
isTrue
(
handler
!=
null
,
"WebSocketHandler not found for "
+
session
);
return
handler
;
}
@Override
public
void
handleTransportError
(
WebSocketSession
session
,
Throwable
exception
)
throws
Exception
{
getHandler
(
session
).
handleTransportError
(
session
,
exception
);
...
...
@@ -103,26 +97,38 @@ public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFact
getHandler
(
session
).
afterConnectionClosed
(
session
,
closeStatus
);
}
finally
{
destroy
(
session
);
destroyHandler
(
session
);
}
}
@Override
public
boolean
supportsPartialMessages
()
{
return
this
.
supportsPartialMessages
;
}
private
WebSocketHandler
getHandler
(
WebSocketSession
session
)
{
WebSocketHandler
handler
=
this
.
handlers
.
get
(
session
);
if
(
handler
==
null
)
{
throw
new
IllegalStateException
(
"WebSocketHandler not found for "
+
session
);
}
return
handler
;
}
private
void
destroy
(
WebSocketSession
session
)
{
private
void
destroy
Handler
(
WebSocketSession
session
)
{
WebSocketHandler
handler
=
this
.
handlers
.
remove
(
session
);
try
{
if
(
handler
!=
null
)
{
this
.
provider
.
destroy
(
handler
);
}
}
catch
(
Throwable
t
)
{
logger
.
warn
(
"Error while destroying "
+
handler
,
t
);
catch
(
Throwable
ex
)
{
if
(
logger
.
isWarnEnabled
())
{
logger
.
warn
(
"Error while destroying "
+
handler
,
ex
);
}
}
}
@Override
public
boolean
supportsPartialMessages
()
{
return
this
.
supportsPartialMessages
;
}
@Override
public
String
toString
()
{
...
...
spring-websocket/src/main/java/org/springframework/web/socket/messaging/SubProtocolWebSocketHandler.java
浏览文件 @
8c838071
...
...
@@ -18,8 +18,8 @@ package org.springframework.web.socket.messaging;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.
Array
s
;
import
java.util.HashSet
;
import
java.util.
Collection
s
;
import
java.util.
Linked
HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
...
...
@@ -86,7 +86,7 @@ public class SubProtocolWebSocketHandler
private
final
Map
<
String
,
SubProtocolHandler
>
protocolHandlerLookup
=
new
TreeMap
<
String
,
SubProtocolHandler
>(
String
.
CASE_INSENSITIVE_ORDER
);
private
final
Set
<
SubProtocolHandler
>
protocolHandlers
=
new
HashSet
<
SubProtocolHandler
>();
private
final
Set
<
SubProtocolHandler
>
protocolHandlers
=
new
Linked
HashSet
<
SubProtocolHandler
>();
private
SubProtocolHandler
defaultProtocolHandler
;
...
...
@@ -143,12 +143,14 @@ public class SubProtocolWebSocketHandler
public
void
addProtocolHandler
(
SubProtocolHandler
handler
)
{
List
<
String
>
protocols
=
handler
.
getSupportedProtocols
();
if
(
CollectionUtils
.
isEmpty
(
protocols
))
{
logger
.
error
(
"No sub-protocols for "
+
handler
+
"."
);
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"No sub-protocols for "
+
handler
);
}
return
;
}
for
(
String
protocol:
protocols
)
{
for
(
String
protocol
:
protocols
)
{
SubProtocolHandler
replaced
=
this
.
protocolHandlerLookup
.
put
(
protocol
,
handler
);
if
(
(
replaced
!=
null
)
&&
(
replaced
!=
handler
)
)
{
if
(
replaced
!=
null
&&
replaced
!=
handler
)
{
throw
new
IllegalStateException
(
"Can't map "
+
handler
+
" to protocol '"
+
protocol
+
"'. Already mapped to "
+
replaced
+
"."
);
}
...
...
@@ -171,7 +173,7 @@ public class SubProtocolWebSocketHandler
public
void
setDefaultProtocolHandler
(
SubProtocolHandler
defaultProtocolHandler
)
{
this
.
defaultProtocolHandler
=
defaultProtocolHandler
;
if
(
this
.
protocolHandlerLookup
.
isEmpty
())
{
setProtocolHandlers
(
Arrays
.
as
List
(
defaultProtocolHandler
));
setProtocolHandlers
(
Collections
.
singleton
List
(
defaultProtocolHandler
));
}
}
...
...
@@ -262,8 +264,10 @@ public class SubProtocolWebSocketHandler
try
{
holder
.
getSession
().
close
(
CloseStatus
.
GOING_AWAY
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Failed to close '"
+
holder
.
getSession
()
+
"': "
+
t
.
getMessage
());
catch
(
Throwable
ex
)
{
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"Failed to close '"
+
holder
.
getSession
()
+
"': "
+
ex
);
}
}
}
}
...
...
@@ -286,36 +290,6 @@ public class SubProtocolWebSocketHandler
findProtocolHandler
(
session
).
afterSessionStarted
(
session
,
this
.
clientInboundChannel
);
}
protected
final
SubProtocolHandler
findProtocolHandler
(
WebSocketSession
session
)
{
String
protocol
=
null
;
try
{
protocol
=
session
.
getAcceptedProtocol
();
}
catch
(
Exception
ex
)
{
// Shouldn't happen
logger
.
error
(
"Failed to obtain session.getAcceptedProtocol(). Will use the "
+
"default protocol handler (if configured)."
,
ex
);
}
SubProtocolHandler
handler
;
if
(!
StringUtils
.
isEmpty
(
protocol
))
{
handler
=
this
.
protocolHandlerLookup
.
get
(
protocol
);
Assert
.
state
(
handler
!=
null
,
"No handler for '"
+
protocol
+
"' among "
+
this
.
protocolHandlerLookup
);
}
else
{
if
(
this
.
defaultProtocolHandler
!=
null
)
{
handler
=
this
.
defaultProtocolHandler
;
}
else
if
(
this
.
protocolHandlers
.
size
()
==
1
)
{
handler
=
this
.
protocolHandlers
.
iterator
().
next
();
}
else
{
throw
new
IllegalStateException
(
"Multiple protocol handlers configured and "
+
"no protocol was negotiated. Consider configuring a default SubProtocolHandler."
);
}
}
return
handler
;
}
/**
* Handle an inbound message from a WebSocket client.
*/
...
...
@@ -340,9 +314,12 @@ public class SubProtocolWebSocketHandler
public
void
handleMessage
(
Message
<?>
message
)
throws
MessagingException
{
String
sessionId
=
resolveSessionId
(
message
);
if
(
sessionId
==
null
)
{
logger
.
error
(
"Couldn't find sessionId in "
+
message
);
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"Couldn't find session id in "
+
message
);
}
return
;
}
WebSocketSessionHolder
holder
=
this
.
sessions
.
get
(
sessionId
);
if
(
holder
==
null
)
{
if
(
logger
.
isDebugEnabled
())
{
...
...
@@ -351,6 +328,7 @@ public class SubProtocolWebSocketHandler
}
return
;
}
WebSocketSession
session
=
holder
.
getSession
();
try
{
findProtocolHandler
(
session
).
handleMessageToClient
(
session
,
message
);
...
...
@@ -368,10 +346,62 @@ public class SubProtocolWebSocketHandler
logger
.
debug
(
"Failure while closing session "
+
sessionId
+
"."
,
secondException
);
}
}
catch
(
Exception
e
)
{
catch
(
Exception
e
x
)
{
// Could be part of normal workflow (e.g. browser tab closed)
logger
.
debug
(
"Failed to send message to client in "
+
session
+
": "
+
message
,
e
);
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Failed to send message to client in "
+
session
+
": "
+
message
,
ex
);
}
}
}
@Override
public
void
handleTransportError
(
WebSocketSession
session
,
Throwable
exception
)
throws
Exception
{
this
.
stats
.
incrementTransportError
();
}
@Override
public
void
afterConnectionClosed
(
WebSocketSession
session
,
CloseStatus
closeStatus
)
throws
Exception
{
clearSession
(
session
,
closeStatus
);
}
@Override
public
boolean
supportsPartialMessages
()
{
return
false
;
}
protected
final
SubProtocolHandler
findProtocolHandler
(
WebSocketSession
session
)
{
String
protocol
=
null
;
try
{
protocol
=
session
.
getAcceptedProtocol
();
}
catch
(
Exception
ex
)
{
// Shouldn't happen
logger
.
error
(
"Failed to obtain session.getAcceptedProtocol(). "
+
"Will use the default protocol handler (if configured)."
,
ex
);
}
SubProtocolHandler
handler
;
if
(!
StringUtils
.
isEmpty
(
protocol
))
{
handler
=
this
.
protocolHandlerLookup
.
get
(
protocol
);
if
(
handler
==
null
)
{
throw
new
IllegalStateException
(
"No handler for '"
+
protocol
+
"' among "
+
this
.
protocolHandlerLookup
);
}
}
else
{
if
(
this
.
defaultProtocolHandler
!=
null
)
{
handler
=
this
.
defaultProtocolHandler
;
}
else
if
(
this
.
protocolHandlers
.
size
()
==
1
)
{
handler
=
this
.
protocolHandlers
.
iterator
().
next
();
}
else
{
throw
new
IllegalStateException
(
"Multiple protocol handlers configured and "
+
"no protocol was negotiated. Consider configuring a default SubProtocolHandler."
);
}
}
return
handler
;
}
private
String
resolveSessionId
(
Message
<?>
message
)
{
...
...
@@ -404,6 +434,7 @@ public class SubProtocolWebSocketHandler
if
(!
isRunning
()
||
(
currentTime
-
this
.
lastSessionCheckTime
<
TIME_TO_FIRST_MESSAGE
))
{
return
;
}
if
(
this
.
sessionCheckLock
.
tryLock
())
{
try
{
for
(
WebSocketSessionHolder
holder
:
this
.
sessions
.
values
())
{
...
...
@@ -423,8 +454,10 @@ public class SubProtocolWebSocketHandler
this
.
stats
.
incrementNoMessagesReceivedCount
();
session
.
close
(
CloseStatus
.
SESSION_NOT_RELIABLE
);
}
catch
(
Throwable
t
)
{
logger
.
error
(
"Failure while closing "
+
session
,
t
);
catch
(
Throwable
ex
)
{
if
(
logger
.
isErrorEnabled
())
{
logger
.
error
(
"Failure while closing "
+
session
,
ex
);
}
}
}
}
...
...
@@ -435,16 +468,6 @@ public class SubProtocolWebSocketHandler
}
}
@Override
public
void
handleTransportError
(
WebSocketSession
session
,
Throwable
exception
)
throws
Exception
{
this
.
stats
.
incrementTransportError
();
}
@Override
public
void
afterConnectionClosed
(
WebSocketSession
session
,
CloseStatus
closeStatus
)
throws
Exception
{
clearSession
(
session
,
closeStatus
);
}
private
void
clearSession
(
WebSocketSession
session
,
CloseStatus
closeStatus
)
throws
Exception
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Clearing session "
+
session
.
getId
());
...
...
@@ -455,16 +478,13 @@ public class SubProtocolWebSocketHandler
findProtocolHandler
(
session
).
afterSessionEnded
(
session
,
closeStatus
,
this
.
clientInboundChannel
);
}
@Override
public
boolean
supportsPartialMessages
()
{
return
false
;
}
@Override
public
String
toString
()
{
return
"SubProtocolWebSocketHandler"
+
getProtocolHandlers
()
;
return
"SubProtocolWebSocketHandler"
+
this
.
protocolHandlers
;
}
private
static
class
WebSocketSessionHolder
{
private
final
WebSocketSession
session
;
...
...
@@ -473,7 +493,6 @@ public class SubProtocolWebSocketHandler
private
volatile
boolean
handledMessages
;
private
WebSocketSessionHolder
(
WebSocketSession
session
)
{
this
.
session
=
session
;
}
...
...
@@ -496,11 +515,12 @@ public class SubProtocolWebSocketHandler
@Override
public
String
toString
()
{
return
"WebSocketSessionHolder[
=
session="
+
this
.
session
+
", createTime="
+
return
"WebSocketSessionHolder[session="
+
this
.
session
+
", createTime="
+
this
.
createTime
+
", hasHandledMessages="
+
this
.
handledMessages
+
"]"
;
}
}
private
class
Stats
{
private
final
AtomicInteger
total
=
new
AtomicInteger
();
...
...
@@ -517,7 +537,6 @@ public class SubProtocolWebSocketHandler
private
final
AtomicInteger
transportError
=
new
AtomicInteger
();
public
void
incrementSessionCount
(
WebSocketSession
session
)
{
getCountFor
(
session
).
incrementAndGet
();
this
.
total
.
incrementAndGet
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录