Ist das ein Bug in Spring 3.1.2 (speziell Spring Portlet MVCs)?

Hintergrund: Ich entwickle ein Portlet mit Spring MVC Framework, das auf einem Liferay 5.x-Server bereitgestellt wird. Derzeit verwende ich 3.0.0.RELEASE. Alles funktioniert wie erwartet. Das heißt, wenn ich Anmerkungen wie @RenderMapping (params = "myaction = editFolderForm") @RenderMapping (params = "myaction = editEntryForm") @RenderMapping verwende
@ActionMapping (params = "myaction = editEntry") usw. DefaultAnnotationHandlerMapping funktioniert wie erwartet, um für jede Anforderung einen Handler zu finden.

Aber aus irgendeinem gültigen Grund muss ich eine aktuellere Version verwenden, nämlich 3.1.2.RELEASE anstelle von 3.0.0.RELEASE.

Ich habe festgestellt, dass DefaultAnnotationHandlerMapping beim Finden eines Handlers für jede Anforderung NICHT wie erwartet funktioniert. Ich fand heraus, was das Problem ist, indem ich die Interna des Spring-Frameworks debuggte. Ich möchte es klar erklären, damit mir jemand sagen kann, ob es sich um einen Bug handelt.

In der übergeordneten Klasse von 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;
}
....
....
}

Diese Sortierung ist in Spring 3.1.2 vermasselt und funktioniert in Spring 3.0.0 einwandfrei. In den nächsten beiden Abschnitten erkläre ich Ihnen, warum das Sortieren wichtig ist und wie es im Frühjahr 3.1.2 vermasselt wird.

Warum ist das Sortieren wichtig?

Diese HandlerMapping durchsucht eine sortierte verknüpfte Liste Knoten für Knoten, bis eine Übereinstimmung für einen bestimmten Handler gefunden wird. In meiner Codebasis habe ich mehrere Controller, deren Methoden mit folgenden Anmerkungen wie abgebildet sind

@RenderMapping ---> Standard

@RenderMapping (params = "myaction = editEntryController")

@RenderMapping (params = "myaction = editFolderController")

usw.

Das Collections.sort () hängt von der compareTo (..) -Methode jeder XXXPredicate-Klasse ab.

Wenn eine Anfrage zuerst kommt, sollte überprüft werden, ob der myaction-Parameter gleich "editEntryController", "editFolderController" ist. Wenn schließlich nichts übereinstimmt, sollte nur der Standardcontroller, der mit der @ RenderMapping-Annotation versehen ist, übereinstimmen.

Mit Spring 3.0.0 funktioniert es genauso wie erwartet. Wo wie in Spring 3.2.1, verhält es sich nicht so.

Bei beiden Versionen ist die Liste vor dem Sortieren identisch.

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

Nach dem Sortieren

Mit 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

Mit Spring 3.1.2 (ignoriere Dinge wie [])

[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

Dies ist eine verknüpfte Liste. Und jede Zuordnung wird vom ersten Knoten aus überprüft. Immer wenn die Standardeinstellung [], d. H. Eine leere Zuordnung, in der Mitte der Liste gefunden wird, wird true zurückgegeben, als ob dies der richtige Handler wäre, und der Rest der Handler wird nicht überprüft.

Ist dies also ein Fehler in Spring Framework 3.2.1?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage