2012-03-01 14 views
23

Chciałbym przechwycić żądanie OPTIONS z moim kontrolerem przy użyciu Spring MVC, ale jest ono przechwytywane przez DispatcherServlet. Jak mogę to zarządzać?Jak obsługiwać OPCJE HTTP za pomocą Spring MVC?

+2

Dla tych na wiosennym Boot to kontynuacja pytanie może być przydatna: http://stackoverflow.com/questions/33331042/how-to-handle-http-options-requests-in-spring-boot – Jonik

Odpowiedz

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

} 

należy skonfigurować dispatcherServlet poprzez ustawienie jej dispatchOptionsRequest do true

+0

w rzeczywistości to nie zadziała, ponieważ DispatcherServlet przechwyci żądanie i poradzi sobie z nim. Zamiast tego należy skonfigurować DispatcherServlet. Miałem dużo bólu z tym problemem, a obecnie częściowo rozwiązałem problem. Chciałem opublikować moje rozwiązanie dla społeczności, ale ... ponieważ mam mniej niż 100 punktów reputacji, stackoverflow zmuszają mnie do czekania 8 godzin przed udzieleniem mi odpowiedzi na własne pytania. – MaVVamaldo

+0

Dodałem aktualizację – Bozho

+1

tak, to jest rozwiązanie. Powinienem cię wcześniej poznać, dobry Boże! XD Jednak jest to rozwiązanie "częściowe", ponieważ DispatcherServlet wykona "trochę pracy" przed delegowaniem kontrolera. Rzeczywiście, nawet jeśli nie dotkniesz nagłówka "Zezwalaj", zostanie wypełniona lista "dozwolonej metody". W moim przypadku nie stanowiłoby to problemu, ale przypuszczam, że jest to dla kogoś innego. – MaVVamaldo

30

dodałam trochę więcej szczegółów do odpowiedzi Bozho dla początkujących. Czasami warto pozwolić kontrolerowi sprężynowemu zarządzać żądaniem OPTIONS (na przykład, aby ustawić poprawny nagłówek "Access-Control-Allow- *" do obsługi wywołania AJAX). Jeśli jednak spróbować powszechną praktyką

@Controller 
public class MyController { 

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

To nie będzie działać, ponieważ DispatcherServlet przechwyci żądanie OPTIONS klienta.

Rozwiązaniem jest bardzo prosta:

... Musisz skonfigurować DispatcherServlet z pliku web.xml następująco:

... 
    <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> 
... 

Dodanie parametru „dispatchOptionsRequest” i ustawienie go na true .

Teraz DispatcherServlet deleguje obsługę OPTIONS do kontrolera i zostanie uruchomiona metoda manageOption().

Mam nadzieję, że to pomoże.

PS. Szczerze mówiąc, widzę, że DispatcherServlet dołącza listę dozwolonej metody do odpowiedzi. W moim przypadku nie było to ważne i zostawiłem to. Może potrzebne są dalsze badania.

+1

ale to nie działa, jeśli na przykład procedura handlowa jest zarejestrowana w punkcie końcowym "/ x/y". Teraz opcja-żądanie do/x działa, ale nie do/x/y czy jest jakaś opcja rozwiązania tego problemu? co oznacza dodanie tej obsługi OPCJI do wszystkich zarejestrowanych punktów końcowych? Myślę o przechwytywaczach, ale czy istnieje jakiś inny sposób? – wrm

8

Jako szybkie uzupełnienie powyższych 2 odpowiedzi, oto jak włączyć dispatchOptionsRequest w środowisku serwletu 3 (bez web.xml), ponieważ zajęło mi trochę czasu, aby dowiedzieć się, jak zastosować powyższe odpowiedzi w języku innym niż xml Ustawiać.

W środowisku źródłowym 3.2/servlet 3, będziesz mieć pewną odmianę klasy inicjatora DispatcherServlet, która jest odpowiednikiem java web.xml; w moim przypadku jest to AbstractAnnotationConfigDispatcherServletInitializer. Dodanie następującego kodu pozwoli dispatchOptionsRequest:

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

wziąłem następujące podejście:

Korzystanie Maven (or manually) pociągnąć w tym dependancy:

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

Ma to wdrożenie do przechwytywania wszystkich przychodzące żądania OPTIONS. W pliku web.xml dodać następujące config:

<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> 

Problem widziałem z podejściem/** to bardziej konkretne wdrożenie Kontroler będzie to zmienić.

0

na wiosnę bez pliku web.xml, oraz w oparciu o Paul Adamson odpowiedzi, po prostu ustawić parametr dispatchOptionsRequest do true do dyspozytora, aby przetwarzać Options wywołań metod.

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

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

dispatcher.setLoadOnStartup(1); 
dispatcher.addMapping("/*"); 
Powiązane problemy