2015-12-31 16 views
5

私はこのような@CrossOriginやってみたい:Spring 3で@CrossOriginアノテーションを行うにはどうすればいいですか?

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

(春4へと仮定すると、アップグレードが制約されている)私は春の3で、現時点で何をすべきか、次のようになります

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); 
    } 
} 

Spring 4.2の@CrossOriginの実装のソースはis hereです。

私の質問は:Spring 3で@CrossOriginアノテーションを行う方法は?

答えて

2

あなたはこのようにそれを実行します。

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

あなたはそうではありません。機能は4.2まで追加されませんでした(Spring 4シリーズはキャッシングやCORSなどのWeb技術に焦点を当てていました)。あなたができる最善の方法は、Filterが提供するアスペクト指向のアプローチです。より細かくしたい場合は、4.2に追加された機能を複製する独自のHandlerInterceptorを書くことができます。

+0

あなたは同様のHandlerInterceptor例に私を指すもらえますか? (私はそれがアノテーションとして動作すると仮定しています) – hawkeye

+0

@hawkeyeアノテーションを自分で調べて解釈する必要があります。私の推奨はSpring 4.2のソースを見ることです。 – chrylis

関連する問題