Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
6f3051c6
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,发现更多精彩内容 >>
提交
6f3051c6
编写于
5月 03, 2017
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support for @RequestPart with reactive type wrapper
Issue: SPR-14546
上级
fc7beded
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
34 addition
and
38 deletion
+34
-38
spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java
...ramework/web/server/adapter/DefaultServerWebExchange.java
+18
-29
spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestPartMethodArgumentResolver.java
.../method/annotation/RequestPartMethodArgumentResolver.java
+11
-7
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MultipartIntegrationTests.java
...e/result/method/annotation/MultipartIntegrationTests.java
+5
-2
未找到文件。
spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java
浏览文件 @
6f3051c6
...
@@ -48,9 +48,6 @@ import org.springframework.web.server.ServerWebExchange;
...
@@ -48,9 +48,6 @@ import org.springframework.web.server.ServerWebExchange;
import
org.springframework.web.server.WebSession
;
import
org.springframework.web.server.WebSession
;
import
org.springframework.web.server.session.WebSessionManager
;
import
org.springframework.web.server.session.WebSessionManager
;
import
static
org
.
springframework
.
http
.
MediaType
.
APPLICATION_FORM_URLENCODED
;
import
static
org
.
springframework
.
http
.
MediaType
.
MULTIPART_FORM_DATA
;
/**
/**
* Default implementation of {@link ServerWebExchange}.
* Default implementation of {@link ServerWebExchange}.
*
*
...
@@ -61,10 +58,10 @@ public class DefaultServerWebExchange implements ServerWebExchange {
...
@@ -61,10 +58,10 @@ public class DefaultServerWebExchange implements ServerWebExchange {
private
static
final
List
<
HttpMethod
>
SAFE_METHODS
=
Arrays
.
asList
(
HttpMethod
.
GET
,
HttpMethod
.
HEAD
);
private
static
final
List
<
HttpMethod
>
SAFE_METHODS
=
Arrays
.
asList
(
HttpMethod
.
GET
,
HttpMethod
.
HEAD
);
private
static
final
ResolvableType
FORM_DATA_
VALUE_
TYPE
=
private
static
final
ResolvableType
FORM_DATA_TYPE
=
ResolvableType
.
forClassWithGenerics
(
MultiValueMap
.
class
,
String
.
class
,
String
.
class
);
ResolvableType
.
forClassWithGenerics
(
MultiValueMap
.
class
,
String
.
class
,
String
.
class
);
private
static
final
ResolvableType
MULTIPART_
VALUE
_TYPE
=
ResolvableType
.
forClassWithGenerics
(
private
static
final
ResolvableType
MULTIPART_
DATA
_TYPE
=
ResolvableType
.
forClassWithGenerics
(
MultiValueMap
.
class
,
String
.
class
,
Part
.
class
);
MultiValueMap
.
class
,
String
.
class
,
Part
.
class
);
private
static
final
Mono
<
MultiValueMap
<
String
,
String
>>
EMPTY_FORM_DATA
=
private
static
final
Mono
<
MultiValueMap
<
String
,
String
>>
EMPTY_FORM_DATA
=
...
@@ -110,21 +107,17 @@ public class DefaultServerWebExchange implements ServerWebExchange {
...
@@ -110,21 +107,17 @@ public class DefaultServerWebExchange implements ServerWebExchange {
}
}
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
private
static
Mono
<
MultiValueMap
<
String
,
String
>>
initFormData
(
private
static
Mono
<
MultiValueMap
<
String
,
String
>>
initFormData
(
ServerHttpRequest
request
,
Server
HttpRequest
request
,
ServerCodecConfigurer
codecC
onfigurer
)
{
Server
CodecConfigurer
c
onfigurer
)
{
MediaType
contentType
;
try
{
try
{
contentType
=
request
.
getHeaders
().
getContentType
();
MediaType
contentType
=
request
.
getHeaders
().
getContentType
();
if
(
APPLICATION_FORM_URLENCODED
.
isCompatibleWith
(
contentType
))
{
if
(
MediaType
.
APPLICATION_FORM_URLENCODED
.
isCompatibleWith
(
contentType
))
{
return
((
HttpMessageReader
<
MultiValueMap
<
String
,
String
>>)
codecConfigurer
return
((
HttpMessageReader
<
MultiValueMap
<
String
,
String
>>)
configurer
.
getReaders
().
stream
()
.
getReaders
()
.
filter
(
reader
->
reader
.
canRead
(
FORM_DATA_TYPE
,
MediaType
.
APPLICATION_FORM_URLENCODED
))
.
stream
()
.
filter
(
reader
->
reader
.
canRead
(
FORM_DATA_VALUE_TYPE
,
APPLICATION_FORM_URLENCODED
))
.
findFirst
()
.
findFirst
()
.
orElseThrow
(()
->
new
IllegalStateException
(
.
orElseThrow
(()
->
new
IllegalStateException
(
"No form data HttpMessageReader."
)))
"Could not find HttpMessageReader that supports "
+
APPLICATION_FORM_URLENCODED
)))
.
readMono
(
FORM_DATA_TYPE
,
request
,
Collections
.
emptyMap
())
.
readMono
(
FORM_DATA_VALUE_TYPE
,
request
,
Collections
.
emptyMap
())
.
switchIfEmpty
(
EMPTY_FORM_DATA
)
.
switchIfEmpty
(
EMPTY_FORM_DATA
)
.
cache
();
.
cache
();
}
}
...
@@ -136,21 +129,17 @@ public class DefaultServerWebExchange implements ServerWebExchange {
...
@@ -136,21 +129,17 @@ public class DefaultServerWebExchange implements ServerWebExchange {
}
}
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
private
static
Mono
<
MultiValueMap
<
String
,
Part
>>
initMultipartData
(
private
static
Mono
<
MultiValueMap
<
String
,
Part
>>
initMultipartData
(
ServerHttpRequest
request
,
Server
HttpRequest
request
,
ServerCodecConfigurer
codecC
onfigurer
)
{
Server
CodecConfigurer
c
onfigurer
)
{
MediaType
contentType
;
try
{
try
{
contentType
=
request
.
getHeaders
().
getContentType
();
MediaType
contentType
=
request
.
getHeaders
().
getContentType
();
if
(
MULTIPART_FORM_DATA
.
isCompatibleWith
(
contentType
))
{
if
(
MediaType
.
MULTIPART_FORM_DATA
.
isCompatibleWith
(
contentType
))
{
return
((
HttpMessageReader
<
MultiValueMap
<
String
,
Part
>>)
codecConfigurer
return
((
HttpMessageReader
<
MultiValueMap
<
String
,
Part
>>)
configurer
.
getReaders
().
stream
()
.
getReaders
()
.
filter
(
reader
->
reader
.
canRead
(
MULTIPART_DATA_TYPE
,
MediaType
.
MULTIPART_FORM_DATA
))
.
stream
()
.
filter
(
reader
->
reader
.
canRead
(
MULTIPART_VALUE_TYPE
,
MULTIPART_FORM_DATA
))
.
findFirst
()
.
findFirst
()
.
orElseThrow
(()
->
new
IllegalStateException
(
.
orElseThrow
(()
->
new
IllegalStateException
(
"No multipart HttpMessageReader."
)))
"Could not find HttpMessageReader that supports "
+
MULTIPART_FORM_DATA
)))
.
readMono
(
MULTIPART_DATA_TYPE
,
request
,
Collections
.
emptyMap
())
.
readMono
(
FORM_DATA_VALUE_TYPE
,
request
,
Collections
.
emptyMap
())
.
switchIfEmpty
(
EMPTY_MULTIPART_DATA
)
.
switchIfEmpty
(
EMPTY_MULTIPART_DATA
)
.
cache
();
.
cache
();
}
}
...
...
spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestPartMethodArgumentResolver.java
浏览文件 @
6f3051c6
...
@@ -21,6 +21,7 @@ import java.util.List;
...
@@ -21,6 +21,7 @@ import java.util.List;
import
reactor.core.publisher.Mono
;
import
reactor.core.publisher.Mono
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.MethodParameter
;
import
org.springframework.core.ReactiveAdapter
;
import
org.springframework.core.ReactiveAdapterRegistry
;
import
org.springframework.core.ReactiveAdapterRegistry
;
import
org.springframework.http.codec.multipart.Part
;
import
org.springframework.http.codec.multipart.Part
;
import
org.springframework.util.CollectionUtils
;
import
org.springframework.util.CollectionUtils
;
...
@@ -61,13 +62,16 @@ public class RequestPartMethodArgumentResolver extends AbstractNamedValueArgumen
...
@@ -61,13 +62,16 @@ public class RequestPartMethodArgumentResolver extends AbstractNamedValueArgumen
@Override
@Override
protected
Mono
<
Object
>
resolveName
(
String
name
,
MethodParameter
param
,
ServerWebExchange
exchange
)
{
protected
Mono
<
Object
>
resolveName
(
String
name
,
MethodParameter
param
,
ServerWebExchange
exchange
)
{
return
exchange
.
getMultipartData
().
flatMap
(
allParts
->
{
List
<
Part
>
parts
=
allParts
.
get
(
name
);
Mono
<
Object
>
partsMono
=
exchange
.
getMultipartData
()
if
(
CollectionUtils
.
isEmpty
(
parts
))
{
.
filter
(
map
->
!
CollectionUtils
.
isEmpty
(
map
.
get
(
name
)))
return
Mono
.
empty
();
.
map
(
map
->
{
}
List
<
Part
>
parts
=
map
.
get
(
name
);
return
Mono
.
just
(
parts
.
size
()
==
1
?
parts
.
get
(
0
)
:
parts
);
return
parts
.
size
()
==
1
?
parts
.
get
(
0
)
:
parts
;
});
});
ReactiveAdapter
adapter
=
getAdapterRegistry
().
getAdapter
(
param
.
getParameterType
());
return
(
adapter
!=
null
?
Mono
.
just
(
adapter
.
fromPublisher
(
partsMono
))
:
partsMono
);
}
}
@Override
@Override
...
...
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/MultipartIntegrationTests.java
浏览文件 @
6f3051c6
...
@@ -16,6 +16,7 @@
...
@@ -16,6 +16,7 @@
package
org.springframework.web.reactive.result.method.annotation
;
package
org.springframework.web.reactive.result.method.annotation
;
import
java.time.Duration
;
import
java.util.Map
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
java.util.stream.Collectors
;
...
@@ -34,6 +35,7 @@ import org.springframework.http.HttpHeaders;
...
@@ -34,6 +35,7 @@ import org.springframework.http.HttpHeaders;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.codec.multipart.FilePart
;
import
org.springframework.http.codec.multipart.FilePart
;
import
org.springframework.http.codec.multipart.FormFieldPart
;
import
org.springframework.http.codec.multipart.Part
;
import
org.springframework.http.codec.multipart.Part
;
import
org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests
;
import
org.springframework.http.server.reactive.AbstractHttpHandlerIntegrationTests
;
import
org.springframework.http.server.reactive.HttpHandler
;
import
org.springframework.http.server.reactive.HttpHandler
;
...
@@ -152,8 +154,9 @@ public class MultipartIntegrationTests extends AbstractHttpHandlerIntegrationTes
...
@@ -152,8 +154,9 @@ public class MultipartIntegrationTests extends AbstractHttpHandlerIntegrationTes
static
class
MultipartController
{
static
class
MultipartController
{
@PostMapping
(
"/requestPart"
)
@PostMapping
(
"/requestPart"
)
void
requestPart
(
@RequestPart
Part
fooPart
)
{
void
requestPart
(
@RequestPart
FormFieldPart
barPart
,
@RequestPart
Mono
<
FilePart
>
fooPart
)
{
assertEquals
(
"foo.txt"
,
((
FilePart
)
fooPart
).
getFilename
());
assertEquals
(
"bar"
,
barPart
.
getValue
());
assertEquals
(
"foo.txt"
,
fooPart
.
block
(
Duration
.
ZERO
).
getFilename
());
}
}
@PostMapping
(
"/requestBodyMap"
)
@PostMapping
(
"/requestBodyMap"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录