2012-03-01 12 views
23

Me gustaría interceptar la solicitud OPTIONS con mi controlador utilizando Spring MVC, pero está atrapado por DispatcherServlet. ¿Cómo puedo gestionar eso?¿Cómo se manejan las OPCIONES HTTP con Spring MVC?

+2

Para aquellos en la primavera de arranque, esta pregunta de seguimiento puede ser útil: http://stackoverflow.com/questions/33331042/how-to-handle-http-options-requests-in-spring-boot – Jonik

Respuesta

9
@RequestMapping(value="/youroptions", method=RequestMethod.OPTIONS) 
public View getOptions() { 

} 

Debe configurar el DispatcherServlet estableciendo su dispatchOptionsRequest a true

+0

en realidad no funcionará, ya que el DispatcherServlet interceptará la solicitud y la manejará. Debería configurarse el DispatcherServlet en su lugar. Tuve mucho dolor con este problema, y ​​actualmente resolví parcialmente el problema. Quería publicar mi solución para la comunidad pero ... dado que tengo menos de 100 de reputación, stackoverflow me obliga a esperar 8 horas antes de dejarme responder mis propias preguntas. – MaVVamaldo

+0

He añadido una actualización – Bozho

+1

sí, es la solución. Debería haberte conocido antes, ¡Dios mío! XD Sin embargo, esta es una solución "parcial" porque el DispatcherServlet hará "algún trabajo" antes de delegar su controlador. De hecho, aunque no toque el encabezado "Permitir", se completará con una lista de "método permitido". En mi caso, no sería un problema, pero supongo que es para otra persona. – MaVVamaldo

30

añadí un poco más de detalle para la respuesta Bozho para los principiantes. A veces es útil dejar que Spring Controller administre la solicitud OPTIONS (por ejemplo, para configurar el encabezado correcto "Access-Control-Allow- *" para atender una llamada AJAX). Sin embargo, si se intenta la práctica común

@Controller 
public class MyController { 

    @RequestMapping(method = RequestMethod.OPTIONS, value="/**") 
    public void manageOptions(HttpServletResponse response) 
    { 
     //do things 
    } 
} 

No va a funcionar ya que el DispatcherServlet interceptará solicitud de OPCIONES del cliente.

La solución es muy sencilla:

Tienes que ... configurar el DispatcherServlet de su archivo web.xml de la siguiente manera:

... 
    <servlet> 
    <servlet-name>yourServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>dispatchOptionsRequest</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 
... 

Añadiendo el parámetro "dispatchOptionsRequest" y se establece en verdadero .

Ahora el DispatcherServlet delegará el manejo de OPCIONES a su controlador y se ejecutará el método manageOption().

Espero que esto ayude.

PS. para ser sincero, veo que DispatcherServlet anexa la lista de métodos permitidos a la respuesta. En mi caso, esto no era importante y dejé que se fuera. Tal vez se necesiten más exámenes.

+1

pero esto no funciona, si, por ejemplo, se registra un handlermethod en el punto final "/ x/y". Ahora, ¿hay alguna opción para resolver este problema? OPCIONES-solicitud a/x pero no a/x/y ¿Quiere decir agregar este manejo de OPCIONES a todos los puntos finales registrados? Pienso en los interceptores, pero ¿hay alguna otra manera? – wrm

8

Como un complemento rápido a las 2 respuestas anteriores, a continuación se indica cómo habilitar dispatchOptionsRequest en un entorno servlet 3 (no web.xml), ya que tardé un rato en descifrar cómo aplicar las respuestas anteriores en un archivo no xml preparar.

En un entorno de primavera 3.2/servlet 3, tendrá una variedad de clase de inicializador DispatcherServlet que es el equivalente java de web.xml; en mi caso es el AbstractAnnotationConfigDispatcherServletInitializer. Añadiendo el siguiente código permitirá dispatchOptionsRequest:

@Override 
    protected void customizeRegistration(Dynamic registration) { 
     registration.setInitParameter("dispatchOptionsRequest", "true"); 
    } 
3

Tomé el siguiente enfoque:

El uso de Maven (or manually) tire de esta dependencia:

<dependency> 
    <groupId>com.thetransactioncompany</groupId> 
    <artifactId>cors-filter</artifactId> 
    <version>1.3.2</version> 
</dependency> 

Esto tiene una aplicación para capturar toda la solicitudes de OPCIONES entrantes. En el archivo web.xml añadir la siguiente configuración:

<filter> 
    <filter-name>CORS</filter-name> 
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>  
    <init-param> 
     <param-name>cors.supportedHeaders</param-name> 
     <param-value>Content-Type,Accept,Origin</param-value> 
    </init-param> 
</filter> 

<filter-mapping> 
    <filter-name>CORS</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

El problema que he visto con el/** enfoque es una implementación del controlador más específica anulará esto.

0

para la primavera sin el archivo web.xml, y en base a la respuesta de Paul Adamson, acabo de poner el parámetro dispatchOptionsRequest a true en el despachador, para procesar las llamadas a métodos Options.

ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new  DispatcherServlet(applicationContext)); 

dispatcher.setInitParameter("dispatchOptionsRequest", "true");     

dispatcher.setLoadOnStartup(1); 
dispatcher.addMapping("/*"); 
Cuestiones relacionadas