SpringMVC处理跨域请求时的一个注意事项

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

一、异常信息

具体的异常信息如下:

threw exception [No adapter for handler [org.springframew[email protected]edcb4b4]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler] with root cause
javax.servlet.ServletException: No adapter for handler [org.springframew[email protected]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的异常

原文地址:https://www.cnblogs.com/zeng1994/p/3557b0b3d61782225ae737c332efdf1b.html

时间: 2024-11-07 00:52:57

SpringMVC处理跨域请求时的一个注意事项的相关文章

javascript fetch 跨域请求时 session失效问题

javascript 使用fetch进行跨域请求时默认是不带cookie的,所以会造成 session失效. fetch(url, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: JSON.stringify({ data: options.data }) }) credentials: 'include' 可以是f

关于.Net Core 前后端分离跨域请求时 ajax并发请求导致部分无法通过验证解决办法。

项目中有这样一个页面.页面加载的时候会同时并发6个ajax请求去后端请求下拉框. 这样会导致每次都有1~2个"浏览器预请求"不通过. 浏览器为什么会自动发送"预请求"?请看以面连接 https://blog.csdn.net/charleslei/article/details/51906635 那么解决办法无非就是尽量避免发送"预请求". 后来经过反复测试发现"预请求"可以通过设置Access-Control-Max-Age

一个跨域请求的XSS续

之前讨论过,在解决post跨域请求时,采用iframe+本域代理页的形式,兼容性(当然是包括IE6啦)是最好的.上次提到,代理页面的作用是:执行本域下的回调函数.就是这个原因,给XSS带来了便利.详细说明,请参考一个跨域请求的XSS漏洞 上次也提到,解决这个问题的根本在于杜绝不合法的函数在页面内执行.上次透了一下懒,对函数名就行了包含匹配.过程如下: /** * callback的值为:namespace.function,prefix123456 */ var filter = [ 'name

CORS——跨域请求那些事儿

在日常的项目开发时会不可避免的需要进行跨域操作,而在实际进行跨域请求时,经常会遇到类似 No 'Access-Control-Allow-Origin' header is present on the requested resource.这样的报错.这样的错误,一般是由于CORS跨域验证机制设置不正确导致的,本文将详细讲解CORS跨域验证机制的原理,让您轻松掌握CORS跨域设置的使用方法,安全.方便的进行前端开发. 什么是CORS CORS(Cross-Origin Resource Sha

Nginx服务器中处理AJAX跨域请求的配置方法讲解

Nginx 实现AJAX跨域请求AJAX从一个域请求另一个域会有跨域的问题.那么如何在nginx上实现ajax跨域请求呢?要在nginx上启用跨域请求,需要添加add_header Access-Control*指令.如下所示: ? 1 2 3 4 5 6 7 8 9 10 11 12 location /{ add_header 'Access-Control-Allow-Origin' 'http://other.subdomain.com'; add_header 'Access-Cont

JS跨域请求

1. 同源策略 所有的浏览器都遵守同源策略,这个策略能够保证一个源的动态脚本不能读取或操作其他源的http响应和cookie,这就使浏览器隔离了来自不同源的内 容,防止它们互相操作.所谓同源是指协议.域名和端口都一致的情况.举例来说,首先在Nginx上配置两个虚拟主机,一个监听80端口,另一个监听81端 口: server {           listen 80;           server_name localhost;                      location /

处理跨域请求

浏览器具有同源策略,会禁止向与当前页面不同的域发送请求,只要是协议,域名,端口中有任何一个不同,都被当作是不同的域,这虽然是一种保护数据的机制,但是对我们开发来说确是个麻烦,解决办法有很多,这里介绍一下JSONP和CORS 先来理解一下浏览器这个同源策略是什么,就是浏览器禁止掉向其他域名发送的请求,其实是在请求回来的时候被禁掉的 哪些操作会受同源策略,哪些不会呢? requests模块不受影响,因为没有经过浏览器 ajax发请求时,浏览器会限制(我们就是要解决这个问题) 有src属性的都不受同源

Springboot如何优雅的解决ajax+自定义headers的跨域请求[转]

1.什么是跨域 由于浏览器同源策略(同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.),凡是发送请求url的协议.域名.端口三者之间任意一与当前页面地址不同即为跨域. 具体可以查看下表: 2.springboot如何解决跨域问题 1.普通跨域请求解决方案: ①请求接口添加注解@CrossOrigin(origins = "http://127.0.0.1:8020", maxAge

ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分离普遍存在的问题跨域(CORS)请求问题.因此就有了这篇文章如何启用ASP.NET WebApi 中的 CORS 支持. 一.解决Vue报错:OPTIONS 405 Method Not Allowed问题: 错误重现: index.umd.min.js:1 OPTIONS http://local