这是Spring 3.1.2中的一个Bug(特别是Spring Portlet MVC)吗?
作者:互联网
背景:
我正在使用部署在liferay 5.x服务器中的Spring MVC框架开发一个Portlet.
目前我正在使用3.0.0.RELEASE.一切都按预期正常工作.
也就是说,当我使用注释时
@RenderMapping(PARAMS = “myaction = editFolderForm”)
@RenderMapping(PARAMS = “myaction = editEntryForm”)
@RenderMapping
@ActionMapping(PARAMS = “myaction = editEntry”)
等等
DefaultAnnotationHandlerMapping在为每个请求查找处理程序时按预期工作.
但是,出于某些正当理由,我必须使用更新的版本3.1.2.RELEASE而不是3.0.0.RELEASE.
我发现DefaultAnnotationHandlerMapping在为每个请求查找处理程序时都没有按预期工作.我通过调试Spring框架的内部结构找出了问题所在.
我想清楚地解释一下,这样有人可以告诉我这是不是一个Bug.
在DefaultAnnotationHandlerMapping的父类中,它是AbstractMapBasedHandlerMapping:
package org.springframework.web.portlet.handler;
public abstract class AbstractMapBasedHandlerMapping<K> extends AbstractHandlerMapping {
....
....
/**
* Determines a handler for the computed lookup key for the given request.
* @see #getLookupKey
*/
@Override
@SuppressWarnings("unchecked")
protected Object getHandlerInternal(PortletRequest request) throws Exception {
...
if (handler instanceof Map) {
Map<PortletRequestMappingPredicate, Object> predicateMap =
(Map<PortletRequestMappingPredicate, Object>) handler;
List<PortletRequestMappingPredicate> predicates =
new LinkedList<PortletRequestMappingPredicate>(predicateMap.keySet());
LINE 81: Collections.sort(predicates); ///////////////// PROBLEM
for (PortletRequestMappingPredicate predicate : predicates) {
if (predicate.match(request)) {
predicate.validate(request);
return predicateMap.get(predicate);
}
}
return null;
}
return handler;
}
....
....
}
这种排序在Spring 3.1.2中搞砸了,在Spring 3.0.0中运行得非常好.
在接下来的两节中,我将告诉您为什么排序很重要以及它如何在Spring 3.1.2中搞砸了.
why sorting matters ?
此HandlerMapping逐节点地搜索已排序的链表,直到找到特定处理程序的匹配项.在我的代码库中,我有多个控制器,其方法映射有以下注释,如
@RenderMapping —>默认
@RenderMapping(PARAMS = “myaction = editEntryController”)
@RenderMapping(PARAMS = “myaction = editFolderController”)
等等
Collections.sort()依赖于每个XXXPredicate类的compareTo(..)方法.
当一个请求出现时,应该检查myaction参数是否等于“editEntryController”,“editFolderController”,…最后如果没有匹配,那么只应该匹配使用@RenderMapping注释注释的默认控制器.
使用Spring 3.0.0,它的工作方式与预期完全一致.
和Spring 3.2.1一样,它的表现不像那样.
对于这两个版本,在排序之前,列表是相同的.
myaction=editEntry,
myaction=editEntryForm,
org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping$ResourceMappingPredicate@123bea8a,
myaction=REDIRECT_TO_DEFAULT_PAGE,
, ---------------------------------> This empty string corrsponds to the default @RenderMapping
myaction=selectFolderEntries,
myaction=searchResults,
myaction=addEntry,
myaction=addEntryForm,
myaction=showMyEntries,
myaction=showRecentEntries,
org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping$ResourceMappingPredicate@4f1e9e2d,
myaction=editFolder,
myaction=editFolderForm,
myaction=addFolder,
myaction=addFolderForm
排序后,
随着Spring 3.0.0,
org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping$ResourceMappingPredicate@123bea8a,
org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping$ResourceMappingPredicate@4f1e9e2d,
myaction=editEntry,
myaction=editEntryForm,
myaction=REDIRECT_TO_DEFAULT_PAGE,
myaction=selectFolderEntries,
myaction=searchResults,
myaction=addEntry,
myaction=addEntryForm,
myaction=showMyEntries,
myaction=showRecentEntries,
myaction=editFolder,
myaction=editFolderForm,
myaction=addFolder,
myaction=addFolderForm,
---------------> Default mapping i.e. @RenderMapping
使用Spring 3.1.2(忽略像[]这样的东西),
[myaction=editEntry]
[myaction=editEntryForm]
deleteFolder
[myaction=REDIRECT_TO_DEFAULT_PAGE]
[] --------------------------> this is wrongly placed in middle.
[myaction=selectFolderEntries]
[myaction=searchResults]
[myaction=addEntry]
[myaction=addEntryForm]
[myaction=showMyEntries]
[myaction=showRecentEntries]
deleteEntry
[myaction=editFolder]
[myaction=editFolderForm]
[myaction=addFolder]
[myaction=addFolderForm]
null
这是一个链表.并且从第一个节点检查每个映射.
如果在列表中间找到默认的[],即空映射,则返回true,就好像这是正确的处理程序,并且未检查其余的处理程序.
这是Spring framework 3.2.1中的一个错误吗?
解决方法:
我有同样的问题.只有3.1.4版本适用于我.
标签:portlet,spring,spring-mvc,spring-3 来源: https://codeday.me/bug/20191002/1841513.html