其他分享
首页 > 其他分享> > 这是Spring 3.1.2中的一个Bug(特别是Spring Portlet MVC)吗?

这是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