Spring 3.1 MVC REST 支持之跨域访问(Cross-origin resource sharing)

关于跨域资源访问请参考 http://en.wikipedia.org/wiki/Cross-origin_resource_sharing ,基本原理是在Spring Controller的每一个请求返回的时候都加上Access-Control-...header,需要注意的是并不是所有的浏览器都支持这些header,使用之前要先了解清楚。

实现起来也很简单那就是Interceptor,代码如下:

public class AccessKeyInterceptor extends HandlerInterceptorAdapter {

	private static Log log=LogFactory.getLog(AccessKeyInterceptor.class);
	
	@Autowired
	private IAccessService accessService;
	
	private String accessKeyParameterName="accessKey";
	private List defaultAccessAllowedFrom;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		String accessKey=request.getParameter(accessKeyParameterName);
		String referer = request.getHeader("Referer");
		URL u = new URL(referer);
		String host = u.getHost().toLowerCase();
		if(accessKey==null){
			log.error("====================================ILLEGAL ACCESS: ACCESS_KEY_MISSING!=======================");
		}else{
			log.debug("====================================ACCESS WITH Access KEY:"+accessKey+"====================");
			IAccess access = accessService.getAccess(UserSessionUtils.getUserSession(request), accessKey);
			if(access!=null){
				defaultAccessAllowedFrom=access.getAccessAllowedFrom();
			}else{
				log.warn("======================================ACCESS KEY:"+accessKey+" DOES NOT EXIST!=================");	
			}
		}
		for(String s : defaultAccessAllowedFrom) {
			if(host.matches(s)){							
				response.setHeader("Access-Control-Allow-Origin", referer);
				break;
			}
		}
		response.setHeader("Access-Control-Allow-Headers", "Content-Type");
		response.setHeader("Access-Control-Allow-Methods", "GET");
		response.setHeader("Allow", "GET");
		return true;
	}
	
	public List getDefaultAccessAllowedFrom() {
		return defaultAccessAllowedFrom;
	}

	public void setDefaultAccessAllowedFrom(List defaultAccessAllowedFrom) {
		this.defaultAccessAllowedFrom = defaultAccessAllowedFrom;
	}

	public String getAccessKeyParameterName() {
		return AccessKeyParameterName;
	}

	public void setAccessKeyParameterName(String accessKeyParameterName) {
		this.AccessKeyParameterName = AccessKeyParameterName;
	}
}
其中defaultAccessAllowedFrom是在Spring的配置文件中,主要的配置默认授权访问的url,如下:

    	
    		
    			(.+\.)?(domain\.com)$
    			(.+\.)?(192\.168\.0\.10)$
    		
    	

但是由于Spring默认Controller是不处理OPTIONS的请求的,所以必须在web.xml中打开,如下:

	  
	   application  
	   org.springframework.web.servlet.DispatcherServlet
	   
	   		dispatchOptionsRequest
	      	true
	     
	   1  
	  
	  
	   application  
	   / 
	  

这样当请求时POST的时候前段就会自动先请求OPTIONS,得到许可后就可以跨域访问POST请求了。一般我们会在OPTIONS的方法中加上"Allow: OPTIONS,GET,POST"类似header以区分于普通的请求。


你可能感兴趣的:(Web,Java,Spring,WebService)