我收到了主题错误消息,但我无法弄清楚原因。我有一套相当复杂的控制器。主题控制器如下:
package ws.daley.hollow.web.controller.admin;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import ws.daley.hollow.persistence.admin.model.Node;
import ws.daley.hollow.persistence.admin.model.PiProcessor;
import ws.daley.hollow.service.admin.intf.INodeService;
import ws.daley.hollow.service.admin.intf.IPiProcessorService;
import ws.daley.hollow.web.controller.CustomErrorController;
import ws.daley.hollow.web.controller.admin.abstractcontroller.AdminSerialSubController;
import ws.daley.hollow.web.controller.admin.abstractcontroller.ElementParameter;
import ws.daley.hollow.web.controller.admin.abstractcontroller.MyModelAndView;
@Controller
public class AdminPiProcessorController extends AdminSerialSubController<PiProcessor>
{
private static final String ENTITY_NAME = "piprocessor";
private static final String[] MEMBER_FIELD_NAMES = new String[] {"node"};
@SuppressWarnings("hiding")
@Autowired
CustomErrorController customErrorController;
@SuppressWarnings("hiding")
@Autowired
private IPiProcessorService service;
@Autowired
private INodeService memberService;
@Autowired
private MessageSource messages;
public AdminPiProcessorController() {super(PiProcessor.class);}
@PostConstruct
@Override
public void postConstruct() {super.postInit(getClass(), this.service, this.customErrorController, this.messages);}
private ElementParameter[] getElementParameters()
{
return new ElementParameter[] {new ElementParameter(Node.class, "node", false, this.memberService)};
}
@ExceptionHandler({ Throwable.class})
@Override
public ModelAndView throwable(HttpServletRequest request, Throwable throwable) {return super.throwable(request, throwable);}
@Override
public String[] getMemberFieldNames() {return MEMBER_FIELD_NAMES;}
@GetMapping(value = STUB, params = ENTITY_NAME)
@Override
public MyModelAndView adminEditEntityList(Model model, Locale locale) {return super.adminEditEntityList(model, locale);}
@GetMapping(value = STUB, params = { ENTITY_NAME, EDIT })
public MyModelAndView adminWithEntityId(@RequestParam("name") String name, Model model, Locale locale) {return super.adminWithEntityId(model, locale, name, getElementParameters());}
@GetMapping(value = STUB, params = { ENTITY_NAME, NEW })
public MyModelAndView adminWithEntityNew(Model model, Locale locale) {return super.adminWithEntityNew(model, locale, getElementParameters());}
@PostMapping(value = STUB, params = { ENTITY_NAME, SUBMIT })
public MyModelAndView adminWithEntitySave(@ModelAttribute(ENTITY_NAME) PiProcessor entity, @RequestParam("action") String action, Model model, Locale locale)
{
return super.adminWithEntitySubmit(model, locale, action, entity);
}
}
和
package ws.daley.hollow.web.controller.admin;
import java.util.Collection;
import java.util.Locale;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import ws.daley.hollow.persistence.admin.model.Node;
import ws.daley.hollow.persistence.admin.model.NodeFunction;
import ws.daley.hollow.persistence.admin.model.PiProcessor;
import ws.daley.hollow.service.admin.intf.INodeFunctionService;
import ws.daley.hollow.service.admin.intf.INodeService;
import ws.daley.hollow.service.admin.intf.IPiProcessorService;
import ws.daley.hollow.web.controller.CustomErrorController;
import ws.daley.hollow.web.controller.admin.abstractcontroller.AdminNameSubController;
import ws.daley.hollow.web.controller.admin.abstractcontroller.ElementParameter;
import ws.daley.hollow.web.controller.admin.abstractcontroller.MyModelAndView;
@Controller
public class AdminNodeController extends AdminNameSubController<Node>
{
private static final String ENTITY_NAME = "node";
private static final String[] MEMBER_FIELD_NAMES = new String[] { "nodeFunction" };
@SuppressWarnings("hiding")
@Autowired
CustomErrorController customErrorController;
@SuppressWarnings("hiding")
@Autowired
private INodeService service;
@Autowired
private IPiProcessorService piProcessorService;
@Autowired
private INodeFunctionService memberService;
@Autowired
private MessageSource messages;
public AdminNodeController() {super(Node.class);}
@PostConstruct
@Override
public void postConstruct() {super.postInit(getClass(), this.service, this.customErrorController, this.messages);}
private ElementParameter[] getElementParameters()
{
return new ElementParameter[] {new ElementParameter(NodeFunction.class, "nodeFunction", false, this.memberService)};
}
@ExceptionHandler({ Throwable.class})
@Override
public ModelAndView throwable(HttpServletRequest request, Throwable throwable) {return super.throwable(request, throwable);}
@Override
public String[] getMemberFieldNames() {return MEMBER_FIELD_NAMES;}
@GetMapping(value = STUB, params = ENTITY_NAME)
@Override
public MyModelAndView adminEditEntityList(Model model, Locale locale) {return super.adminEditEntityList(model, locale);}
@GetMapping(value = STUB, params = { ENTITY_NAME, EDIT })
public MyModelAndView adminWithEntityId(@RequestParam("name") String name, Model model, Locale locale) {return super.adminWithEntityId(model, locale, name, getElementParameters());}
@GetMapping(value = STUB, params = { ENTITY_NAME, NEW })
public MyModelAndView adminWithEntityNew(Model model, Locale locale) {return super.adminWithEntityNew(model, locale, getElementParameters());}
@PostMapping(value = STUB, params = { ENTITY_NAME, SUBMIT })
public MyModelAndView adminWithEntitySave(@ModelAttribute(ENTITY_NAME) Node entity, @RequestParam("action") String action, Model model, Locale locale)
{
if ("Delete".equals(action))
{
Collection<PiProcessor> piProcessors = this.piProcessorService.queryByNode(entity.getName());
if (piProcessors != null && piProcessors.size() > 0)
{
String names = piProcessors.stream().map(r -> r.getName()).collect(Collectors.joining(", "));
MyModelAndView mav = super.adminWithEntityId(model, locale, entity.getName());
mav.addObject("error", "Cannot delete node function. It is used in the following PiProcessor(s): "+names);
return mav;
}
}
return super.adminWithEntitySubmit(model, locale, action, entity);
}
}
参数是:
STUB=/server-admin
EDIT=edit
NEW=new
SUBMIT=submit
我还制作了AbstractHandler的副本,并将它放在我自己的源代码树中的org.springframework.web.servlet.handler包中。我添加了以下更改:
加
private static Logger logger = LoggerFactory.getLogger(AbstractHandlerMethodMapping.class);
已添加
logger.warn("Url :"+request.getContentType().toString());
logger.warn("Request: "+request.toString());
logger.warn("Context Path: "+request.getContextPath().toString());
logger.warn("Method: "+request.getMethod().toString());
logger.warn("Query string: "+request.getQueryString().toString());
logger.warn("Scheme: "+request.getScheme().toString());
Enumeration<String> e = request.getParameterNames();
while(e.hasMoreElements())
{
String parameterName = e.nextElement();
String parameter = request.getParameter(parameterName).toString();
logger.warn("Parameter: "+parameterName+"->"+parameter);
}
logger.warn("matches:");
for(Match match:matches)
logger.warn("\t"+match.toString());
logger.warn("bestMatch: "+bestMatch.toString());
logger.warn("secondBestMatch: "+secondBestMatch.toString());
在声明之前:
throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +
request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");
输出结果为:
webadmin - 2018-02-20 21:13:32,170 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Url :application/x-www-form-urlencoded
webadmin - 2018-02-20 21:13:32,170 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Request: SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.context.HttpSessionSecurityContextRepository$Servlet3SaveToSessionRequestWrapper@21a71563]
webadmin - 2018-02-20 21:13:32,170 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Context Path:
webadmin - 2018-02-20 21:13:32,171 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Method: POST
webadmin - 2018-02-20 21:13:32,171 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Query string: lang=en_US&piprocessor&submit
webadmin - 2018-02-20 21:13:32,171 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Scheme: http
webadmin - 2018-02-20 21:13:32,171 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: lang->en_US
webadmin - 2018-02-20 21:13:32,172 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: piprocessor->
webadmin - 2018-02-20 21:13:32,172 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: submit->
webadmin - 2018-02-20 21:13:32,172 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: id->16
webadmin - 2018-02-20 21:13:32,172 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: name->000000009ec1f24d
webadmin - 2018-02-20 21:13:32,173 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: node->18
webadmin - 2018-02-20 21:13:32,173 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - Parameter: action->Submit
webadmin - 2018-02-20 21:13:32,173 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - matches:
webadmin - 2018-02-20 21:13:32,173 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - {[/server-admin],methods=[POST],params=[node && submit]}
webadmin - 2018-02-20 21:13:32,174 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - {[/server-admin],methods=[POST],params=[piprocessor && submit]}
webadmin - 2018-02-20 21:13:32,174 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - bestMatch: {[/server-admin],methods=[POST],params=[node && submit]}
webadmin - 2018-02-20 21:13:32,174 [http-nio-8081-exec-9] WARN org.springframework.web.servlet.handler.AbstractHandlerMethodMapping - secondBestMatch: {[/server-admin],methods=[POST],params=[piprocessor && submit]}
webadmin - 2018-02-20 21:13:46,821 [http-nio-8081-exec-9] DEBUG ws.daley.hollow.web.error.RestResponseEntityExceptionHandler - ws.daley.hollow.web.error.RestResponseEntityExceptionHandler::handleInternal(ex={java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8081/server-admin': {public ws.daley.hollow.web.controller.admin.abstractcontroller.MyModelAndView ws.daley.hollow.web.controller.admin.AdminNodeController.adminWithEntitySave(ws.daley.hollow.persistence.admin.model.Node,java.lang.String,org.springframework.ui.Model,java.util.Locale), public ws.daley.hollow.web.controller.admin.abstractcontroller.MyModelAndView ws.daley.hollow.web.controller.admin.AdminPiProcessorController.adminWithEntitySave(ws.daley.hollow.persistence.admin.model.PiProcessor,java.lang.String,org.springframework.ui.Model,java.util.Locale)}}, request={ServletWebRequest: uri=/server-admin;client=0:0:0:0:0:0:0:1;session=110061C48999447505CF1AA326575B98;user=test}
webadmin - 2018-02-20 21:13:46,824 [http-nio-8081-exec-9] ERROR ws.daley.hollow.web.error.RestResponseEntityExceptionHandler - 500 Status Code
java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8081/server-admin': {public ws.daley.hollow.web.controller.admin.abstractcontroller.MyModelAndView ws.daley.hollow.web.controller.admin.AdminNodeController.adminWithEntitySave(ws.daley.hollow.persistence.admin.model.Node,java.lang.String,org.springframework.ui.Model,java.util.Locale), public ws.daley.hollow.web.controller.admin.abstractcontroller.MyModelAndView ws.daley.hollow.web.controller.admin.AdminPiProcessorController.adminWithEntitySave(ws.daley.hollow.persistence.admin.model.PiProcessor,java.lang.String,org.springframework.ui.Model,java.util.Locale)}
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:394)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:323)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:1)
at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:351)
at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1188)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:964)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
我忘了提到我使用的是spring-boot 1.5.10.RELEASE并已移至2.0.0.RC1并且都有这个问题。
此外,在另外十几个模块中,我有完全相同的结构。 AdminPiProcessorController是唯一表现出此行为的模块。模型,存储库,服务和控制器被大量抽象,以允许这种类型的代码。不幸的是,这使得构建一个简单的测试用例变得非常困难。
答案 0 :(得分:0)
您在两个控制器中具有相同的映射
AdminPiProcessorController
AdminNodeController
因为映射对于应用程序是全局的,所以不能对两个不同的控制器使用相同的uri。
我希望它会对你有所帮助。
控制器类AdminPiProcessorController:
@GetMapping(value = STUB, params = ENTITY_NAME)
@Override
public MyModelAndView adminEditEntityList(Model model, Locale locale) {return super.adminEditEntityList(model, locale);}
与AdminNodeController中的映射相同
@GetMapping(value = STUB, params = ENTITY_NAME)
@Override
public MyModelAndView adminEditEntityList(Model model, Locale locale) {return super.adminEditEntityList(model, locale);}
请检查其他方法。
答案 1 :(得分:0)
虽然技术上不是一个答案,但问题本身就已经消失了。我认为类似的问题在......之前采取了相同的行动。