【问题标题】:No adapter for handler ... The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler处理程序没有适配器... DispatcherServlet 配置需要包含支持此处理程序的 HandlerAdapter
【发布时间】:2017-03-15 23:28:02
【问题描述】:

厌倦了在 Spring 配置中使用 XML 文件,尝试转而采用完整的 Java 方法,但毫无疑问我失败了。

仅涉及 2 个类:

@Configuration
public class AppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        WebApplicationContext context = getContext();
        servletContext.addListener(new ContextLoaderListener(context));
        DispatcherServlet dispatcherServlet = new DispatcherServlet(context);
        dispatcherServlet.setDetectAllHandlerAdapters(true);
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dispatcherServlet);
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    private AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("cl.waypoint.ecobox");
        return context;
    }

    @Bean
    public RequestMappingHandlerAdapter annotationMethodHandlerAdapter() {
        final RequestMappingHandlerAdapter annotationMethodHandlerAdapter = new RequestMappingHandlerAdapter();
        List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<>();
        httpMessageConverters.add(new MappingJackson2HttpMessageConverter());
        annotationMethodHandlerAdapter.setMessageConverters(httpMessageConverters);
        return annotationMethodHandlerAdapter;
    }
}

和控制器:

@Controller
public class Loader {

    private static final Logger LOGGER = Logger.getLogger("Loader");

    @RequestMapping("/routeLoader")
    public LoaderResult load(@RequestBody byte[] data) {
        LOGGER.info("new Route!");
        return new LoaderResult();
    }

}

当使用 cUrl 将一些 JSON 数据 POST 到端点时,会出现一个“美丽的”红色波浪 (Stacktrace):

javax.servlet.ServletException: No adapter for handler [cl.waypoint.ecobox.Loader@2c4d0325]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
    at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1173)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:722)

Tomcat的启动日志:

Información: Initializing Spring root WebApplicationContext
nov 02, 2016 12:40:57 PM org.springframework.web.context.ContextLoader initWebApplicationContext
Información: Root WebApplicationContext: initialization started
nov 02, 2016 12:40:57 PM org.springframework.web.context.support.AnnotationConfigWebApplicationContext prepareRefresh
Información: Refreshing Root WebApplicationContext: startup date [Wed Nov 02 12:40:57 ART 2016]; root of context hierarchy
nov 02, 2016 12:40:57 PM org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
Información: Found 2 annotated classes in package [cl.waypoint.ecobox]
nov 02, 2016 12:40:58 PM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
Información: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Wed Nov 02 12:40:57 ART 2016]; root of context hierarchy
nov 02, 2016 12:40:59 PM org.springframework.web.context.ContextLoader initWebApplicationContext
Información: Root WebApplicationContext: initialization completed in 1469 ms
nov 02, 2016 12:40:59 PM org.apache.catalina.core.ApplicationContext log
Información: Initializing Spring FrameworkServlet 'DispatcherServlet'
nov 02, 2016 12:40:59 PM org.springframework.web.servlet.DispatcherServlet initServletBean
Información: FrameworkServlet 'DispatcherServlet': initialization started
nov 02, 2016 12:40:59 PM org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping registerHandler
Información: Mapped URL path [/routeLoader] onto handler 'loader'
nov 02, 2016 12:40:59 PM org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping registerHandler
Información: Mapped URL path [/routeLoader.*] onto handler 'loader'
nov 02, 2016 12:40:59 PM org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping registerHandler
Información: Mapped URL path [/routeLoader/] onto handler 'loader'
nov 02, 2016 12:40:59 PM org.springframework.web.servlet.DispatcherServlet initServletBean
Información: FrameworkServlet 'DispatcherServlet': initialization completed in 152 ms

相关的 Maven 依赖项:

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.4</version>
        </dependency>
    </dependencies>

测试调用者:

curl --request POST -H "Content-Type: application/json" -d '{  "NroViaje": 1,  "CodDestino": "678",  "DescDestino": "VILLA ALEMANA",  "PatenteCamion": "AA1111",  "PatenteTrailer": "BB2222",  "FechaEntrega": "2016-10-31"}' http://localhost:8080/ecobox-load-route/routeLoader

Sample sources and pom file

可能缺少什么?

PS:在 Stackoverflow 社区中发现了至少 4 个类似的问题,但不幸的是,它们都没有帮助:(

【问题讨论】:

  • 为什么要使用相同的上下文创建 ContextLoaderListenerDispatcherServlet
  • 什么是cl.waypoint.ecobox,它包含什么?
  • @SotiriosDelimanolis cl.waypoint.ecobox 是以上2个类的包名
  • @SotiriosDelimanolis 也许我不需要 ContextLoaderListener 和 DispatcherServlet。我实际上只需要 servlet,但配置了侦听器,以便 Spring 可以自动发现 Dispatcher。
  • 我无法重现您所看到的行为。但是在将其传递给DispatcherServlet 之前,请摆脱您的ContextLoaderListener 和可能的refresh 您的ApplicationContext。阅读 DispatcherServlet 的 javadoc 以了解如果不这样做会发生什么。

标签: java json spring tomcat spring-web


【解决方案1】:

试试,

@RequestMapping("/routeLoader")
public @ResponseBody LoaderResult load(@RequestBody byte[] data) {..}

(由于您要返回 LoaderResult 对象,您可能必须将其标记为响应正文)

【讨论】:

    猜你喜欢
    • 2021-07-27
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 2021-08-11
    相关资源
    最近更新 更多