¿Es esto un error en Spring 3.1.2(específicamente Spring Portlet MVC)?
spring-mvc spring-3 (1)
Yo tuve el mismo problema. Solo la versión 3.1.4 me estaba funcionando.
Antecedentes: estoy desarrollando un portlet utilizando el marco Spring MVC implementado en el servidor Liferay 5.x. Actualmente estoy usando 3.0.0.RELEASE. Todo está funcionando bien como se esperaba. Es decir, cuando uso anotaciones como @RenderMapping (params = "myaction = editFolderForm") @RenderMapping (params = "myaction = editEntryForm") @RenderMapping
@ActionMapping (params = "myaction = editEntry") etc. DefaultAnnotationHandlerMapping está funcionando como se esperaba para encontrar un controlador para cada solicitud.
Pero, por alguna razón válida, tengo que usar más versión más reciente que es 3.1.2.RELEASE en lugar de 3.0.0.RELEASE.
Observé que DefaultAnnotationHandlerMapping NO FUNCIONA como se esperaba al buscar un controlador para cada solicitud. Descubrí cuál es el problema depurando las partes internas del framework Spring. Quiero explicarlo claramente para que alguien me pueda decir si esto es un error.
En la clase padre de DefaultAnnotationHandlerMapping que es 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;
}
....
....
}
Esta clasificación está arruinada en Spring 3.1.2 y funciona perfectamente en Spring 3.0.0. En las próximas dos secciones, le diré por qué importa la clasificación y cómo se estropea en la primavera 3.1.2.
por qué clasificar importa?
Este HandlerMapping busca un nodo de lista clasificada por nodo hasta que encuentre la coincidencia para un controlador en particular. En mi base de código, tengo múltiples controladores cuyos métodos están mapeados con las siguientes anotaciones como
@RenderMapping ---> predeterminado
@RenderMapping (params = "myaction = editEntryController")
@RenderMapping (params = "myaction = editFolderController")
etc.
Collections.sort () depende del método compareTo (..) de cada clase de XXXPredicate.
cuando una solicitud viene primero debe verificarse si el parámetro myaction es igual a "editEntryController", "editFolderController", ... y finalmente, si nada coincide, el único controlador predeterminado anotado con la anotación @RenderMapping debe coincidir.
Con Spring 3.0.0, funciona exactamente como se esperaba. Mientras que con el resorte 3.2.1, no se está comportando así.
Con ambas versiones, antes de ordenar, la lista es la misma.
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
Después de ordenar,
Con 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
Con Spring 3.1.2 (ignore cosas como []),
[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
Esta es una lista enlazada. Y cada mapeo se verifica desde el primer nodo. Cuando el valor predeterminado [], es decir, un mapeo vacío se encuentra en el medio de la lista, se devuelve verdadero como si fuera el controlador derecho y el resto de los controladores no están marcados.
Entonces, ¿esto es un error en Spring framework 3.2.1?