Czy to błąd w Spring 3.1.2 (w szczególności Spring Portlet MVC)?

Tło: Zajmuję się tworzeniem portletu przy użyciu frameworka Spring MVC wdrożonego na serwerze liferay 5.x. Obecnie używam 3.0.0.RELEASE. Wszystko działa zgodnie z oczekiwaniami. To znaczy, gdy używam adnotacji takich jak @RenderMapping (params = "myaction = editFolderForm") @RenderMapping (params = "myaction = editEntryForm") @RenderMapping
@ActionMapping (params = "myaction = editEntry") itp. DefaultAnnotationHandlerMapping działa zgodnie z oczekiwaniami w poszukiwaniu programu obsługi dla każdego żądania.

Ale z jakiegoś ważnego powodu muszę użyć najnowszej wersji, którą jest 3.1.2.RELEASE zamiast 3.0.0.RELEASE.

Zauważyłem, że DefaultAnnotationHandlerMapping NIE DZIAŁA zgodnie z oczekiwaniami w znalezieniu programu obsługi dla każdego żądania. Zorientowałem się, jaki jest problem, debugując wewnętrzne elementy Spring. Chcę to wyjaśnić, żeby ktoś mógł mi powiedzieć, czy to Bug.

W klasie nadrzędnej DefaultAnnotationHandlerMapping, która jest 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;
}
....
....
}

To sortowanie jest spieprzone w Spring 3.1.2 i działa doskonale w Spring 3.0.0. W następnych dwóch sekcjach powiem ci, dlaczego sortowanie ma znaczenie i jak jest spieprzone wiosną 3.1.2.

dlaczego sortowanie ma znaczenie?

To HandlerMapping wyszukuje posortowany węzeł połączonej listy według węzła, aż znajdzie dopasowanie dla określonego modułu obsługi. W mojej bazie kodu mam wiele kontrolerów, których metody są mapowane za pomocą następujących adnotacji, takich jak

@RenderMapping ---> default

@RenderMapping (params = "myaction = editEntryController")

@RenderMapping (params = "myaction = editFolderController")

itp.

Collections.sort () zależy od metody compareTo (..) każdej klasy XXXPredicate.

gdy najpierw przychodzi żądanie, należy sprawdzić, czy parametr myaction jest równy „editEntryController”, „editFolderController”, ... i na koniec, jeśli nic nie pasuje, thn należy dopasować tylko domyślny kontroler z adnotacją @RenderMapping.

Dzięki Spring 3.0.0 działa dokładnie tak, jak oczekiwano. Gdzie jako Wiosna 3.2.1 nie zachowuje się w ten sposób.

W obu wersjach lista przed sortowaniem jest taka sama.

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

Po sortowaniu

Z 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

W Spring 3.1.2 (ignoruj ​​rzeczy takie jak []),

[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

To jest lista połączona. Każde mapowanie jest sprawdzane z pierwszego węzła. Kiedykolwiek domyślne [] tj. Puste mapowanie znajduje się w środku listy, zwracana jest prawda, tak jakby to był prawy program obsługi, a reszta procedur obsługi nie jest sprawdzana.

Czy jest to błąd w Spring Framework 3.2.1?

questionAnswers(1)

yourAnswerToTheQuestion