Spring CORS example using @CrossOrigin – Spring Boot

Spring CORS example using @CrossOrigin – Spring Boot

Cross-Origin-Resource-Sharing (CORS) is a W3C specification which defines how a browser should be allowed using script to access different origin than the origin it has been served. With CORS, we can specify what kind of cross domain requests are authorized in a flexible way, instead of using some less secured and less powerful hacks like IFRAME or JSONP. In this tutorial, we’re gonna look at way to create a Spring Boot REST service with Spring CORS integration using @CrossOrigin annotation.

Related Articles:
Spring Boot – CORS Support using Java Config
Spring Boot – CORS Support using XML Config
AngularJs CrossSite HTTP Requests to SpringBoot RestAPIs

I. CORS Configuration using @CrossOrigin Annotation

1. On @RequestMapping-Annotated Method
@RestController
public class WebController {

	@CrossOrigin(origins = { "http://localhost:8484", "http://localhost:9000" }, maxAge = 6000)
	@RequestMapping("customers")
	public List getCustomers() {
		// ...
	}

	@CrossOrigin(origins = { "http://localhost:9000" }, allowCredentials = "false")
	@RequestMapping("data")
	public List getData() {
		// ...
	}

	@RequestMapping("cart")
	public Cart getCart() {
		// ...
	}
}

In the code above, CORS is not enabled for getCart() method. getCustomers() and getData() have different CORS configuration.

origins: specifies the URI that can be accessed by resource. “*” means that all origins are allowed. If undefined, all origins are allowed.

allowCredentials: defines the value for Access-Control-Allow-Credentials response header. If value is true, response to the request can be exposed to the page. The credentials are cookies, authorization headers or TLS client certificates. The default value is true.

maxAge: defines maximum age (in seconds) for cache to be alive for a pre-flight request. By default, its value is 1800 seconds.

We also have some attributes:
methods: specifies methods (GET, POST,…) to allow when accessing the resource. If we don’t use this attribute, it takes the value of @RequestMapping method by default. If we specify methods attribute value in @CrossOrigin annotation, default method will be overridden.

allowedHeaders: defines the values for Access-Control-Allow-Headers response header. We don’t need to list headers if it is one of Cache-Control, Content-Language, Expires, Last-Modified, or Pragma. By default all requested headers are allowed.

exposedHeaders: values for Access-Control-Expose-Headers response header. Server uses it to tell the browser about its whitelist headers. By default, an empty exposed header list is used.

2. On Controller
@CrossOrigin(origins = { "http://localhost:9000" }, maxAge = 3000)
@RestController
public class WebController {

	@RequestMapping("customers")
	public List getCustomers() {
		// ...
	}

	@RequestMapping("data")
	public List getData() {
		// ...
	}
}

If we use @CrossOrigin annotation on the Controller, all CORS Configuration of methods inside will be enabled.

3. On Both
@CrossOrigin(origins = { "http://localhost:9000" }, maxAge = 3000)
@RestController
public class WebController {

	@CrossOrigin(origins = { "http://localhost:8484" }, maxAge = 6000)
	@RequestMapping("customers")
	public List getCustomers() {
		// ...
	}

	@RequestMapping("data")
	public List getData() {
		// ...
	}
}

Spring will combine attributes from both to merge CORS configuration:
/customers:

@CrossOrigin(origins = { "http://localhost:8484" , "http://localhost:9000" }, maxAge = 6000)

/data:

@CrossOrigin(origins = { "http://localhost:9000" }, maxAge = 3000)

II. Practice

1. Technology

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.4.RELEASE
– Spring Boot: 1.5.4.RELEASE

2. Project Overview

spring-cors-structure

Dependency for Spring Boot Starter Web in pom.xml.

3. Step by step
3.1 Create Spring Boot project

Using Spring Tool Suite/Eclipse to create Project and add Dependencies to pom.xml file:


	org.springframework.boot
	spring-boot-starter-web

3.2 Create Data Model Classes
package com.javasampleapproach.cors.model;

public class Customer {

	private Long id;
	private String name;

	public Customer(Long id, String name) {
		this.id = id;
		this.name = name;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
3.3 Create Service
package com.javasampleapproach.cors.service;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.javasampleapproach.cors.model.Customer;

@Service
public class CustomerService {

	public List getCustomers() {
		
		List list = new ArrayList<>();
		list.add(new Customer(1L, "Jack"));
		list.add(new Customer(2L, "Adam"));
		list.add(new Customer(3L, "Kim"));
		
		return list;
	}
}
3.4 Create Controller
package com.javasampleapproach.cors.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.javasampleapproach.cors.model.Customer;
import com.javasampleapproach.cors.service.CustomerService;

@CrossOrigin(origins = { "http://localhost:9000" }, maxAge = 3000)
@RestController
public class WebController {

	@Autowired
	private CustomerService service;

	@CrossOrigin(origins = { "http://localhost:8484" }, maxAge = 6000)
	@RequestMapping("customers")
	public List getCustomers() {

		List list = service.getCustomers();
		return list;
	}

	@RequestMapping("data")
	public List getData() {

		List list = service.getCustomers();
		list.forEach(item -> item.setName(item.getName().toUpperCase()));
		
		return list;
	}
}
3.5 Run & Check Result

– Config maven build:
clean install
– Run project with mode Spring Boot App and port 8080.
– Create Client Application (stored in folder webapps/Cors of Apache Tomcat):

$(document).ready(function() {
	$.ajax({
		url: "http://localhost:8080/customers"
	}).then(function(data) {
	  var items = [];
	  $.each( data, function( key, val ) {
		items.push("Id: "+val.id +", Name: "+val.name+"
"); }); $('.result').append(items); }); });


    
        Spring Boot - CORS
        
        
    
    
        

– Deploy client project on Tomcat with port 8484:

Send Request on Browser:
http://localhost:8484/Cors/index.html
Result:

Id: 1, Name: Jack
Id: 2, Name: Adam
Id: 3, Name: Kim

Clear Browser Cache, then modify data.js file by changing url to:

$.ajax({
	url: "http://localhost:8080/data"
})

Send Request on Browser:
http://localhost:8484/Cors/index.html
Result: Browser shows nothing.

– Deploy client project on Tomcat with port 9000:

Clear Browser Cache, then send Request on Browser:
http://localhost:9000/Cors/index.html
Result:

Id: 1, Name: JACK
Id: 2, Name: ADAM
Id: 3, Name: KIM

III. Source Code

SpringBootCORS
Cors

0 0 votes
Article Rating
Subscribe
Notify of
guest
886 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments