2015-12-31 15 views
5

Tôi muốn làm @CrossOrigin như thế này:Cách thực hiện chú thích @CrossOrigin trong Mùa xuân 3?

@CrossOrigin(origins = "http://domain2.com") 
@RequestMapping("/{id}") 
public Account retrieve(@PathVariable Long id) { 
    // ... 
} 

(Giả sử nâng cấp lên mùa xuân 4 bị hạn chế) Những gì tôi phải làm vào lúc với mùa xuân 3 trông như thế này:

public class CORSFilter implements Filter { 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 
     HttpServletResponse response = (HttpServletResponse) res; 
     HttpServletRequest request= (HttpServletRequest) req; 
     response.setHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); 
     response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); 
     response.setHeader("Access-Control-Expose-Headers", "x-requested-with"); chain.doFilter(req, res); 
    } 
} 

Lưu ý rằng nguồn để thực hiện @CrossOrigin trong Mùa xuân 4.2 is here.

Câu hỏi của tôi là: Cách thực hiện chú thích @CrossOrigin trong Spring 3?

Trả lời

2

Bạn làm điều đó như thế này:

package com.mycompany; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Spring3CorsFilter {} 

package com.mycompany; 

import org.springframework.web.method.HandlerMethod; 
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

/** 
* The purpose of this class is to emulate the Spring 4 annotation @CORSFilter - using the power of Spring 3 
* Note that is is constrained to non-prod environments 
*/ 
public class Spring3CorsFilterHandlerInterceptor extends HandlerInterceptorAdapter { 

    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws 
      Exception { 

     if (handler instanceof HandlerMethod) { 
      HandlerMethod handlerMethod = (HandlerMethod) handler; 
      // Test if the controller-method is annotated with @Spring3CORSFilter 
      Spring3CorsFilter filter = handlerMethod.getMethod().getAnnotation(Spring3CorsFilter.class); 
      if (filter != null) { 
       // ... do the filtering 
       response.setHeader("Access-Control-Allow-Origin", "*"); 
       response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); 
       response.setHeader("Access-Control-Max-Age", "3600"); 
       response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); 
      } 
     } 
     return true; 
    } 
} 

package com.mycompany; 

import com.google.common.base.Optional; 
import com.google.common.collect.FluentIterable; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.mock.web.MockHttpServletRequest; 
import org.springframework.mock.web.MockHttpServletResponse; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 
import org.springframework.test.context.support.AnnotationConfigContextLoader; 
import org.springframework.web.servlet.HandlerExecutionChain; 
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 

import java.util.Arrays; 
import java.util.Set; 

import static junit.framework.TestCase.assertTrue; 
import static org.junit.Assert.assertFalse; 


@RunWith(SpringJUnit4ClassRunner.class) 
public class Spring3CorsFilterHandlerInterceptorTest { 

    @Autowired 
    private RequestMappingHandlerMapping requestMappingHandlerMapping; 

    @Test 
    public void interceptor_is_on_request() throws Exception { 
     MockHttpServletRequest request = new MockHttpServletRequest("GET", 
       "/public/version"); 

     HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request); 

     Optional<Spring3CorsFilterHandlerInterceptor> containsHandler = FluentIterable 
       .from(Arrays.asList(handlerExecutionChain.getInterceptors())) 
       .filter(Spring3CorsFilterHandlerInterceptor.class).first(); 

     // Note that this will be present for all requests due to the mapping in spring-security.xml 
     assertTrue(containsHandler.isPresent()); 
    } 

    @Test 
    public void interceptor_is_not_run_on_non_annotated_request() throws Exception { 
    MockHttpServletRequest request = new MockHttpServletRequest("GET", 
       "/public/home"); 

     HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request); 

     Optional<Spring3CorsFilterHandlerInterceptor> containsHandler = FluentIterable 
       .from(Arrays.asList(handlerExecutionChain.getInterceptors())) 
       .filter(Spring3CorsFilterHandlerInterceptor.class).first(); 

     MockHttpServletResponse response = new MockHttpServletResponse(); 

     Spring3CorsFilterHandlerInterceptor handlerInterceptor = containsHandler.get(); 
     handlerInterceptor.preHandle(request, response, handlerExecutionChain.getHandler()); 

     Set<String> headerNames = response.getHeaderNames(); 
     assertFalse(headerNames.contains("Access-Control-Allow-Origin")); 
     assertFalse(headerNames.contains("Access-Control-Allow-Methods")); 
     assertFalse(headerNames.contains("Access-Control-Max-Age")); 
     assertFalse(headerNames.contains("Access-Control-Allow-Headers")); 
    } 

    @Test 
    public void interceptor_runs_on_annotated_request() throws Exception { 

     MockHttpServletRequest request = new MockHttpServletRequest("GET", 
       "/public/version"); 
     MockHttpServletResponse response = new MockHttpServletResponse(); 

     HandlerExecutionChain handlerExecutionChain = requestMappingHandlerMapping.getHandler(request); 

     Optional<Spring3CorsFilterHandlerInterceptor> containsHandler = FluentIterable 
       .from(Arrays.asList(handlerExecutionChain.getInterceptors())) 
       .filter(Spring3CorsFilterHandlerInterceptor.class).first(); 

     Spring3CorsFilterHandlerInterceptor handlerInterceptor = containsHandler.get(); 
     handlerInterceptor.preHandle(request, response, handlerExecutionChain.getHandler()); 

     Set<String> headerNames = response.getHeaderNames(); 
     assertTrue(headerNames.contains("Access-Control-Allow-Origin")); 
     assertTrue(headerNames.contains("Access-Control-Allow-Methods")); 
     assertTrue(headerNames.contains("Access-Control-Max-Age")); 
     assertTrue(headerNames.contains("Access-Control-Allow-Headers")); 
    } 
} 
1

Bạn không; chức năng không được thêm vào cho đến 4.2 (loạt phim Spring 4 đã tập trung vào các công nghệ web như bộ nhớ đệm và CORS). Điều tốt nhất bạn có thể làm là cách tiếp cận hướng-khía cạnh, mà Filter của bạn cung cấp, hoặc nếu bạn muốn chi tiết hơn, bạn có thể viết của riêng bạn HandlerInterceptor sao chép các chức năng được thêm vào 4.2.

+0

Ông có thể chỉ cho tôi một ví dụ HandlerInterceptor tương tự? (Tôi giả sử nó sẽ hoạt động như một chú giải) – hawkeye

+0

@hawkeye Bạn sẽ phải tự mình kiểm tra và giải thích chú thích. Khuyến nghị của tôi là xem xét nguồn Spring 4.2. – chrylis

Các vấn đề liên quan