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

来源:互联网 发布:mac如何网页看视频 编辑:程序博客网 时间:2024/05/27 01:29

关于跨域资源访问请参考 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);@Autowiredprivate IAccessService accessService;private String accessKeyParameterName="accessKey";private List<String> defaultAccessAllowedFrom;@Overridepublic 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<String> getDefaultAccessAllowedFrom() {return defaultAccessAllowedFrom;}public void setDefaultAccessAllowedFrom(List<String> defaultAccessAllowedFrom) {this.defaultAccessAllowedFrom = defaultAccessAllowedFrom;}public String getAccessKeyParameterName() {return AccessKeyParameterName;}public void setAccessKeyParameterName(String accessKeyParameterName) {this.AccessKeyParameterName = AccessKeyParameterName;}}
其中defaultAccessAllowedFrom是在Spring的配置文件中,主要的配置默认授权访问的url,如下:

    <property name="defaultAccessAllowedFrom">    <list>    <value>(.+\.)?(domain\.com)$</value>    <value>(.+\.)?(192\.168\.0\.10)$</value>    </list>    </property>

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

<servlet>     <servlet-name>application</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>   <init-param>   <param-name>dispatchOptionsRequest</param-name>      <param-value>true</param-value>   </init-param>     <load-on-startup>1</load-on-startup>  </servlet>  <servlet-mapping>     <servlet-name>application</servlet-name>     <url-pattern>/</url-pattern> </servlet-mapping>  

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