26-springMvc注解开发-跨域问题

1 什么是跨域

  • 当一个域名请求另一个域名的资源时,即是跨域
  • 协议,主机,端口任何一个不同即为跨域

2 解决跨域

核心就是设置响应头,允许跨域

2.1 通过过滤器解决

  1. 通过过滤器统一添加响应头
public class CrossOriginFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        try{
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse)res;
            //设置response的响应消息头实现跨域问题的解决
            /* 允许跨域的主机地址 */
            response.setHeader("Access-Control-Allow-Origin", "*");
            /* 允许跨域的请求方法GET, POST, HEAD 等 */
            response.setHeader("Access-Control-Allow-Methods", "*");
            /* 重新预检验跨域的缓存时间 (s) */
            response.setHeader("Access-Control-Max-Age", "3600");
            /* 允许跨域的请求头 */
            response.setHeader("Access-Control-Allow-Headers", "*");
            /* 是否携带cookie */
            response.setHeader("Access-Control-Allow-Credentials", "true");
            //放行
            chain.doFilter(request,response);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void destroy() {

    }
}
  1. 配置过滤器
    可参考环境搭建配置字符编码过滤器
 FilterRegistration.Dynamic crossOriginFilter = servletContext.addFilter("crossOriginFilter", new CrossOriginFilter());
     crossOriginFilter.addMappingForUrlPatterns(
             EnumSet.of(DispatcherType.FORWARD,DispatcherType.REQUEST,DispatcherType.INCLUDE),
             false,
             "/*"
     );
public class Config extends AbstractDispatcherServletInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        // 调用父类的onStartup
        super.onStartup(servletContext);
        // 创建乱码过滤器对象
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        // 设置字符集
        encodingFilter.setEncoding("UTF-8");
        // 添加到servlet容器中
        FilterRegistration.Dynamic registration = servletContext.addFilter("encodingFilter", encodingFilter);
        // 添加映射
        registration.addMappingForUrlPatterns(
                EnumSet.of(DispatcherType.FORWARD,DispatcherType.REQUEST,DispatcherType.INCLUDE),
                false,
                "/*"
                );
        // 注册解决跨域的过滤器
        FilterRegistration.Dynamic crossOriginFilter = servletContext.addFilter("crossOriginFilter", new CrossOriginFilter());
        crossOriginFilter.addMappingForUrlPatterns(
                EnumSet.of(DispatcherType.FORWARD,DispatcherType.REQUEST,DispatcherType.INCLUDE),
                false,
                "/*"
        );

    }

    /**
        创建Servlet容器,创建springmvc容器
     */
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        // 由于是基于注解开发,创建注解开发对应的容器
        AnnotationConfigWebApplicationContext acw = new AnnotationConfigWebApplicationContext();
        // 注册配置类
        acw.register(SpringMvcConfiguration.class);
        return acw;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     创建根容器,根容器是不可以访问子容器Servlet容器的bean,也就控制了service层是不能访问controller层的bean
     创建springioc容器
     */
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        // 由于是基于注解开发,创建注解开发对应的容器
        AnnotationConfigWebApplicationContext acw = new AnnotationConfigWebApplicationContext();
        // 注册配置类: 这就要注册spring的配置类
        acw.register(ApplicationContextConfiguration.class);
        return acw;
    }
}

2.2 通过CrossOrigin注解

在需要跨域的请求上使用注解CrossOrigin
此注解用于指定是否支持跨域访问

@RequestMapping("/useCrossOrigin")
@CrossOrigin
public String useCrossOrigin(@RequestBody(required = false) User user){
    System.out.println("user is "+user);
    return "success";
}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	String[] DEFAULT_ORIGINS = { "*" };

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	String[] DEFAULT_ALLOWED_HEADERS = { "*" };

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	boolean DEFAULT_ALLOW_CREDENTIALS = false;

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	long DEFAULT_MAX_AGE = 1800;


	/**
	 * Alias for {@link #origins}.
	 */
	@AliasFor("origins")
	String[] value() default {};

	/**
		 "*"代表所有域的请求都支持
		 如果没有定义,所有请求的域都支持
	 */
	@AliasFor("value")
	String[] origins() default {};

	/**
	允许请求头中的header,默认都支持
	 */
	String[] allowedHeaders() default {};

	/**
	响应头中允许访问的header,默认为空
	 */
	String[] exposedHeaders() default {};

	/**
	用于指定支持的HTTP请求方式列表
	 */
	RequestMethod[] methods() default {};

	/**
	是否允许cookie随请求发送,使用时必须指定具体的域
	 */
	String allowCredentials() default "";

	/**
	预请求的结果的有效期 * 默认值是:1800秒 (30分钟).
	 */
	long maxAge() default -1;

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值