Mastering CORS in Spring Boot: Simple Configurations to Eliminate Cross‑Origin Errors
This article explains the Same Origin Policy, introduces the CORS standard, details simple and preflight request handling, lists essential response headers, and provides three practical Spring Boot solutions—including global configuration, a servlet filter, and the @CrossOrigin annotation—to resolve cross‑origin issues.
Front‑back separation makes CORS a common problem; this guide shows how to solve it in Spring Boot.
Problem Background
Same Origin Policy (SOP) restricts client scripts to resources from the same protocol, host, and port. If any of these differ, the browser treats the request as cross‑origin and blocks it.
CORS Overview
CORS (Cross‑Origin Resource Sharing) is a W3C standard that allows browsers to make XMLHttpRequest or Fetch calls to a different origin when the server explicitly permits it. The browser adds the necessary headers automatically; the server must implement the CORS interface.
Browsers classify CORS requests into simple requests and non‑simple (preflight) requests.
Simple vs Non‑Simple Requests
Simple requests (GET, HEAD, POST) with only the following headers are sent directly with an Origin header:
Accept
Accept‑Language
Content‑Language
Last‑Event‑ID
Content‑Type (only application/x-www-form-urlencoded, multipart/form-data, or text/plain)
Any request that does not meet these criteria triggers a preflight OPTIONS request, where the browser asks the server which methods and headers are allowed.
Response Headers
Access-Control-Allow-Origin : required; either the request’s Origin value or * to allow any domain.
Access-Control-Allow-Methods : required; a comma‑separated list (or *) of HTTP methods the server supports.
Access-Control-Expose-Headers : optional; lists additional response headers that JavaScript can read.
Access-Control-Allow-Credentials : optional; boolean indicating whether cookies may be sent.
Access-Control-Max-Age : optional; caches the preflight response for the given number of seconds.
If you notice an OPTIONS request for every call, configure Access-Control-Max-Age to reduce preflight traffic.
Solutions
Method 1: Global configuration with WebMvcConfigurer
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}Older tutorials use the now‑deprecated WebMvcConfigurerAdapter; with Spring 5 you can implement WebMvcConfigurer directly.
Method 2: Servlet filter
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "CorsFilter")
@Configuration
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
chain.doFilter(req, res);
}
}This approach writes the necessary headers directly into the response; only one of the first two methods is needed.
Method 3: @CrossOrigin annotation
public class GoodsController {
@CrossOrigin(origins = "http://localhost:4000")
@GetMapping("goods-url")
public Response queryGoodsWithGoodsUrl(@RequestParam String goodsUrl) throws Exception {}
}The annotation can be placed on a class or method, giving fine‑grained control over CORS for individual endpoints.
All three methods are valid; the one closest to the request (e.g., method‑level annotation) takes precedence, similar to CSS specificity.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
