zoukankan      html  css  js  c++  java
  • SpringMVC处理跨域请求时的一个注意事项

        由于公司对SpingMVC框架里面的东西进行了扩展,在配置SpringMVC时没有使用<mvc:annotation-driven>这个标签。而且是自己手动来配置HandlerMappingHandlerAdapter。在处理跨域请求时,就抛No adapter for handler 异常了。记录下该异常的解决过程,方便后续查询。

    一、异常信息

        具体的异常信息如下:
    threw exception [No adapter for handler [org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler@edcb4b4]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler] with root cause
    javax.servlet.ServletException: No adapter for handler [org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler@edcb4b4]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
    	at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1202)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:947)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    	at org.springframework.web.servlet.FrameworkServlet.doOptions(FrameworkServlet.java:908)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:657)
    	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    x
     
    1
    threw exception [No adapter for handler [org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler@edcb4b4]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler] with root cause
    2
    javax.servlet.ServletException: No adapter for handler [org.springframework.web.servlet.handler.AbstractHandlerMapping$PreFlightHandler@edcb4b4]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler
    3
        at org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter(DispatcherServlet.java:1202)
    4
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:947)
    5
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    6
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    7
        at org.springframework.web.servlet.FrameworkServlet.doOptions(FrameworkServlet.java:908)
    8
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:657)
    9
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    10
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

    二、问题的解决

    (1)异常的分析
        分析上面的异常信息,发现是在doOptions没找到合适的HandlerAdapter。跨域请求时是会发送2个请求的,第一个是就是options类型的请求。所以这里的问题就是在处理options请求时。
        再看了下代码中配置的HandlerAdapter,配置代码如下图
        注册的HandlerAdapter实例为 RequestMappingHandlerAdapter于是我怀疑是这个RequestMappingHandlerAdapter不支持options类型的请求。
    (2)验证自己的想法
        带着怀疑的想法,把xml配置中手动配置的HandlerAdapter给去掉了,然后加上<mvc:annotation-driven>这个标签。再运行项目,发现跨域请求居然可以处理了。说明确实是有handlerAdapter没有配置上去。
        debug了DispatcherServlet下里面的代码,发现处理options请求时需要的handlerAdapter是HttpRequestHandlerAdapter的实例。因此问题的根源就是我们的SpringMVC的配置中没有配置HttpRequestHandlerAdapter,导致没有找到支持options类型请求的handlerAdapter。
    (3)解决问题
        由于框架的问题,不适合直接使用<mvc:annotation-driven>这个标签(用了会导致扩展的功能失效)。分析了<mvc:annotation-driven>这个标签可知它会实例化3个HandlerAdapter,而我的配置文件只实例化了一个RequestMappingHandlerAdapter。因此我把另外两个handlerAdapter的实例也添加到配置文件中了。另外2个handlerAdapter的其中之一就是HttpRequestHandlerAdapter,这个handlerAdapter就可以处理options请求。
        我把代码还原至没添加<mvc:annotation-driven>的状态,然后在注册RequestMappingHandlerAdapter的代码后面加上如下代码:
        <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    2
     
    1
        <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
    2
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    三、小结

        (1)SpringMVC处理Options类型的请求,需要HttpRequestHandlerAdapter,如果没有就会抛异常
        (2)当我们不使用<mvc:annotation-driven>这个标签时,尽量手动把它会注册的HandlerAdapter都注册一遍,防止出现No adapter for handler的异常


  • 相关阅读:
    按列数自动换行
    百度C 语言吧 · 问题资料大全
    最新动态.某美女象山旅游计划
    被点名了,玩个游戏。
    我们仍未知道那天所看见的题的解法 1
    我们仍未知道那天所看见的题的解法 2
    算法初探 平衡树
    排列组合
    HttpRunner2.X开源接口测试框架学习(一):介绍与安装
    jmeter基础一:JMeter的主要测试组件总结
  • 原文地址:https://www.cnblogs.com/zeng1994/p/3557b0b3d61782225ae737c332efdf1b.html
Copyright © 2011-2022 走看看