SpringBoot使用CROS解决跨域问题

跨域问题其实之前就有说过,不明白的可以参考我之前的文章,这章主要讲解SpringBoot CROS的支持。

这里主要按照官方文档方式讲述。

SpringBoot CROS 参考: http://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/htmlsingle/#boot-features-cors

Spring CROS 参考: http://docs.spring.io/spring/docs/4.3.9.RELEASE/spring-framework-reference/htmlsingle/#cors

在这里插入图片描述

package cn.saytime.web;
 
import cn.saytime.bean.JsonResult;
import cn.saytime.bean.User;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * @author zh
 * @ClassName cn.saytime.web.UserController
 * @Description
 */
@RestController
public class UserController {
 
	// 创建线程安全的Map
	static Map users = Collections.synchronizedMap(new HashMap());
 
	/**
	 * 根据ID查询用户
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "user/{id}", method = RequestMethod.GET)
	public ResponseEntity getUserById (@PathVariable(value = "id") Integer id){
		JsonResult r = new JsonResult();
		try {
			User user = users.get(id);
			r.setResult(user);
			r.setStatus("ok");
		} catch (Exception e) {
			r.setResult(e.getClass().getName() + ":" + e.getMessage());
			r.setStatus("error");
			e.printStackTrace();
		}
		return ResponseEntity.ok(r);
	}
 
	/**
	 * 查询用户列表
	 * @return
	 */
	 @CrossOrigin
	@RequestMapping(value = "users", method = RequestMethod.GET)
	public ResponseEntity getUserList (){
		JsonResult r = new JsonResult();
		try {
			List userList = new ArrayList(users.values());
			r.setResult(userList);
			r.setStatus("ok");
		} catch (Exception e) {
			r.setResult(e.getClass().getName() + ":" + e.getMessage());
			r.setStatus("error");
			e.printStackTrace();
		}
		return ResponseEntity.ok(r);
	}
 
	/**
	 * 添加用户
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "user", method = RequestMethod.POST)
	public ResponseEntity add (@RequestBody User user){
		JsonResult r = new JsonResult();
		try {
			users.put(user.getId(), user);
			r.setResult(user.getId());
			r.setStatus("ok");
		} catch (Exception e) {
			r.setResult(e.getClass().getName() + ":" + e.getMessage());
			r.setStatus("error");
 
			e.printStackTrace();
		}
		return ResponseEntity.ok(r);
	}
 
	/**
	 * 根据id删除用户
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "user/{id}", method = RequestMethod.DELETE)
	public ResponseEntity delete (@PathVariable(value = "id") Integer id){
		JsonResult r = new JsonResult();
		try {
			users.remove(id);
			r.setResult(id);
			r.setStatus("ok");
		} catch (Exception e) {
			r.setResult(e.getClass().getName() + ":" + e.getMessage());
			r.setStatus("error");
 
			e.printStackTrace();
		}
		return ResponseEntity.ok(r);
	}
 
	/**
	 * 根据id修改用户信息
	 * @param user
	 * @return
	 */
	@RequestMapping(value = "user/{id}", method = RequestMethod.PUT)
	public ResponseEntity update (@PathVariable("id") Integer id, @RequestBody User user){
		JsonResult r = new JsonResult();
		try {
			User u = users.get(id);
			u.setUsername(user.getUsername());
			u.setAge(user.getAge());
			users.put(id, u);
			r.setResult(u);
			r.setStatus("ok");
		} catch (Exception e) {
			r.setResult(e.getClass().getName() + ":" + e.getMessage());
			r.setStatus("error");
 
			e.printStackTrace();
		}
		return ResponseEntity.ok(r);
	}
 
}

User.class

package cn.saytime.bean;
 
import java.util.Date;
 
/**
 * @author zh
 * @ClassName cn.saytime.bean.User
 * @Description
 */
public class User {
 
	private int id;
	private String username;
	private int age;
	private Date ctm;
 
	// Getter Setter
}

JsonResult.class

package cn.saytime.bean;
 
public class JsonResult {
 
	private String status = null;
 
	private Object result = null;
 
	// Getter Setter
}

二、测试是否存在跨域问题
我们在static目录新建一个test.html




	
	Title
	
	


	


我们使用IDEA的浏览器预览功能,点击谷歌小图标,可以看到打开网址为: http://localhost:63342/springboot-demo/springboot-cros/static/test.html?_ijt=ibtt432ffb9rh0vffqkkug3je8
启动SpringBoot工程,默认8080

不是使用IDEA的用户,自己找个tomcat启动test.html页面,修改端口为其他,然后启动springboot。

在这里插入图片描述
所以证明存在跨域问题。

一、@CrossOrigin注解方式 Controller method CORS configuration
这里我们在users映射的方法getUserList上面加上@CrossOrigin

@CrossOrigin
	@RequestMapping(value = "users", method = RequestMethod.GET)
	public ResponseEntity getUserList ()

然后再次使用上面的方式访问。


![在这里插入图片描述](https://img-blog.csdn.net/20170710213931410?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2F5dGltZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
表示跨域问题解决。 default @CrossOrigin allows all origins and the HTTP methods specified in the @RequestMapping annotation 上面的官方文档说明,也就是默认的@CrossOrigin允许所有跨域请求。

通过查看CrossOrigin源码可以看到, 默认配置为:

“Access-Control-Allow-Origin” : “*”
“Access-Control-Allow-Methods” : “GET,POST,PUT,OPTIONS”
“Access-Control-Allow-Credentials” : “true”


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
/** @deprecated /
@Deprecated
String[] DEFAULT_ORIGINS = new String[]{"
"};
/** @deprecated /
@Deprecated
String[] DEFAULT_ALLOWED_HEADERS = new String[]{"
"};
/** @deprecated /
@Deprecated
boolean DEFAULT_ALLOW_CREDENTIALS = true;
/
* @deprecated */
@Deprecated
long DEFAULT_MAX_AGE = 1800L;

@AliasFor("origins")
String[] value() default {};

@AliasFor("value")
String[] origins() default {};

String[] allowedHeaders() default {};

String[] exposedHeaders() default {};

RequestMethod[] methods() default {};

String allowCredentials() default "";

long maxAge() default -1L;

}

It is also possible to enable CORS for the whole controller 也可以用在整个Controller类上面。即该controller所有映射都支持跨域请求。

@CrossOrigin(origins = “http://domain2.com”,
maxAge = 3600,
methods = {RequestMethod.GET, RequestMethod.POST})
@RestController
public class UserController


二、全局CORS配置

Global CORS configuration In addition to fine-grained, annotation-based configuration you’ll probably want to define some global CORS configuration as well. This is similar to using filters but can be declared withing Spring MVC and combined with fine-grained @CrossOrigin configuration. By default all origins and GET, HEAD and POST methods are allowed.

package cn.saytime.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**

  • @author zh

  • @ClassName cn.saytime.config.CORSConfiguration

  • @Description
    */
    @Configuration
    public class CORSConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
    // registry.addMapping("/api/");
    registry.addMapping("/
    ")
    .allowedOrigins(“http://domain.com”, “http://domain2.com”)
    .allowedMethods(“GET”, “POST”, “DELETE”, “PUT”, “OPTIONS”)
    .allowCredentials(false).maxAge(3600);
    }
    };
    }
    }

三、过滤器实现跨域 Filter based CORS support

@Configuration
public class MyConfiguration {

@Bean
public FilterRegistrationBean corsFilter() {
	UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
	CorsConfiguration config = new CorsConfiguration();
	config.setAllowCredentials(false);
	config.addAllowedOrigin("http://domain.com");
	config.addAllowedHeader("*");
	config.addAllowedMethod("*");
	source.registerCorsConfiguration("/**", config);
	FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
	bean.setOrder(0);
	return bean;
}

}


你可能感兴趣的:(springboot,spring,boot)