Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
爱吃血肠
spring-framework
提交
1cd0a975
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,发现更多精彩内容 >>
提交
1cd0a975
编写于
1月 15, 2010
作者:
A
Arjen Poutsma
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
SPR-6467 - Allow ContentNegotiatingViewResolver to be strict ant return a 406 if no view found
上级
0cb9271b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
85 addition
and
4 deletion
+85
-4
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java
...work/web/servlet/view/ContentNegotiatingViewResolver.java
+30
-4
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java
...web/servlet/view/ContentNegotiatingViewResolverTests.java
+55
-0
未找到文件。
org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java
浏览文件 @
1cd0a975
...
@@ -31,6 +31,7 @@ import javax.activation.FileTypeMap;
...
@@ -31,6 +31,7 @@ import javax.activation.FileTypeMap;
import
javax.activation.MimetypesFileTypeMap
;
import
javax.activation.MimetypesFileTypeMap
;
import
javax.servlet.ServletContext
;
import
javax.servlet.ServletContext
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.beans.factory.BeanFactoryUtils
;
import
org.springframework.beans.factory.BeanFactoryUtils
;
import
org.springframework.core.OrderComparator
;
import
org.springframework.core.OrderComparator
;
...
@@ -114,6 +115,8 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -114,6 +115,8 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
private
boolean
favorParameter
=
false
;
private
boolean
favorParameter
=
false
;
private
String
parameterName
=
"format"
;
private
String
parameterName
=
"format"
;
private
boolean
useNotAcceptableStatusCode
=
false
;
private
boolean
ignoreAcceptHeader
=
false
;
private
boolean
ignoreAcceptHeader
=
false
;
...
@@ -125,7 +128,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -125,7 +128,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
private
List
<
ViewResolver
>
viewResolvers
;
private
List
<
ViewResolver
>
viewResolvers
;
public
void
setOrder
(
int
order
)
{
public
void
setOrder
(
int
order
)
{
this
.
order
=
order
;
this
.
order
=
order
;
}
}
...
@@ -174,6 +176,20 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -174,6 +176,20 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
this
.
ignoreAcceptHeader
=
ignoreAcceptHeader
;
this
.
ignoreAcceptHeader
=
ignoreAcceptHeader
;
}
}
/**
* Indicates whether a {@link HttpServletResponse#SC_NOT_ACCEPTABLE 406 Not Acceptable} status code should be
* returned if no suitable view can be found.
*
* <p>Default is {@code false}, meaning that this view resolver returns {@code null} for
* {@link #resolveViewName(String, Locale)} when an acceptable view cannot be found. This will allow for view
* resolvers chaining. When this property is set to {@code true},
* {@link #resolveViewName(String, Locale)} will respond with a view that sets the response status to
* {@code 406 Not Acceptable} instead.
*/
public
void
setUseNotAcceptableStatusCode
(
boolean
useNotAcceptableStatusCode
)
{
this
.
useNotAcceptableStatusCode
=
useNotAcceptableStatusCode
;
}
/**
/**
* Sets the mapping from file extensions to media types.
* Sets the mapping from file extensions to media types.
* <p>When this mapping is not set or when an extension is not present, this view resolver
* <p>When this mapping is not set or when an extension is not present, this view resolver
...
@@ -337,7 +353,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -337,7 +353,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
Collections
.
sort
(
requestedMediaTypes
);
Collections
.
sort
(
requestedMediaTypes
);
}
}
SortedMap
<
MediaType
,
View
>
views
=
new
TreeMap
<
MediaType
,
View
>();
List
<
View
>
candidateViews
=
new
ArrayList
<
View
>();
List
<
View
>
candidateViews
=
new
ArrayList
<
View
>();
for
(
ViewResolver
viewResolver
:
this
.
viewResolvers
)
{
for
(
ViewResolver
viewResolver
:
this
.
viewResolvers
)
{
View
view
=
viewResolver
.
resolveViewName
(
viewName
,
locale
);
View
view
=
viewResolver
.
resolveViewName
(
viewName
,
locale
);
...
@@ -349,6 +364,7 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -349,6 +364,7 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
candidateViews
.
addAll
(
this
.
defaultViews
);
candidateViews
.
addAll
(
this
.
defaultViews
);
}
}
SortedMap
<
MediaType
,
View
>
views
=
new
TreeMap
<
MediaType
,
View
>();
for
(
View
candidateView
:
candidateViews
)
{
for
(
View
candidateView
:
candidateViews
)
{
String
contentType
=
candidateView
.
getContentType
();
String
contentType
=
candidateView
.
getContentType
();
if
(
StringUtils
.
hasText
(
contentType
))
{
if
(
StringUtils
.
hasText
(
contentType
))
{
...
@@ -373,11 +389,10 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -373,11 +389,10 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
return
view
;
return
view
;
}
}
else
{
else
{
return
null
;
return
useNotAcceptableStatusCode
?
new
NotAcceptableView
()
:
null
;
}
}
}
}
/**
/**
* Inner class to avoid hard-coded JAF dependency.
* Inner class to avoid hard-coded JAF dependency.
*/
*/
...
@@ -421,4 +436,15 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
...
@@ -421,4 +436,15 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport
}
}
}
}
private
static
class
NotAcceptableView
implements
View
{
public
String
getContentType
()
{
return
null
;
}
public
void
render
(
Map
<
String
,
?>
model
,
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
Exception
{
response
.
setStatus
(
HttpServletResponse
.
SC_NOT_ACCEPTABLE
);
}
}
}
}
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java
浏览文件 @
1cd0a975
...
@@ -30,6 +30,7 @@ import org.junit.Test;
...
@@ -30,6 +30,7 @@ import org.junit.Test;
import
org.springframework.http.MediaType
;
import
org.springframework.http.MediaType
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.mock.web.MockHttpServletRequest
;
import
org.springframework.mock.web.MockHttpServletResponse
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
org.springframework.web.context.request.ServletRequestAttributes
;
import
org.springframework.web.servlet.View
;
import
org.springframework.web.servlet.View
;
...
@@ -305,4 +306,58 @@ public class ContentNegotiatingViewResolverTests {
...
@@ -305,4 +306,58 @@ public class ContentNegotiatingViewResolverTests {
verify
(
viewResolverMock
,
viewMock
);
verify
(
viewResolverMock
,
viewMock
);
}
}
@Test
public
void
resolveViewNoMatch
()
throws
Exception
{
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/test"
);
request
.
addHeader
(
"Accept"
,
"text/html,application/xhtml+xml,application/xml;q=0.9"
);
RequestContextHolder
.
setRequestAttributes
(
new
ServletRequestAttributes
(
request
));
ViewResolver
viewResolverMock
=
createMock
(
ViewResolver
.
class
);
viewResolver
.
setViewResolvers
(
Collections
.
singletonList
(
viewResolverMock
));
View
viewMock
=
createMock
(
"application_xml"
,
View
.
class
);
String
viewName
=
"view"
;
Locale
locale
=
Locale
.
ENGLISH
;
expect
(
viewResolverMock
.
resolveViewName
(
viewName
,
locale
)).
andReturn
(
viewMock
);
expect
(
viewMock
.
getContentType
()).
andReturn
(
"application/pdf"
);
replay
(
viewResolverMock
,
viewMock
);
View
result
=
viewResolver
.
resolveViewName
(
viewName
,
locale
);
assertNull
(
"Invalid view"
,
result
);
verify
(
viewResolverMock
,
viewMock
);
}
@Test
public
void
resolveViewNoMatchUseUnacceptableStatus
()
throws
Exception
{
viewResolver
.
setUseNotAcceptableStatusCode
(
true
);
MockHttpServletRequest
request
=
new
MockHttpServletRequest
(
"GET"
,
"/test"
);
request
.
addHeader
(
"Accept"
,
"text/html,application/xhtml+xml,application/xml;q=0.9"
);
RequestContextHolder
.
setRequestAttributes
(
new
ServletRequestAttributes
(
request
));
ViewResolver
viewResolverMock
=
createMock
(
ViewResolver
.
class
);
viewResolver
.
setViewResolvers
(
Collections
.
singletonList
(
viewResolverMock
));
View
viewMock
=
createMock
(
"application_xml"
,
View
.
class
);
String
viewName
=
"view"
;
Locale
locale
=
Locale
.
ENGLISH
;
expect
(
viewResolverMock
.
resolveViewName
(
viewName
,
locale
)).
andReturn
(
viewMock
);
expect
(
viewMock
.
getContentType
()).
andReturn
(
"application/pdf"
);
replay
(
viewResolverMock
,
viewMock
);
View
result
=
viewResolver
.
resolveViewName
(
viewName
,
locale
);
assertNotNull
(
"Invalid view"
,
result
);
MockHttpServletResponse
response
=
new
MockHttpServletResponse
();
result
.
render
(
null
,
request
,
response
);
assertEquals
(
"Invalid status code set"
,
406
,
response
.
getStatus
());
verify
(
viewResolverMock
,
viewMock
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录