2012-08-16 70 views
1

背景: 我正在使用部署在liferay 5.x服务器中的Spring MVC框架开发Portlet。 目前我正在使用3.0.0.RELEASE。一切工作正常,如预期。 也就是说,当我使用注释等 @RenderMapping(PARAMS = “myaction = editFolderForm”) @RenderMapping(PARAMS = “myaction = editEntryForm”) @RenderMapping
@ActionMapping(PARAMS = “myaction = editEntry”) DefaultAnnotationHandlerMapping按照预期为每个请求查找处理程序。这是Spring 3.1.2(特别是Spring Portlet MVC)中的一个Bug吗?

但是,出于某种正当理由,我必须使用更多的最新版本,它是3.1.2.RELEASE而不是3.0.0.RELEASE。

我发现DefaultAnnotationHandlerMapping不像预期的那样为每个请求找到一个处理程序。我通过调试Spring框架的内部知道了什么是问题。 我想解释清楚,以便有人可以告诉我,如果这是一个错误。

在父类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中搞砸。

为什么排序很重要?

此HandlerMapping按节点搜索排序后的链接列表,直到它找到与特定处理程序匹配为止。在我的代码的基础上,我有多个控制器,它的方法被映射与以下注释等

@RenderMapping --->默认

@RenderMapping(PARAMS = “myaction = editEntryController”)

@RenderMapping( PARAMS = “myaction = editFolderController”)

的Collections.sort()取决于的compareTo(..)每个XXXPredicate类的方法。

当一个请求到达时,应该检查myaction参数是否等于“editEntryController”,“editFolderController”,以及最后如果没有任何匹配,那么只有使用@RenderMapping注释注释的默认控制器应该匹配。

使用Spring 3.0.0,其工作方式与预期完全相同。 因为Spring 3.2.1,它的行为不像那样。

对于这两个版本,在排序之前,列表是相同的。

myaction=editEntry, 
myaction=editEntryForm, 
org.springframework.web.portlet.mvc.anno[email protected]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.anno[email protected]4f1e9e2d, 
myaction=editFolder, 
myaction=editFolderForm, 
myaction=addFolder, 
myaction=addFolderForm 

排序后,

使用Spring 3.0。0,

org.springframework.web.portlet.mvc.anno[email protected]123bea8a, 
org.springframework.web.portlet.mvc.anno[email protected]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框架3.2.1中的一个bug吗?

回答

1

我有同样的问题。只有版本3.1.4为我工作。