Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
4e25a14f
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,发现更多精彩内容 >>
提交
4e25a14f
编写于
7月 16, 2014
作者:
J
Juergen Hoeller
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #571 from sdeleuze/SPR-11820
Make ListenableFuture compliant with Java 8 lambda
上级
b1b7f8ab
86e8bdab
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
392 addition
and
41 deletion
+392
-41
spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java
...rg/springframework/scheduling/annotation/AsyncResult.java
+11
-1
spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java
.../org/springframework/util/concurrent/FailureCallback.java
+34
-0
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java
...org/springframework/util/concurrent/ListenableFuture.java
+13
-1
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureAdapter.java
...ingframework/util/concurrent/ListenableFutureAdapter.java
+10
-3
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java
...ngframework/util/concurrent/ListenableFutureCallback.java
+3
-14
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java
...ork/util/concurrent/ListenableFutureCallbackRegistry.java
+57
-8
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureTask.java
...springframework/util/concurrent/ListenableFutureTask.java
+7
-1
spring-core/src/main/java/org/springframework/util/concurrent/SettableListenableFuture.java
...ngframework/util/concurrent/SettableListenableFuture.java
+5
-0
spring-core/src/main/java/org/springframework/util/concurrent/SuccessCallback.java
.../org/springframework/util/concurrent/SuccessCallback.java
+34
-0
spring-core/src/test/java/org/springframework/util/concurrent/ListenableFutureTaskTests.java
...gframework/util/concurrent/ListenableFutureTaskTests.java
+33
-1
spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/AbstractPromiseToListenableFutureAdapter.java
...tcp/reactor/AbstractPromiseToListenableFutureAdapter.java
+8
-1
spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java
...ork/http/client/HttpComponentsAsyncClientHttpRequest.java
+19
-2
spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java
...ava/org/springframework/web/client/AsyncRestTemplate.java
+19
-7
spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java
...amework/web/client/AsyncRestTemplateIntegrationTests.java
+139
-2
未找到文件。
spring-context/src/main/java/org/springframework/scheduling/annotation/AsyncResult.java
浏览文件 @
4e25a14f
...
...
@@ -18,8 +18,10 @@ package org.springframework.scheduling.annotation;
import
java.util.concurrent.TimeUnit
;
import
org.springframework.util.concurrent.FailureCallback
;
import
org.springframework.util.concurrent.ListenableFuture
;
import
org.springframework.util.concurrent.ListenableFutureCallback
;
import
org.springframework.util.concurrent.SuccessCallback
;
/**
* A pass-through {@code Future} handle that can be used for method signatures
...
...
@@ -74,7 +76,15 @@ public class AsyncResult<V> implements ListenableFuture<V> {
@Override
public
void
addCallback
(
ListenableFutureCallback
<?
super
V
>
callback
)
{
callback
.
onSuccess
(
this
.
value
);
addCallback
(
callback
,
callback
);
}
@Override
public
void
addCallback
(
SuccessCallback
<?
super
V
>
successCallback
,
FailureCallback
failureCallback
)
{
try
{
successCallback
.
onSuccess
(
this
.
value
);
}
catch
(
Throwable
t
)
{
failureCallback
.
onFailure
(
t
);
}
}
}
spring-core/src/main/java/org/springframework/util/concurrent/FailureCallback.java
0 → 100644
浏览文件 @
4e25a14f
/*
* Copyright 2002-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.util.concurrent
;
/**
* Defines the contract for failure callbacks that accept the result of a
* {@link ListenableFuture}.
*
* @author Sebastien Deleuze
* @since 4.1
*/
public
interface
FailureCallback
{
/**
* Called when the {@link ListenableFuture} fails to complete.
* @param t the exception that triggered the failure
*/
void
onFailure
(
Throwable
t
);
}
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFuture.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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,6 +25,7 @@ import java.util.concurrent.Future;
* <p>Inspired by {@code com.google.common.util.concurrent.ListenableFuture}.
* @author Arjen Poutsma
* @author Sebastien Deleuze
* @since 4.0
*/
public
interface
ListenableFuture
<
T
>
extends
Future
<
T
>
{
...
...
@@ -37,4 +38,15 @@ public interface ListenableFuture<T> extends Future<T> {
*/
void
addCallback
(
ListenableFutureCallback
<?
super
T
>
callback
);
/**
* Registers the given success and failure callbacks to this {@code ListenableFuture}.
* The callback will be triggered when this {@code Future} is complete or, if it is
* already complete immediately. This is a Java 8 lambdas compliant alternative to
* {@link #addCallback(ListenableFutureCallback)}.
* @param successCallback the success callback to register
* @param failureCallback the failure callback to register
* @since 4.1
*/
void
addCallback
(
SuccessCallback
<?
super
T
>
successCallback
,
FailureCallback
failureCallback
);
}
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureAdapter.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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.
...
...
@@ -44,12 +44,18 @@ public abstract class ListenableFutureAdapter<T, S> extends FutureAdapter<T, S>
@Override
public
void
addCallback
(
final
ListenableFutureCallback
<?
super
T
>
callback
)
{
addCallback
(
callback
,
callback
);
}
@Override
public
void
addCallback
(
final
SuccessCallback
<?
super
T
>
successCallback
,
final
FailureCallback
failureCallback
)
{
ListenableFuture
<
S
>
listenableAdaptee
=
(
ListenableFuture
<
S
>)
getAdaptee
();
listenableAdaptee
.
addCallback
(
new
ListenableFutureCallback
<
S
>()
{
@Override
public
void
onSuccess
(
S
result
)
{
try
{
c
allback
.
onSuccess
(
adaptInternal
(
result
));
successC
allback
.
onSuccess
(
adaptInternal
(
result
));
}
catch
(
ExecutionException
ex
)
{
Throwable
cause
=
ex
.
getCause
();
...
...
@@ -62,8 +68,9 @@ public abstract class ListenableFutureAdapter<T, S> extends FutureAdapter<T, S>
@Override
public
void
onFailure
(
Throwable
t
)
{
c
allback
.
onFailure
(
t
);
failureC
allback
.
onFailure
(
t
);
}
});
}
}
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallback.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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,20 +21,9 @@ package org.springframework.util.concurrent;
* {@link ListenableFuture}.
*
* @author Arjen Poutsma
* @author Sebastien Deleuze
* @since 4.0
*/
public
interface
ListenableFutureCallback
<
T
>
{
/**
* Called when the {@link ListenableFuture} successfully completes.
* @param result the result
*/
void
onSuccess
(
T
result
);
/**
* Called when the {@link ListenableFuture} fails to complete.
* @param t the exception that triggered the failure
*/
void
onFailure
(
Throwable
t
);
public
interface
ListenableFutureCallback
<
T
>
extends
SuccessCallback
<
T
>,
FailureCallback
{
}
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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.
...
...
@@ -27,12 +27,16 @@ import org.springframework.util.Assert;
* <p>Inspired by {@code com.google.common.util.concurrent.ExecutionList}.
*
* @author Arjen Poutsma
* @author Sebastien Deleuze
* @since 4.0
*/
public
class
ListenableFutureCallbackRegistry
<
T
>
{
private
final
Queue
<
ListenableFutureCallback
<?
super
T
>>
callbacks
=
new
LinkedList
<
ListenableFutureCallback
<?
super
T
>>();
private
final
Queue
<
SuccessCallback
<?
super
T
>>
successCallbacks
=
new
LinkedList
<
SuccessCallback
<?
super
T
>>();
private
final
Queue
<
FailureCallback
>
failureCallbacks
=
new
LinkedList
<
FailureCallback
>();
private
State
state
=
State
.
NEW
;
...
...
@@ -52,7 +56,8 @@ public class ListenableFutureCallbackRegistry<T> {
synchronized
(
mutex
)
{
switch
(
state
)
{
case
NEW:
callbacks
.
add
(
callback
);
successCallbacks
.
add
(
callback
);
failureCallbacks
.
add
(
callback
);
break
;
case
SUCCESS:
callback
.
onSuccess
((
T
)
result
);
...
...
@@ -64,6 +69,50 @@ public class ListenableFutureCallbackRegistry<T> {
}
}
/**
* Adds the given success callback to this registry.
* @param callback the success callback to add
*
* @since 4.1
*/
@SuppressWarnings
(
"unchecked"
)
public
void
addSuccessCallback
(
SuccessCallback
<?
super
T
>
callback
)
{
Assert
.
notNull
(
callback
,
"'callback' must not be null"
);
synchronized
(
mutex
)
{
switch
(
state
)
{
case
NEW:
successCallbacks
.
add
(
callback
);
break
;
case
SUCCESS:
callback
.
onSuccess
((
T
)
result
);
break
;
}
}
}
/**
* Adds the given failure callback to this registry.
* @param callback the failure callback to add
*
* @since 4.1
*/
@SuppressWarnings
(
"unchecked"
)
public
void
addFailureCallback
(
FailureCallback
callback
)
{
Assert
.
notNull
(
callback
,
"'callback' must not be null"
);
synchronized
(
mutex
)
{
switch
(
state
)
{
case
NEW:
failureCallbacks
.
add
(
callback
);
break
;
case
FAILURE:
callback
.
onFailure
((
Throwable
)
result
);
break
;
}
}
}
/**
* Triggers a {@link ListenableFutureCallback#onSuccess(Object)} call on all added
* callbacks with the given result
...
...
@@ -74,8 +123,8 @@ public class ListenableFutureCallbackRegistry<T> {
state
=
State
.
SUCCESS
;
this
.
result
=
result
;
while
(!
c
allbacks
.
isEmpty
())
{
c
allbacks
.
poll
().
onSuccess
(
result
);
while
(!
successC
allbacks
.
isEmpty
())
{
successC
allbacks
.
poll
().
onSuccess
(
result
);
}
}
}
...
...
@@ -90,8 +139,8 @@ public class ListenableFutureCallbackRegistry<T> {
state
=
State
.
FAILURE
;
this
.
result
=
t
;
while
(!
c
allbacks
.
isEmpty
())
{
c
allbacks
.
poll
().
onFailure
(
t
);
while
(!
failureC
allbacks
.
isEmpty
())
{
failureC
allbacks
.
poll
().
onFailure
(
t
);
}
}
}
...
...
spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureTask.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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.
...
...
@@ -57,6 +57,12 @@ public class ListenableFutureTask<T> extends FutureTask<T> implements Listenable
this
.
callbacks
.
addCallback
(
callback
);
}
@Override
public
void
addCallback
(
SuccessCallback
<?
super
T
>
successCallback
,
FailureCallback
failureCallback
)
{
this
.
callbacks
.
addSuccessCallback
(
successCallback
);
this
.
callbacks
.
addFailureCallback
(
failureCallback
);
}
@Override
protected
final
void
done
()
{
Throwable
cause
;
...
...
spring-core/src/main/java/org/springframework/util/concurrent/SettableListenableFuture.java
浏览文件 @
4e25a14f
...
...
@@ -84,6 +84,11 @@ public class SettableListenableFuture<T> implements ListenableFuture<T> {
this
.
listenableFuture
.
addCallback
(
callback
);
}
@Override
public
void
addCallback
(
SuccessCallback
<?
super
T
>
successCallback
,
FailureCallback
failureCallback
)
{
this
.
listenableFuture
.
addCallback
(
successCallback
,
failureCallback
);
}
@Override
public
boolean
cancel
(
boolean
mayInterruptIfRunning
)
{
this
.
settableTask
.
setCancelled
();
...
...
spring-core/src/main/java/org/springframework/util/concurrent/SuccessCallback.java
0 → 100644
浏览文件 @
4e25a14f
/*
* Copyright 2002-2014 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.springframework.util.concurrent
;
/**
* Defines the contract for success callbacks that accept the result of a
* {@link ListenableFuture}.
*
* @author Sebastien Deleuze
* @since 4.1
*/
public
interface
SuccessCallback
<
T
>
{
/**
* Called when the {@link ListenableFuture} successfully completes.
* @param result the result
*/
void
onSuccess
(
T
result
);
}
spring-core/src/test/java/org/springframework/util/concurrent/ListenableFutureTaskTests.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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.
...
...
@@ -24,8 +24,13 @@ import static org.junit.Assert.assertEquals;
import
static
org
.
junit
.
Assert
.
fail
;
import
org.junit.Test
;
import
static
org
.
mockito
.
Mockito
.
mock
;
import
static
org
.
mockito
.
Mockito
.
verify
;
import
static
org
.
mockito
.
Mockito
.
verifyZeroInteractions
;
/**
* @author Arjen Poutsma
* @author Sebastien Deleuze
*/
public
class
ListenableFutureTaskTests
{
...
...
@@ -77,6 +82,33 @@ public class ListenableFutureTaskTests {
task
.
run
();
}
@Test
public
void
successWithLambdas
()
throws
ExecutionException
,
InterruptedException
{
final
String
s
=
"Hello World"
;
Callable
<
String
>
callable
=
()
->
s
;
SuccessCallback
<
String
>
successCallback
=
mock
(
SuccessCallback
.
class
);
FailureCallback
failureCallback
=
mock
(
FailureCallback
.
class
);
ListenableFutureTask
<
String
>
task
=
new
ListenableFutureTask
<>(
callable
);
task
.
addCallback
(
successCallback
,
failureCallback
);
task
.
run
();
verify
(
successCallback
).
onSuccess
(
s
);
verifyZeroInteractions
(
failureCallback
);
}
@Test
public
void
failureWithLambdas
()
throws
ExecutionException
,
InterruptedException
{
final
String
s
=
"Hello World"
;
IOException
ex
=
new
IOException
(
s
);
Callable
<
String
>
callable
=
()
->
{
throw
ex
;
};
SuccessCallback
<
String
>
successCallback
=
mock
(
SuccessCallback
.
class
);
FailureCallback
failureCallback
=
mock
(
FailureCallback
.
class
);
ListenableFutureTask
<
String
>
task
=
new
ListenableFutureTask
<>(
callable
);
task
.
addCallback
(
successCallback
,
failureCallback
);
task
.
run
();
verify
(
failureCallback
).
onFailure
(
ex
);
verifyZeroInteractions
(
successCallback
);
}
}
spring-messaging/src/main/java/org/springframework/messaging/tcp/reactor/AbstractPromiseToListenableFutureAdapter.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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,9 +21,11 @@ import java.util.concurrent.TimeUnit;
import
java.util.concurrent.TimeoutException
;
import
org.springframework.util.Assert
;
import
org.springframework.util.concurrent.FailureCallback
;
import
org.springframework.util.concurrent.ListenableFuture
;
import
org.springframework.util.concurrent.ListenableFutureCallback
;
import
org.springframework.util.concurrent.ListenableFutureCallbackRegistry
;
import
org.springframework.util.concurrent.SuccessCallback
;
import
reactor.core.composable.Promise
;
import
reactor.function.Consumer
;
...
...
@@ -106,4 +108,9 @@ abstract class AbstractPromiseToListenableFutureAdapter<S, T> implements Listena
this
.
registry
.
addCallback
(
callback
);
}
@Override
public
void
addCallback
(
SuccessCallback
<?
super
T
>
successCallback
,
FailureCallback
failureCallback
)
{
this
.
registry
.
addSuccessCallback
(
successCallback
);
this
.
registry
.
addFailureCallback
(
failureCallback
);
}
}
spring-web/src/main/java/org/springframework/http/client/HttpComponentsAsyncClientHttpRequest.java
浏览文件 @
4e25a14f
...
...
@@ -29,12 +29,15 @@ import org.apache.http.nio.client.HttpAsyncClient;
import
org.apache.http.nio.entity.NByteArrayEntity
;
import
org.apache.http.protocol.HttpContext
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.util.concurrent.FailureCallback
;
import
org.springframework.util.concurrent.FutureAdapter
;
import
org.springframework.util.concurrent.ListenableFuture
;
import
org.springframework.util.concurrent.ListenableFutureCallback
;
import
org.springframework.util.concurrent.ListenableFutureCallbackRegistry
;
import
org.springframework.util.concurrent.SuccessCallback
;
import
org.springframework.http.HttpHeaders
;
import
org.springframework.http.HttpMethod
;
/**
* {@link ClientHttpRequest} implementation that uses Apache HttpComponents HttpClient to
...
...
@@ -101,6 +104,14 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC
this
.
callbacks
.
addCallback
(
callback
);
}
public
void
addSuccessCallback
(
SuccessCallback
<?
super
ClientHttpResponse
>
callback
)
{
this
.
callbacks
.
addSuccessCallback
(
callback
);
}
public
void
addFailureCallback
(
FailureCallback
callback
)
{
this
.
callbacks
.
addFailureCallback
(
callback
);
}
@Override
public
void
completed
(
HttpResponse
result
)
{
this
.
callbacks
.
success
(
new
HttpComponentsAsyncClientHttpResponse
(
result
));
...
...
@@ -136,6 +147,12 @@ final class HttpComponentsAsyncClientHttpRequest extends AbstractBufferingAsyncC
public
void
addCallback
(
ListenableFutureCallback
<?
super
ClientHttpResponse
>
callback
)
{
this
.
callback
.
addCallback
(
callback
);
}
@Override
public
void
addCallback
(
SuccessCallback
<?
super
ClientHttpResponse
>
successCallback
,
FailureCallback
failureCallback
)
{
this
.
callback
.
addSuccessCallback
(
successCallback
);
this
.
callback
.
addFailureCallback
(
failureCallback
);
}
}
...
...
spring-web/src/main/java/org/springframework/web/client/AsyncRestTemplate.java
浏览文件 @
4e25a14f
/*
* Copyright 2002-201
3
the original author or authors.
* Copyright 2002-201
4
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.
...
...
@@ -44,9 +44,11 @@ import org.springframework.http.client.SimpleClientHttpRequestFactory;
import
org.springframework.http.client.support.AsyncHttpAccessor
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.util.Assert
;
import
org.springframework.util.concurrent.FailureCallback
;
import
org.springframework.util.concurrent.ListenableFuture
;
import
org.springframework.util.concurrent.ListenableFutureAdapter
;
import
org.springframework.util.concurrent.ListenableFutureCallback
;
import
org.springframework.util.concurrent.SuccessCallback
;
import
org.springframework.web.util.UriTemplate
;
/**
...
...
@@ -254,15 +256,21 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
@Override
public
void
addCallback
(
final
ListenableFutureCallback
<?
super
URI
>
callback
)
{
addCallback
(
callback
,
callback
);
}
@Override
public
void
addCallback
(
final
SuccessCallback
<?
super
URI
>
successCallback
,
final
FailureCallback
failureCallback
)
{
headersFuture
.
addCallback
(
new
ListenableFutureCallback
<
HttpHeaders
>()
{
@Override
public
void
onSuccess
(
HttpHeaders
result
)
{
c
allback
.
onSuccess
(
result
.
getLocation
());
successC
allback
.
onSuccess
(
result
.
getLocation
());
}
@Override
public
void
onFailure
(
Throwable
t
)
{
c
allback
.
onFailure
(
t
);
failureC
allback
.
onFailure
(
t
);
}
});
}
...
...
@@ -391,17 +399,21 @@ public class AsyncRestTemplate extends AsyncHttpAccessor implements AsyncRestOpe
return
new
ListenableFuture
<
Set
<
HttpMethod
>>()
{
@Override
public
void
addCallback
(
final
ListenableFutureCallback
<?
super
Set
<
HttpMethod
>>
callback
)
{
public
void
addCallback
(
final
ListenableFutureCallback
<?
super
Set
<
HttpMethod
>>
callback
)
{
addCallback
(
callback
,
callback
);
}
@Override
public
void
addCallback
(
final
SuccessCallback
<?
super
Set
<
HttpMethod
>>
successCallback
,
final
FailureCallback
failureCallback
)
{
headersFuture
.
addCallback
(
new
ListenableFutureCallback
<
HttpHeaders
>()
{
@Override
public
void
onSuccess
(
HttpHeaders
result
)
{
c
allback
.
onSuccess
(
result
.
getAllow
());
successC
allback
.
onSuccess
(
result
.
getAllow
());
}
@Override
public
void
onFailure
(
Throwable
t
)
{
c
allback
.
onFailure
(
t
);
failureC
allback
.
onFailure
(
t
);
}
});
}
...
...
spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java
浏览文件 @
4e25a14f
...
...
@@ -45,6 +45,7 @@ import org.springframework.util.concurrent.ListenableFutureCallback;
/**
* @author Arjen Poutsma
* @author Sebastien Deleuze
*/
public
class
AsyncRestTemplateIntegrationTests
extends
AbstractJettyServerTestCase
{
...
...
@@ -98,6 +99,21 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
getEntityCallbackWithLambdas
()
throws
ExecutionException
,
InterruptedException
{
ListenableFuture
<
ResponseEntity
<
String
>>
futureEntity
=
template
.
getForEntity
(
baseUrl
+
"/{method}"
,
String
.
class
,
"get"
);
futureEntity
.
addCallback
((
entity
)
->
{
assertEquals
(
"Invalid content"
,
helloWorld
,
entity
.
getBody
());
assertFalse
(
"No headers"
,
entity
.
getHeaders
().
isEmpty
());
assertEquals
(
"Invalid content-type"
,
textContentType
,
entity
.
getHeaders
().
getContentType
());
assertEquals
(
"Invalid status code"
,
HttpStatus
.
OK
,
entity
.
getStatusCode
());
},
(
t
)
->
fail
(
t
.
getMessage
()));
// wait till done
while
(!
futureEntity
.
isDone
())
{
}
}
@Test
public
void
getNoResponse
()
throws
ExecutionException
,
InterruptedException
{
Future
<
ResponseEntity
<
String
>>
...
...
@@ -164,6 +180,15 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
headForHeadersCallbackWithLambdas
()
throws
ExecutionException
,
InterruptedException
{
ListenableFuture
<
HttpHeaders
>
headersFuture
=
template
.
headForHeaders
(
baseUrl
+
"/get"
);
headersFuture
.
addCallback
(
result
->
assertTrue
(
"No Content-Type header"
,
result
.
containsKey
(
"Content-Type"
)),
t
->
fail
(
t
.
getMessage
()));
while
(!
headersFuture
.
isDone
())
{
}
}
@Test
public
void
postForLocation
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
...
...
@@ -202,6 +227,22 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
postForLocationCallbackWithLambdas
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
HttpHeaders
entityHeaders
=
new
HttpHeaders
();
entityHeaders
.
setContentType
(
new
MediaType
(
"text"
,
"plain"
,
Charset
.
forName
(
"ISO-8859-15"
)));
HttpEntity
<
String
>
entity
=
new
HttpEntity
<
String
>(
helloWorld
,
entityHeaders
);
final
URI
expected
=
new
URI
(
baseUrl
+
"/post/1"
);
ListenableFuture
<
URI
>
locationFuture
=
template
.
postForLocation
(
baseUrl
+
"/{method}"
,
entity
,
"post"
);
locationFuture
.
addCallback
(
result
->
assertEquals
(
"Invalid location"
,
expected
,
result
)
,
t
->
fail
(
t
.
getMessage
()));
while
(!
locationFuture
.
isDone
())
{
}
}
@Test
public
void
postForEntity
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
...
...
@@ -235,6 +276,19 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
postForEntityCallbackWithLambdas
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
HttpEntity
<
String
>
requestEntity
=
new
HttpEntity
<>(
helloWorld
);
ListenableFuture
<
ResponseEntity
<
String
>>
responseEntityFuture
=
template
.
postForEntity
(
baseUrl
+
"/{method}"
,
requestEntity
,
String
.
class
,
"post"
);
responseEntityFuture
.
addCallback
(
result
->
assertEquals
(
"Invalid content"
,
helloWorld
,
result
.
getBody
())
,
t
->
fail
(
t
.
getMessage
()));
while
(!
responseEntityFuture
.
isDone
())
{
}
}
@Test
public
void
put
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
...
...
@@ -294,6 +348,15 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
deleteCallbackWithLambdas
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
ListenableFuture
<?>
deletedFuture
=
template
.
delete
(
new
URI
(
baseUrl
+
"/delete"
));
deletedFuture
.
addCallback
(
result
->
assertNull
(
result
),
t
->
fail
(
t
.
getMessage
()));
while
(!
deletedFuture
.
isDone
())
{
}
}
@Test
public
void
notFound
()
throws
ExecutionException
,
InterruptedException
{
try
{
...
...
@@ -332,6 +395,22 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
notFoundCallbackWithLambdas
()
throws
ExecutionException
,
InterruptedException
{
ListenableFuture
<?>
future
=
template
.
execute
(
baseUrl
+
"/status/notfound"
,
HttpMethod
.
GET
,
null
,
null
);
future
.
addCallback
(
result
->
fail
(
"onSuccess not expected"
),
t
->
{
assertTrue
(
t
instanceof
HttpClientErrorException
);
HttpClientErrorException
ex
=
(
HttpClientErrorException
)
t
;
assertEquals
(
HttpStatus
.
NOT_FOUND
,
ex
.
getStatusCode
());
assertNotNull
(
ex
.
getStatusText
());
assertNotNull
(
ex
.
getResponseBodyAsString
());
});
while
(!
future
.
isDone
())
{
}
}
@Test
public
void
serverError
()
throws
ExecutionException
,
InterruptedException
{
try
{
...
...
@@ -368,6 +447,20 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
serverErrorCallbackWithLambdas
()
throws
ExecutionException
,
InterruptedException
{
ListenableFuture
<
Void
>
future
=
template
.
execute
(
baseUrl
+
"/status/server"
,
HttpMethod
.
GET
,
null
,
null
);
future
.
addCallback
(
result
->
fail
(
"onSuccess not expected"
),
t
->
{
assertTrue
(
t
instanceof
HttpServerErrorException
);
HttpServerErrorException
ex
=
(
HttpServerErrorException
)
t
;
assertEquals
(
HttpStatus
.
INTERNAL_SERVER_ERROR
,
ex
.
getStatusCode
());
assertNotNull
(
ex
.
getStatusText
());
assertNotNull
(
ex
.
getResponseBodyAsString
());
});
while
(!
future
.
isDone
())
{
}
}
@Test
public
void
optionsForAllow
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
...
...
@@ -386,8 +479,8 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
allowedFuture
.
addCallback
(
new
ListenableFutureCallback
<
Set
<
HttpMethod
>>()
{
@Override
public
void
onSuccess
(
Set
<
HttpMethod
>
result
)
{
assertEquals
(
"Invalid response"
,
EnumSet
.
of
(
HttpMethod
.
GET
,
HttpMethod
.
OPTIONS
,
HttpMethod
.
HEAD
,
HttpMethod
.
TRACE
),
result
);
assertEquals
(
"Invalid response"
,
EnumSet
.
of
(
HttpMethod
.
GET
,
HttpMethod
.
OPTIONS
,
HttpMethod
.
HEAD
,
HttpMethod
.
TRACE
),
result
);
}
@Override
...
...
@@ -399,6 +492,18 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
public
void
optionsForAllowCallbackWithLambdas
()
throws
URISyntaxException
,
ExecutionException
,
InterruptedException
{
ListenableFuture
<
Set
<
HttpMethod
>>
allowedFuture
=
template
.
optionsForAllow
(
new
URI
(
baseUrl
+
"/get"
));
allowedFuture
.
addCallback
(
result
->
assertEquals
(
"Invalid response"
,
EnumSet
.
of
(
HttpMethod
.
GET
,
HttpMethod
.
OPTIONS
,
HttpMethod
.
HEAD
,
HttpMethod
.
TRACE
),
result
),
t
->
fail
(
t
.
getMessage
()));
while
(!
allowedFuture
.
isDone
())
{
}
}
@Test
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
public
void
exchangeGet
()
throws
Exception
{
...
...
@@ -436,6 +541,21 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
}
}
@Test
@SuppressWarnings
({
"unchecked"
,
"rawtypes"
})
public
void
exchangeGetCallbackWithLambdas
()
throws
Exception
{
HttpHeaders
requestHeaders
=
new
HttpHeaders
();
requestHeaders
.
set
(
"MyHeader"
,
"MyValue"
);
HttpEntity
<?>
requestEntity
=
new
HttpEntity
(
requestHeaders
);
ListenableFuture
<
ResponseEntity
<
String
>>
responseFuture
=
template
.
exchange
(
baseUrl
+
"/{method}"
,
HttpMethod
.
GET
,
requestEntity
,
String
.
class
,
"get"
);
responseFuture
.
addCallback
(
result
->
assertEquals
(
"Invalid content"
,
helloWorld
,
result
.
getBody
()),
t
->
fail
(
t
.
getMessage
()));
while
(!
responseFuture
.
isDone
())
{
}
}
@Test
public
void
exchangePost
()
throws
Exception
{
HttpHeaders
requestHeaders
=
new
HttpHeaders
();
...
...
@@ -476,7 +596,24 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa
});
while
(!
resultFuture
.
isDone
())
{
}
}
@Test
public
void
exchangePostCallbackWithLambdas
()
throws
Exception
{
HttpHeaders
requestHeaders
=
new
HttpHeaders
();
requestHeaders
.
set
(
"MyHeader"
,
"MyValue"
);
requestHeaders
.
setContentType
(
MediaType
.
TEXT_PLAIN
);
HttpEntity
<
String
>
requestEntity
=
new
HttpEntity
<
String
>(
helloWorld
,
requestHeaders
);
ListenableFuture
<
ResponseEntity
<
Void
>>
resultFuture
=
template
.
exchange
(
baseUrl
+
"/{method}"
,
HttpMethod
.
POST
,
requestEntity
,
Void
.
class
,
"post"
);
final
URI
expected
=
new
URI
(
baseUrl
+
"/post/1"
);
resultFuture
.
addCallback
(
result
->
{
assertEquals
(
"Invalid location"
,
expected
,
result
.
getHeaders
().
getLocation
());
assertFalse
(
result
.
hasBody
());
},
t
->
fail
(
t
.
getMessage
()));
while
(!
resultFuture
.
isDone
())
{
}
}
@Test
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录