배경 : liferay 5.x 서버에 배포 된 Spring MVC 프레임 워크를 사용하여 포틀릿을 개발 중입니다. 현재 3.0.0.RELEASE를 사용 중입니다. 예상대로 모든 것이 잘 작동합니다. 제가 @RenderMapping (PARAMS = "= editFolderForm 시켜라") @RenderMapping (PARAMS = "= editEntryForm 시켜라") @RenderMapping
@ActionMapping (PARAMS = "= editEntry 시켜라") 같은 특수 효과를 사용할 때, DefaultAnnotationHandlerMapping은 모든 요청에 대해 처리기를 찾는 데 예상대로 작동합니다.이것은 Spring 3.1.2의 버그 (특히 Spring 포틀릿 MVC)입니까?
그러나 몇 가지 유효한 이유 때문에 최신 버전 인 3.1.2.RELEASE 대신 3.0.0.RELEASE를 사용해야합니다.
모든 요청에 대해 처리기를 찾는 데 DefaultAnnotationHandlerMapping이 예상대로 작동하지 않는다는 것이 관찰되었습니다. 스프링 프레임 워크의 내부를 디버깅하여 문제가 무엇인지 알아 냈습니다. 누군가가 이것이 버그인지 말해 줄 수 있도록 명확하게 설명하고 싶습니다.
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;
}
....
....
}
이 분류는 봄 3.1.2에 망쳐하고 봄 3.0.0에서 완벽하게 잘 작동 : AbstractMapBasedHandlerMapping되는 DefaultAnnotationHandlerMapping의 부모 클래스에서
. 다음 두 섹션에서는 왜 문제를 정렬하고 어떻게 Spring 3.1.2에서 엉망이되는지 설명 할 것입니다.
왜 분류가 중요합니까?
이 모든 HandlerMapping은 특정 핸들러 일치를 발견 때까지 노드에 의해 정렬 된 연결리스트 노드를 검색합니다. 내 코드베이스에서, 나는 그 방법
처럼, 다음의 주석과 함께 맵핑되는 다중 컨트롤러가 @RenderMapping ---> 기본
@RenderMapping (PARAMS = "시켜라 = editEntryController")
@RenderMapping (PARAMS = "= editFolderController 시켜라")
등
은, Collections.sort는()은 compareTo (..) XXXPredicate 각 클래스의 방법에 의존한다.
myaction 매개 변수가 "editEntryController", "editFolderController"...와 같은지 확인해야합니다. 마지막으로 아무것도 일치하지 않으면 @RenderMapping 주석으로 주석 된 기본 컨트롤러 만 일치해야합니다 .
스프링 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
, 봄 3.0
.0 스프링 3.1.2 ([] 등을 무시하고)을
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
는
[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가 반환됩니다.
스프링 프레임 워크 3.2.1의 버그입니까?