2012-03-01 7 views
23

Tôi muốn chặn yêu cầu OPTIONS với bộ điều khiển của tôi bằng cách sử dụng Spring MVC, nhưng nó bị bắt bởi DispatcherServlet. Làm thế nào tôi có thể quản lý điều đó?Làm cách nào để xử lý các TÙY CHỌN HTTP với Spring MVC?

+2

Đối với những người trên Khởi động mùa xuân, câu hỏi tiếp theo này có thể hữu ích: http://stackoverflow.com/questions/33331042/how-to-handle-http-options-requests-in-spring-boot – Jonik

Trả lời

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

} 

Bạn nên cấu hình DispatcherServlet bằng cách thiết lập của nó dispatchOptionsRequest để true

+0

thực sự nó sẽ không hoạt động vì DispatcherServlet sẽ chặn yêu cầu và nó sẽ xử lý nó. Nó nên được cấu hình DispatcherServlet thay thế. Tôi đã có rất nhiều đau đớn với vấn đề này, và hiện tại tôi đã giải quyết được một phần vấn đề. Tôi muốn đăng giải pháp của mình cho cộng đồng nhưng ... vì tôi có ít hơn 100 luồng xếp chồng danh tiếng buộc tôi phải đợi 8 tiếng để tôi trả lời câu hỏi của riêng mình. – MaVVamaldo

+0

Tôi đã thêm bản cập nhật – Bozho

+1

có nó là giải pháp. Tôi nên gặp bạn trước đây, Chúa ơi! XD Tuy nhiên đây là một giải pháp "một phần" vì DispatcherServlet sẽ làm "một số công việc" trước khi ủy quyền cho bộ điều khiển của bạn. Infact, mặc dù bạn sẽ không chạm vào tiêu đề "Cho phép" nó sẽ được lấp đầy với một danh sách "cho phép phương pháp". Trong trường hợp của tôi nó sẽ không là một vấn đề nhưng tôi cho rằng nó là dành cho người khác. – MaVVamaldo

30

tôi đã thêm một số chi tiết để trả lời Bozho cho người mới bắt đầu. Đôi khi rất hữu ích khi để Trình điều khiển Spring quản lý yêu cầu OPTIONS (ví dụ để đặt tiêu đề "Access-Control-Allow- *" chính xác để phục vụ cuộc gọi AJAX). Tuy nhiên, nếu bạn thử thực hành phổ biến

@Controller 
public class MyController { 

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

Nó sẽ không hoạt động vì DispatcherServlet sẽ chặn yêu cầu OPTIONS của khách hàng.

Cách giải quyết rất đơn giản:

Bạn phải ... cấu hình DispatcherServlet từ file web.xml của bạn như sau:

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

Thêm "dispatchOptionsRequest" tham số và thiết lập nó là true .

Bây giờ DispatcherServlet sẽ ủy quyền xử lý OPTIONS cho bộ điều khiển của bạn và phương thức manageOption() sẽ thực thi.

Hy vọng điều này sẽ hữu ích.

PS. thành thật mà nói, tôi thấy rằng DispatcherServlet nối thêm danh sách các phương thức được phép vào phản hồi. Trong trường hợp của tôi, điều này không quan trọng và tôi để điều đó xảy ra. Có thể cần kiểm tra thêm.

+1

nhưng điều này không làm việc, nếu ví dụ một handlermethod được đăng ký tại điểm cuối "/ x/y". Bây giờ yêu cầu OPTIONS đến/x hoạt động nhưng không đến/x/y có tùy chọn nào để giải quyết vấn đề này không? có nghĩa là để thêm OPTIONS-xử lý này cho tất cả các thiết bị đầu cuối đã đăng ký? Tôi nghĩ về những kẻ đánh chặn nhưng có cách nào khác không? – wrm

8

Là một bổ sung nhanh cho 2 câu trả lời ở trên, dưới đây là cách bật dispatchOptionsRequest trong môi trường servlet 3 (không có web.xml) vì tôi mất một thời gian để tìm hiểu cách áp dụng câu trả lời ở trên không phải là xml thiết lập.

Trong môi trường mùa xuân 3.2/servlet 3, bạn sẽ có một số lớp học khởi tạo DispatcherServlet tương đương java của web.xml; trong trường hợp của tôi là AbstractAnnotationConfigDispatcherServletInitializer. Thêm đoạn mã sau sẽ cho phép dispatchOptionsRequest:

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

tôi lấy phương pháp sau đây:

Sử dụng Maven (or manually) kéo trong dependancy này:

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

này có một thực hiện để nắm bắt tất cả các yêu cầu OPTIONS đến. Vào tệp tin web.xml, hãy thêm cấu hình sau:

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

Vấn đề tôi đã thấy với cách tiếp cận/** là việc triển khai Bộ điều khiển cụ thể hơn sẽ ghi đè điều này.

0

Đối với Spring không có tệp web.xml và dựa trên câu trả lời của Paul Adamson, tôi chỉ đặt tham số dispatchOptionsRequest thành true vào điều phối, để xử lý các cuộc gọi phương thức Options.

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

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

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