2015-12-31 13 views
5

Böyle @CrossOrigin yapmak istiyorum:İlkbahar 3'te @CrossOrigin ek açıklaması nasıl yapılır?

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

(Bahar 4'e varsayarsak yükseltme kısıtlıdır) Ne Bahar 3 ile şu anda yapmak zorunda şuna benzer:

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

Not: @CrossOrigin'un Spring 4.2 is here numaralı telefonunda uygulanması için kaynak olduğunu unutmayın.

Soruma ilişkin soru: İlkbahar 3'te @CrossOrigin ek açıklaması nasıl yapılır?

cevap

2

Sen böyle yapın:

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

Yapmayın; işlevsellik 4.2'ye kadar eklenmedi (Spring 4 serisi önbellekleme ve CORS gibi Web teknolojilerine odaklanmıştı). Yapabileceğiniz en iyi şey, Filter'unuzun sağladığı, yönelimli yaklaşımdır veya daha fazla ayrıntı istiyorsanız, 4.2'ye eklenen işlevselliği çoğaltan kendi HandlerInterceptor'unuzu yazabilirsiniz.

+0

Benzer bir HandlerInterceptor örnek bana gösterebilir misiniz? (Bir not olarak çalışacağını varsayalım) – hawkeye

+0

@hawkeye Ek açıklamaları kendiniz incelemek ve yorumlamak zorundasınız. Benim tavsiyem Spring 4.2 kaynağına bakmak. – chrylis

İlgili konular