Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
1f283acb
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,发现更多精彩内容 >>
提交
1f283acb
编写于
4月 18, 2016
作者:
R
Rossen Stoyanchev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add path extension and parameter ContentTypeResolver's
上级
9ffc0b5e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
678 addition
and
0 deletion
+678
-0
spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/AbstractMappingContentTypeResolver.java
...b/reactive/accept/AbstractMappingContentTypeResolver.java
+159
-0
spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/ParameterContentTypeResolver.java
...ork/web/reactive/accept/ParameterContentTypeResolver.java
+82
-0
spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
...web/reactive/accept/PathExtensionContentTypeResolver.java
+196
-0
spring-web-reactive/src/test/java/org/springframework/web/reactive/accept/MappingContentTypeResolverTests.java
.../web/reactive/accept/MappingContentTypeResolverTests.java
+122
-0
spring-web-reactive/src/test/java/org/springframework/web/reactive/accept/PathExtensionContentNegotiationStrategyTests.java
.../accept/PathExtensionContentNegotiationStrategyTests.java
+119
-0
未找到文件。
spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/AbstractMappingContentTypeResolver.java
0 → 100644
浏览文件 @
1f283acb
/*
* Copyright 2002-2016 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.web.reactive.accept
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Locale
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentMap
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.LinkedMultiValueMap
;
import
org.springframework.util.MultiValueMap
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.server.ServerWebExchange
;
/**
* Abstract base class for {@link MappingContentTypeResolver} implementations.
* Maintains the actual mappings and pre-implements the overall algorithm with
* sub-classes left to provide a way to extract the lookup key (e.g. file
* extension, query parameter, etc) for a given exchange.
*
* @author Rossen Stoyanchev
*/
public
abstract
class
AbstractMappingContentTypeResolver
implements
MappingContentTypeResolver
{
/** Primary lookup for media types by key (e.g. "json" -> "application/json") */
private
final
ConcurrentMap
<
String
,
MediaType
>
mediaTypeLookup
=
new
ConcurrentHashMap
<>(
64
);
/** Reverse lookup for keys associated with a media type */
private
final
MultiValueMap
<
MediaType
,
String
>
keyLookup
=
new
LinkedMultiValueMap
<>(
64
);
/**
* Create an instance with the given map of file extensions and media types.
*/
public
AbstractMappingContentTypeResolver
(
Map
<
String
,
MediaType
>
mediaTypes
)
{
if
(
mediaTypes
!=
null
)
{
for
(
Map
.
Entry
<
String
,
MediaType
>
entry
:
mediaTypes
.
entrySet
())
{
String
extension
=
entry
.
getKey
().
toLowerCase
(
Locale
.
ENGLISH
);
MediaType
mediaType
=
entry
.
getValue
();
this
.
mediaTypeLookup
.
put
(
extension
,
mediaType
);
this
.
keyLookup
.
add
(
mediaType
,
extension
);
}
}
}
/**
* Sub-classes can use this method to look up a MediaType by key.
* @param key the key converted to lower case
* @return a MediaType or {@code null}
*/
protected
MediaType
getMediaType
(
String
key
)
{
return
this
.
mediaTypeLookup
.
get
(
key
.
toLowerCase
(
Locale
.
ENGLISH
));
}
/**
* Sub-classes can use this method get all mapped media types.
*/
protected
List
<
MediaType
>
getMediaTypes
()
{
return
new
ArrayList
<>(
this
.
mediaTypeLookup
.
values
());
}
// ContentTypeResolver implementation
@Override
public
List
<
MediaType
>
resolveMediaTypes
(
ServerWebExchange
exchange
)
throws
HttpMediaTypeNotAcceptableException
{
String
key
=
extractKey
(
exchange
);
return
resolveMediaTypes
(
key
);
}
/**
* An overloaded resolve method with a pre-resolved lookup key.
* @param key the key for looking up media types
* @return a list of resolved media types or an empty list
* @throws HttpMediaTypeNotAcceptableException
*/
public
List
<
MediaType
>
resolveMediaTypes
(
String
key
)
throws
HttpMediaTypeNotAcceptableException
{
if
(
StringUtils
.
hasText
(
key
))
{
MediaType
mediaType
=
getMediaType
(
key
);
if
(
mediaType
!=
null
)
{
handleMatch
(
key
,
mediaType
);
return
Collections
.
singletonList
(
mediaType
);
}
mediaType
=
handleNoMatch
(
key
);
if
(
mediaType
!=
null
)
{
MediaType
previous
=
this
.
mediaTypeLookup
.
putIfAbsent
(
key
,
mediaType
);
if
(
previous
==
null
)
{
this
.
keyLookup
.
add
(
mediaType
,
key
);
}
return
Collections
.
singletonList
(
mediaType
);
}
}
return
Collections
.
emptyList
();
}
/**
* Extract the key to use to look up a media type from the given exchange,
* e.g. file extension, query parameter, etc.
* @return the key or {@code null}
*/
protected
abstract
String
extractKey
(
ServerWebExchange
exchange
);
/**
* Override to provide handling when a key is successfully resolved via
* {@link #getMediaType(String)}.
*/
@SuppressWarnings
(
"UnusedParameters"
)
protected
void
handleMatch
(
String
key
,
MediaType
mediaType
)
{
}
/**
* Override to provide handling when a key is not resolved via.
* {@link #getMediaType(String)}. If a MediaType is returned from
* this method it will be added to the mappings.
*/
@SuppressWarnings
(
"UnusedParameters"
)
protected
MediaType
handleNoMatch
(
String
key
)
throws
HttpMediaTypeNotAcceptableException
{
return
null
;
}
// MappingContentTypeResolver implementation
@Override
public
Set
<
String
>
getKeysFor
(
MediaType
mediaType
)
{
List
<
String
>
keys
=
this
.
keyLookup
.
get
(
mediaType
);
return
(
keys
!=
null
?
new
HashSet
<>(
keys
)
:
Collections
.
emptySet
());
}
@Override
public
Set
<
String
>
getKeys
()
{
return
new
HashSet
<>(
this
.
mediaTypeLookup
.
keySet
());
}
}
spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/ParameterContentTypeResolver.java
0 → 100644
浏览文件 @
1f283acb
/*
* Copyright 2002-2016 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.web.reactive.accept
;
import
java.util.Map
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.Assert
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.server.ServerWebExchange
;
/**
* A {@link ContentTypeResolver} that extracts the media type lookup key from a
* known query parameter named "format" by default.
*s
* @author Rossen Stoyanchev
*/
public
class
ParameterContentTypeResolver
extends
AbstractMappingContentTypeResolver
{
private
static
final
Log
logger
=
LogFactory
.
getLog
(
ParameterContentTypeResolver
.
class
);
private
String
parameterName
=
"format"
;
/**
* Create an instance with the given map of file extensions and media types.
*/
public
ParameterContentTypeResolver
(
Map
<
String
,
MediaType
>
mediaTypes
)
{
super
(
mediaTypes
);
}
/**
* Set the name of the parameter to use to determine requested media types.
* <p>By default this is set to {@code "format"}.
*/
public
void
setParameterName
(
String
parameterName
)
{
Assert
.
notNull
(
parameterName
,
"parameterName is required"
);
this
.
parameterName
=
parameterName
;
}
public
String
getParameterName
()
{
return
this
.
parameterName
;
}
@Override
protected
String
extractKey
(
ServerWebExchange
exchange
)
{
return
exchange
.
getRequest
().
getQueryParams
().
getFirst
(
getParameterName
());
}
@Override
protected
void
handleMatch
(
String
mediaTypeKey
,
MediaType
mediaType
)
{
if
(
logger
.
isDebugEnabled
())
{
logger
.
debug
(
"Requested media type is '"
+
mediaType
+
"' based on '"
+
getParameterName
()
+
"'='"
+
mediaTypeKey
+
"'."
);
}
}
@Override
protected
MediaType
handleNoMatch
(
String
key
)
throws
HttpMediaTypeNotAcceptableException
{
throw
new
HttpMediaTypeNotAcceptableException
(
getMediaTypes
());
}
}
spring-web-reactive/src/main/java/org/springframework/web/reactive/accept/PathExtensionContentTypeResolver.java
0 → 100644
浏览文件 @
1f283acb
/*
* Copyright 2002-2016 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.web.reactive.accept
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.Locale
;
import
java.util.Map
;
import
javax.activation.FileTypeMap
;
import
javax.activation.MimetypesFileTypeMap
;
import
org.apache.commons.logging.Log
;
import
org.apache.commons.logging.LogFactory
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.core.io.Resource
;
import
org.springframework.http.MediaType
;
import
org.springframework.util.Assert
;
import
org.springframework.util.ClassUtils
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.accept.PathExtensionContentNegotiationStrategy
;
import
org.springframework.web.server.ServerWebExchange
;
import
org.springframework.web.util.WebUtils
;
/**
* A {@link ContentTypeResolver} that extracts the file extension from the
* request path and uses that as the media type lookup key.
*
* <p>If the file extension is not found in the explicit registrations provided
* to the constructor, the Java Activation Framework (JAF) is used as a fallback
* mechanism. The presence of the JAF is detected and enabled automatically but
* the {@link #setUseJaf(boolean)} property may be set to false.
*
* @author Rossen Stoyanchev
*/
public
class
PathExtensionContentTypeResolver
extends
AbstractMappingContentTypeResolver
{
private
static
final
Log
logger
=
LogFactory
.
getLog
(
PathExtensionContentNegotiationStrategy
.
class
);
private
static
final
boolean
JAF_PRESENT
=
ClassUtils
.
isPresent
(
"javax.activation.FileTypeMap"
,
PathExtensionContentNegotiationStrategy
.
class
.
getClassLoader
());
private
boolean
useJaf
=
true
;
private
boolean
ignoreUnknownExtensions
=
true
;
/**
* Create an instance with the given map of file extensions and media types.
*/
public
PathExtensionContentTypeResolver
(
Map
<
String
,
MediaType
>
mediaTypes
)
{
super
(
mediaTypes
);
}
/**
* Create an instance without any mappings to start with. Mappings may be added
* later on if any extensions are resolved through the Java Activation framework.
*/
public
PathExtensionContentTypeResolver
()
{
super
(
null
);
}
/**
* Whether to use the Java Activation Framework to look up file extensions.
* <p>By default this is set to "true" but depends on JAF being present.
*/
public
void
setUseJaf
(
boolean
useJaf
)
{
this
.
useJaf
=
useJaf
;
}
/**
* Whether to ignore requests with unknown file extension. Setting this to
* {@code false} results in {@code HttpMediaTypeNotAcceptableException}.
* <p>By default this is set to {@code true}.
*/
public
void
setIgnoreUnknownExtensions
(
boolean
ignoreUnknownExtensions
)
{
this
.
ignoreUnknownExtensions
=
ignoreUnknownExtensions
;
}
@Override
protected
String
extractKey
(
ServerWebExchange
exchange
)
{
String
path
=
exchange
.
getRequest
().
getURI
().
getRawPath
();
String
filename
=
WebUtils
.
extractFullFilenameFromUrlPath
(
path
);
String
extension
=
StringUtils
.
getFilenameExtension
(
filename
);
return
(
StringUtils
.
hasText
(
extension
))
?
extension
.
toLowerCase
(
Locale
.
ENGLISH
)
:
null
;
}
@Override
protected
MediaType
handleNoMatch
(
String
key
)
throws
HttpMediaTypeNotAcceptableException
{
if
(
this
.
useJaf
&&
JAF_PRESENT
)
{
MediaType
mediaType
=
JafMediaTypeFactory
.
getMediaType
(
"file."
+
key
);
if
(
mediaType
!=
null
&&
!
MediaType
.
APPLICATION_OCTET_STREAM
.
equals
(
mediaType
))
{
return
mediaType
;
}
}
if
(!
this
.
ignoreUnknownExtensions
)
{
throw
new
HttpMediaTypeNotAcceptableException
(
getMediaTypes
());
}
return
null
;
}
/**
* A public method exposing the knowledge of the path extension resolver to
* determine the media type for a given {@link Resource}. First it checks
* the explicitly registered mappings and then falls back on JAF.
* @param resource the resource
* @return the MediaType for the extension or {@code null}.
*/
public
MediaType
resolveMediaTypeForResource
(
Resource
resource
)
{
Assert
.
notNull
(
resource
);
MediaType
mediaType
=
null
;
String
filename
=
resource
.
getFilename
();
String
extension
=
StringUtils
.
getFilenameExtension
(
filename
);
if
(
extension
!=
null
)
{
mediaType
=
getMediaType
(
extension
);
}
if
(
mediaType
==
null
&&
JAF_PRESENT
)
{
mediaType
=
JafMediaTypeFactory
.
getMediaType
(
filename
);
}
if
(
MediaType
.
APPLICATION_OCTET_STREAM
.
equals
(
mediaType
))
{
mediaType
=
null
;
}
return
mediaType
;
}
/**
* Inner class to avoid hard-coded dependency on JAF.
*/
private
static
class
JafMediaTypeFactory
{
private
static
final
FileTypeMap
fileTypeMap
;
static
{
fileTypeMap
=
initFileTypeMap
();
}
/**
* Find extended mime.types from the spring-context-support module.
*/
private
static
FileTypeMap
initFileTypeMap
()
{
Resource
resource
=
new
ClassPathResource
(
"org/springframework/mail/javamail/mime.types"
);
if
(
resource
.
exists
())
{
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"Loading JAF FileTypeMap from "
+
resource
);
}
InputStream
inputStream
=
null
;
try
{
inputStream
=
resource
.
getInputStream
();
return
new
MimetypesFileTypeMap
(
inputStream
);
}
catch
(
IOException
ex
)
{
// ignore
}
finally
{
if
(
inputStream
!=
null
)
{
try
{
inputStream
.
close
();
}
catch
(
IOException
ex
)
{
// ignore
}
}
}
}
if
(
logger
.
isTraceEnabled
())
{
logger
.
trace
(
"Loading default Java Activation Framework FileTypeMap"
);
}
return
FileTypeMap
.
getDefaultFileTypeMap
();
}
public
static
MediaType
getMediaType
(
String
filename
)
{
String
mediaType
=
fileTypeMap
.
getContentType
(
filename
);
return
(
StringUtils
.
hasText
(
mediaType
)
?
MediaType
.
parseMediaType
(
mediaType
)
:
null
);
}
}
}
spring-web-reactive/src/test/java/org/springframework/web/reactive/accept/MappingContentTypeResolverTests.java
0 → 100644
浏览文件 @
1f283acb
/*
* Copyright 2002-2016 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.web.reactive.accept
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
org.junit.Test
;
import
org.springframework.http.MediaType
;
import
org.springframework.web.server.ServerWebExchange
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
/**
* Unit tests for {@link AbstractMappingContentTypeResolver}.
* @author Rossen Stoyanchev
*/
public
class
MappingContentTypeResolverTests
{
@Test
public
void
resolveExtensions
()
{
Map
<
String
,
MediaType
>
mapping
=
Collections
.
singletonMap
(
"json"
,
MediaType
.
APPLICATION_JSON
);
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
""
,
mapping
);
Set
<
String
>
keys
=
resolver
.
getKeysFor
(
MediaType
.
APPLICATION_JSON
);
assertEquals
(
1
,
keys
.
size
());
assertEquals
(
"json"
,
keys
.
iterator
().
next
());
}
@Test
public
void
resolveExtensionsNoMatch
()
{
Map
<
String
,
MediaType
>
mapping
=
Collections
.
singletonMap
(
"json"
,
MediaType
.
APPLICATION_JSON
);
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
""
,
mapping
);
Set
<
String
>
keys
=
resolver
.
getKeysFor
(
MediaType
.
TEXT_HTML
);
assertTrue
(
keys
.
isEmpty
());
}
@Test
// SPR-13747
public
void
lookupMediaTypeCaseInsensitive
()
{
Map
<
String
,
MediaType
>
mapping
=
Collections
.
singletonMap
(
"json"
,
MediaType
.
APPLICATION_JSON
);
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
""
,
mapping
);
MediaType
mediaType
=
resolver
.
getMediaType
(
"JSoN"
);
assertEquals
(
mediaType
,
MediaType
.
APPLICATION_JSON
);
}
@Test
public
void
resolveMediaTypes
()
throws
Exception
{
Map
<
String
,
MediaType
>
mapping
=
Collections
.
singletonMap
(
"json"
,
MediaType
.
APPLICATION_JSON
);
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
"json"
,
mapping
);
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
((
ServerWebExchange
)
null
);
assertEquals
(
1
,
mediaTypes
.
size
());
assertEquals
(
"application/json"
,
mediaTypes
.
get
(
0
).
toString
());
}
@Test
public
void
resolveMediaTypesNoMatch
()
throws
Exception
{
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
"blah"
,
null
);
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
((
ServerWebExchange
)
null
);
assertEquals
(
0
,
mediaTypes
.
size
());
}
@Test
public
void
resolveMediaTypesNoKey
()
throws
Exception
{
Map
<
String
,
MediaType
>
mapping
=
Collections
.
singletonMap
(
"json"
,
MediaType
.
APPLICATION_JSON
);
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
null
,
mapping
);
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
((
ServerWebExchange
)
null
);
assertEquals
(
0
,
mediaTypes
.
size
());
}
@Test
public
void
resolveMediaTypesHandleNoMatch
()
throws
Exception
{
TestMappingContentTypeResolver
resolver
=
new
TestMappingContentTypeResolver
(
"xml"
,
null
);
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
((
ServerWebExchange
)
null
);
assertEquals
(
1
,
mediaTypes
.
size
());
assertEquals
(
"application/xml"
,
mediaTypes
.
get
(
0
).
toString
());
}
private
static
class
TestMappingContentTypeResolver
extends
AbstractMappingContentTypeResolver
{
private
final
String
key
;
public
TestMappingContentTypeResolver
(
String
key
,
Map
<
String
,
MediaType
>
mapping
)
{
super
(
mapping
);
this
.
key
=
key
;
}
@Override
protected
String
extractKey
(
ServerWebExchange
exchange
)
{
return
this
.
key
;
}
@Override
protected
MediaType
handleNoMatch
(
String
mappingKey
)
{
return
"xml"
.
equals
(
mappingKey
)
?
MediaType
.
APPLICATION_XML
:
null
;
}
}
}
spring-web-reactive/src/test/java/org/springframework/web/reactive/accept/PathExtensionContentNegotiationStrategyTests.java
0 → 100644
浏览文件 @
1f283acb
/*
* Copyright 2002-2016 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.web.reactive.accept
;
import
java.net.URI
;
import
java.net.URISyntaxException
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
org.junit.Test
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.server.reactive.MockServerHttpRequest
;
import
org.springframework.http.server.reactive.MockServerHttpResponse
;
import
org.springframework.http.server.reactive.ServerHttpRequest
;
import
org.springframework.web.HttpMediaTypeNotAcceptableException
;
import
org.springframework.web.server.ServerWebExchange
;
import
org.springframework.web.server.adapter.DefaultServerWebExchange
;
import
org.springframework.web.server.session.WebSessionManager
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
mockito
.
Mockito
.
mock
;
/**
* Unit tests for {@link PathExtensionContentTypeResolver}.
*
* @author Rossen Stoyanchev
*/
public
class
PathExtensionContentNegotiationStrategyTests
{
@Test
public
void
resolveMediaTypesFromMapping
()
throws
Exception
{
ServerWebExchange
exchange
=
createExchange
(
"/test.html"
);
PathExtensionContentTypeResolver
resolver
=
new
PathExtensionContentTypeResolver
();
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
(
exchange
);
assertEquals
(
Collections
.
singletonList
(
new
MediaType
(
"text"
,
"html"
)),
mediaTypes
);
Map
<
String
,
MediaType
>
mapping
=
Collections
.
singletonMap
(
"HTML"
,
MediaType
.
APPLICATION_XHTML_XML
);
resolver
=
new
PathExtensionContentTypeResolver
(
mapping
);
mediaTypes
=
resolver
.
resolveMediaTypes
(
exchange
);
assertEquals
(
Collections
.
singletonList
(
new
MediaType
(
"application"
,
"xhtml+xml"
)),
mediaTypes
);
}
@Test
public
void
resolveMediaTypesFromJaf
()
throws
Exception
{
ServerWebExchange
exchange
=
createExchange
(
"test.xls"
);
PathExtensionContentTypeResolver
resolver
=
new
PathExtensionContentTypeResolver
();
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
(
exchange
);
assertEquals
(
Collections
.
singletonList
(
new
MediaType
(
"application"
,
"vnd.ms-excel"
)),
mediaTypes
);
}
// SPR-10334
@Test
public
void
getMediaTypeFromFilenameNoJaf
()
throws
Exception
{
ServerWebExchange
exchange
=
createExchange
(
"test.json"
);
PathExtensionContentTypeResolver
resolver
=
new
PathExtensionContentTypeResolver
();
resolver
.
setUseJaf
(
false
);
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
(
exchange
);
assertEquals
(
Collections
.<
MediaType
>
emptyList
(),
mediaTypes
);
}
// SPR-9390
@Test
public
void
getMediaTypeFilenameWithEncodedURI
()
throws
Exception
{
ServerWebExchange
exchange
=
createExchange
(
"/quo%20vadis%3f.html"
);
PathExtensionContentTypeResolver
resolver
=
new
PathExtensionContentTypeResolver
();
List
<
MediaType
>
result
=
resolver
.
resolveMediaTypes
(
exchange
);
assertEquals
(
"Invalid content type"
,
Collections
.
singletonList
(
new
MediaType
(
"text"
,
"html"
)),
result
);
}
// SPR-10170
@Test
public
void
resolveMediaTypesIgnoreUnknownExtension
()
throws
Exception
{
ServerWebExchange
exchange
=
createExchange
(
"test.xyz"
);
PathExtensionContentTypeResolver
resolver
=
new
PathExtensionContentTypeResolver
();
List
<
MediaType
>
mediaTypes
=
resolver
.
resolveMediaTypes
(
exchange
);
assertEquals
(
Collections
.<
MediaType
>
emptyList
(),
mediaTypes
);
}
@Test
(
expected
=
HttpMediaTypeNotAcceptableException
.
class
)
public
void
resolveMediaTypesDoNotIgnoreUnknownExtension
()
throws
Exception
{
ServerWebExchange
exchange
=
createExchange
(
"test.xyz"
);
PathExtensionContentTypeResolver
resolver
=
new
PathExtensionContentTypeResolver
();
resolver
.
setIgnoreUnknownExtensions
(
false
);
resolver
.
resolveMediaTypes
(
exchange
);
}
private
ServerWebExchange
createExchange
(
String
path
)
throws
URISyntaxException
{
ServerHttpRequest
request
=
new
MockServerHttpRequest
(
HttpMethod
.
GET
,
new
URI
(
path
));
WebSessionManager
sessionManager
=
mock
(
WebSessionManager
.
class
);
return
new
DefaultServerWebExchange
(
request
,
new
MockServerHttpResponse
(),
sessionManager
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录