2015-12-31 17 views
5

Mi piacerebbe fare @CrossOrigin in questo modo:Come fare un'annotazione @CrossOrigin nella primavera 3?

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

(Supponendo che l'aggiornamento a molla 4 è vincolato) Cosa devo fare in questo momento con Spring 3 si presenta così:

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

Si noti che la fonte per l'implementazione di @CrossOrigin nella primavera 4.2 is here.

La mia domanda è: Come fare un'annotazione @CrossOrigin nella primavera 3?

risposta

2

lo fate come questo:

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

Non è così; la funzionalità non è stata aggiunta fino alla 4.2 (la serie Spring 4 si è concentrata sulle tecnologie Web come la cache e il CORS). Il meglio che puoi fare è l'approccio orientato all'aspetto, che fornisce il tuo Filter o se vuoi più granularità, puoi scrivere il tuo HandlerInterceptor che duplica la funzionalità aggiunta alla 4.2.

+0

Mi può indicare un esempio HandlerInterceptor simile? (Suppongo che funzioni come annotazione) – hawkeye

+0

@hawkeye Dovresti controllare e interpretare tu stesso l'annotazione. La mia raccomandazione è di guardare la fonte Spring 4.2. – chrylis

Problemi correlati