Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
80ff5ae9
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 搜索 >>
提交
80ff5ae9
编写于
9月 13, 2016
作者:
V
Violeta Georgieva
提交者:
Rossen Stoyanchev
9月 16, 2016
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Improve exception handling when clients disconnect.
Issue: SPR-14538
上级
c4b9b922
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
80 addition
and
9 deletion
+80
-9
spring-web/src/main/java/org/springframework/http/server/reactive/AbstractResponseBodyFlushProcessor.java
...p/server/reactive/AbstractResponseBodyFlushProcessor.java
+2
-2
spring-web/src/main/java/org/springframework/http/server/reactive/AbstractResponseBodyProcessor.java
...k/http/server/reactive/AbstractResponseBodyProcessor.java
+2
-2
spring-web/src/main/java/org/springframework/http/server/reactive/ReactorHttpHandlerAdapter.java
...ework/http/server/reactive/ReactorHttpHandlerAdapter.java
+9
-1
spring-web/src/main/java/org/springframework/http/server/reactive/RxNettyHttpHandlerAdapter.java
...ework/http/server/reactive/RxNettyHttpHandlerAdapter.java
+10
-1
spring-web/src/main/java/org/springframework/web/server/handler/ExceptionHandlingWebHandler.java
...ework/web/server/handler/ExceptionHandlingWebHandler.java
+57
-3
未找到文件。
spring-web/src/main/java/org/springframework/http/server/reactive/AbstractResponseBodyFlushProcessor.java
浏览文件 @
80ff5ae9
...
...
@@ -74,8 +74,8 @@ abstract class AbstractResponseBodyFlushProcessor implements Processor<Publisher
@Override
public
final
void
onError
(
Throwable
t
)
{
if
(
logger
.
is
Error
Enabled
())
{
logger
.
error
(
this
.
state
+
" onError: "
+
t
,
t
);
if
(
logger
.
is
Trace
Enabled
())
{
logger
.
trace
(
this
.
state
+
" onError: "
+
t
);
}
this
.
state
.
get
().
onError
(
this
,
t
);
}
...
...
spring-web/src/main/java/org/springframework/http/server/reactive/AbstractResponseBodyProcessor.java
浏览文件 @
80ff5ae9
...
...
@@ -79,8 +79,8 @@ abstract class AbstractResponseBodyProcessor implements Processor<DataBuffer, Vo
@Override
public
final
void
onError
(
Throwable
t
)
{
if
(
logger
.
is
Error
Enabled
())
{
logger
.
error
(
this
.
state
+
" onError: "
+
t
,
t
);
if
(
logger
.
is
Trace
Enabled
())
{
logger
.
trace
(
this
.
state
+
" onError: "
+
t
);
}
this
.
state
.
get
().
onError
(
this
,
t
);
}
...
...
spring-web/src/main/java/org/springframework/http/server/reactive/ReactorHttpHandlerAdapter.java
浏览文件 @
80ff5ae9
...
...
@@ -21,9 +21,12 @@ import java.util.function.Function;
import
reactor.core.publisher.Mono
;
import
reactor.ipc.netty.http.HttpChannel
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.core.io.buffer.NettyDataBufferFactory
;
import
org.springframework.util.Assert
;
import
io.netty.handler.codec.http.HttpResponseStatus
;
/**
* Adapt {@link HttpHandler} to the Reactor Netty channel handling function.
*
...
...
@@ -46,7 +49,12 @@ public class ReactorHttpHandlerAdapter implements Function<HttpChannel, Mono<Voi
NettyDataBufferFactory
bufferFactory
=
new
NettyDataBufferFactory
(
channel
.
delegate
().
alloc
());
ReactorServerHttpRequest
adaptedRequest
=
new
ReactorServerHttpRequest
(
channel
,
bufferFactory
);
ReactorServerHttpResponse
adaptedResponse
=
new
ReactorServerHttpResponse
(
channel
,
bufferFactory
);
return
this
.
httpHandler
.
handle
(
adaptedRequest
,
adaptedResponse
);
return
this
.
httpHandler
.
handle
(
adaptedRequest
,
adaptedResponse
)
.
otherwise
(
ex
->
{
LogFactory
.
getLog
(
ReactorHttpHandlerAdapter
.
class
).
error
(
"Could not complete request"
,
ex
);
channel
.
status
(
HttpResponseStatus
.
INTERNAL_SERVER_ERROR
);
return
Mono
.
empty
();
});
}
}
spring-web/src/main/java/org/springframework/http/server/reactive/RxNettyHttpHandlerAdapter.java
浏览文件 @
80ff5ae9
...
...
@@ -17,11 +17,15 @@
package
org.springframework.http.server.reactive
;
import
io.netty.buffer.ByteBuf
;
import
io.netty.handler.codec.http.HttpResponseStatus
;
import
io.reactivex.netty.protocol.http.server.HttpServerRequest
;
import
io.reactivex.netty.protocol.http.server.HttpServerResponse
;
import
io.reactivex.netty.protocol.http.server.RequestHandler
;
import
org.apache.commons.logging.LogFactory
;
import
org.reactivestreams.Publisher
;
import
reactor.adapter.RxJava1Adapter
;
import
reactor.core.publisher.Mono
;
import
rx.Observable
;
import
org.springframework.core.io.buffer.NettyDataBufferFactory
;
...
...
@@ -49,7 +53,12 @@ public class RxNettyHttpHandlerAdapter implements RequestHandler<ByteBuf, ByteBu
NettyDataBufferFactory
bufferFactory
=
new
NettyDataBufferFactory
(
response
.
unsafeNettyChannel
().
alloc
());
RxNettyServerHttpRequest
adaptedRequest
=
new
RxNettyServerHttpRequest
(
request
,
bufferFactory
);
RxNettyServerHttpResponse
adaptedResponse
=
new
RxNettyServerHttpResponse
(
response
,
bufferFactory
);
Publisher
<
Void
>
result
=
this
.
httpHandler
.
handle
(
adaptedRequest
,
adaptedResponse
);
Publisher
<
Void
>
result
=
this
.
httpHandler
.
handle
(
adaptedRequest
,
adaptedResponse
)
.
otherwise
(
ex
->
{
LogFactory
.
getLog
(
RxNettyHttpHandlerAdapter
.
class
).
error
(
"Could not complete request"
,
ex
);
response
.
setStatus
(
HttpResponseStatus
.
INTERNAL_SERVER_ERROR
);
return
Mono
.
empty
();
});
return
RxJava1Adapter
.
publisherToObservable
(
result
);
}
...
...
spring-web/src/main/java/org/springframework/web/server/handler/ExceptionHandlingWebHandler.java
浏览文件 @
80ff5ae9
...
...
@@ -18,12 +18,15 @@ package org.springframework.web.server.handler;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
reactor.core.publisher.Mono
;
import
org.springframework.core.NestedCheckedException
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.web.server.ServerWebExchange
;
import
org.springframework.web.server.WebExceptionHandler
;
...
...
@@ -37,6 +40,36 @@ import org.springframework.web.server.WebHandler;
* @since 5.0
*/
public
class
ExceptionHandlingWebHandler
extends
WebHandlerDecorator
{
/**
* Log category to use on network IO exceptions after a client has gone away.
* <p>The Servlet API does not provide notifications when a client disconnects;
* see <a href="https://java.net/jira/browse/SERVLET_SPEC-44">SERVLET_SPEC-44</a>.
* Therefore network IO failures may occur simply because a client has gone away,
* and that can fill the logs with unnecessary stack traces.
* <p>We make a best effort to identify such network failures, on a per-server
* basis, and log them under a separate log category. A simple one-line message
* is logged at DEBUG level, while a full stack trace is shown at TRACE level.
* @see #disconnectedClientLogger
*/
private
static
final
String
DISCONNECTED_CLIENT_LOG_CATEGORY
=
"org.springframework.web.server.handler.DisconnectedClient"
;
/**
* Separate logger to use on network IO failure after a client has gone away.
* @see #DISCONNECTED_CLIENT_LOG_CATEGORY
*/
private
static
final
Log
disconnectedClientLogger
=
LogFactory
.
getLog
(
DISCONNECTED_CLIENT_LOG_CATEGORY
);
private
static
final
Set
<
String
>
disconnectedClientExceptions
;
static
{
Set
<
String
>
set
=
new
HashSet
<>(
3
);
set
.
add
(
"ClientAbortException"
);
// Tomcat
set
.
add
(
"EOFException"
);
// Tomcat
set
.
add
(
"EofException"
);
// Jetty
// java.io.IOException "Broken pipe" on WildFly, Glassfish (already covered)
disconnectedClientExceptions
=
Collections
.
unmodifiableSet
(
set
);
}
private
static
Log
logger
=
LogFactory
.
getLog
(
ExceptionHandlingWebHandler
.
class
);
...
...
@@ -77,11 +110,32 @@ public class ExceptionHandlingWebHandler extends WebHandlerDecorator {
}
private
Mono
<?
extends
Void
>
handleUnresolvedException
(
ServerWebExchange
exchange
,
Throwable
ex
)
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Could not complete request"
,
ex
);
}
logError
(
ex
);
exchange
.
getResponse
().
setStatusCode
(
HttpStatus
.
INTERNAL_SERVER_ERROR
);
return
Mono
.
empty
();
}
private
void
logError
(
Throwable
t
)
{
@SuppressWarnings
(
"serial"
)
NestedCheckedException
nestedException
=
new
NestedCheckedException
(
""
,
t
)
{};
if
(
"Broken pipe"
.
equalsIgnoreCase
(
nestedException
.
getMostSpecificCause
().
getMessage
())
||
disconnectedClientExceptions
.
contains
(
t
.
getClass
().
getSimpleName
()))
{
if
(
disconnectedClientLogger
.
isTraceEnabled
())
{
disconnectedClientLogger
.
trace
(
"Looks like the client has gone away"
,
t
);
}
else
if
(
disconnectedClientLogger
.
isDebugEnabled
())
{
disconnectedClientLogger
.
debug
(
"Looks like the client has gone away: "
+
nestedException
.
getMessage
()
+
" (For full stack trace, set the '"
+
DISCONNECTED_CLIENT_LOG_CATEGORY
+
"' log category to TRACE level)"
);
}
}
else
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Could not complete request"
,
t
);
}
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录