Implementing CORS Cross‑Origin Requests in Java Backend (Spring Boot)
This article explains why browsers enforce the Same‑Origin Policy, defines cross‑origin requests, lists the restrictions of non‑same‑origin access, and provides five practical ways—global filter, WebMvcConfigurer, @CrossOrigin annotation, manual header setting, and a custom filter—to enable CORS in Java Spring Boot applications, complete with code examples.
1. Why the cross‑origin problem occurs
Browsers enforce the Same‑Origin Policy, a core security mechanism that blocks JavaScript from interacting with resources that do not share the same protocol, host, and port. Without this policy, many browser functions would be unsafe.
2. What is cross‑origin
A request is considered cross‑origin when its protocol, domain, or port differs from the current page’s URL.
3. Non‑same‑origin restrictions
Cannot read cookies, LocalStorage, or IndexedDB of another origin.
Cannot access the DOM of a page from another origin.
Cannot send AJAX requests to a different origin.
4. Ways to implement CORS in a Java backend
For CORS requests, the following approaches are available:
Return a new CorsFilter bean (global configuration).
Override WebMvcConfigurer (global configuration).
Use the @CrossOrigin annotation (local configuration).
Manually set response headers via HttpServletResponse (local configuration).
Implement a custom filter to add CORS headers (local configuration).
Note:
The CorsFilter, WebMvcConfigurer, and @CrossOrigin approaches require Spring MVC 4.2+ (Spring Boot 1.3+).
The first two methods apply globally, while the latter three are local; local settings can override global rules, so @CrossOrigin offers fine‑grained control.
All methods ultimately modify the response headers to satisfy the browser’s CORS requirements.
Example 1: Global CorsFilter
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px">@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
// 1. Create CORS configuration
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*"); // allow any origin
config.setAllowCredentials(true); // allow cookies
config.addAllowedMethod("*"); // allow any HTTP method
config.addAllowedHeader("*"); // allow any header
config.addExposedHeader("*");
// 2. Register configuration for all paths
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
// 3. Return the filter
return new CorsFilter(source);
}
}
</code>Example 2: Global WebMvcConfigurer
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px">@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.exposedHeaders("*");
}
}
</code>Example 3: Using @CrossOrigin (local)
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px">@RestController
@CrossOrigin(origins = "*")
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "hello world";
}
}
</code>On a method level, the annotation can be applied directly:
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px">@RequestMapping("/hello")
@CrossOrigin(origins = "*")
public String hello() {
return "hello world";
}
</code>Example 4: Manually setting response headers (local)
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px">@RequestMapping("/index")
public String index(HttpServletResponse response) {
response.addHeader("Access-Allow-Control-Origin", "*");
return "index";
}
</code>Example 5: Custom filter (local)
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px">package com.mesnac.aop;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component
public class MyCorsFilter implements Filter {
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-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
chain.doFilter(req, res);
}
public void init(FilterConfig filterConfig) {}
public void destroy() {}
}
</code>Register the filter in web.xml:
<code style="padding: 16px; color: #abb2bf; font-family: Operator Mono, Consolas, Monaco, Menlo, monospace; font-size: 12px"><!-- CORS filter START -->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>com.mesnac.aop.MyCorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- CORS filter END -->
</code>For a complete Spring Boot tutorial, see https://blog.didispace.com/spring-boot-learning-2x/ .
All methods achieve the same goal: adding the necessary response headers so that browsers allow cross‑origin access.
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.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
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.
