Implementing CORS Cross‑Origin Requests in Java Backend (Spring MVC)
This article explains why browsers enforce same‑origin restrictions, defines cross‑origin requests, lists the limitations of non‑same‑origin interactions, and presents five practical Java backend solutions—including a global CorsFilter bean, WebMvcConfigurer override, @CrossOrigin annotation, manual response headers, and a custom filter—complete with code examples.
Cross-Origin Resource Sharing (CORS) issues arise because browsers enforce the Same‑Origin Policy, which blocks JavaScript from interacting with resources that have a different protocol, host, or port.
When any of these three components differ between the request URL and the current page, the request is considered cross‑origin.
Non‑same‑origin restrictions include:
Inability to read cookies, LocalStorage, IndexedDB from another origin.
Inability to access the DOM of a non‑same‑origin page.
Inability to send AJAX requests to a non‑same‑origin address.
Java backend provides several ways to enable CORS:
Register a global CorsFilter bean.
Implement WebMvcConfigurer and override addCorsMappings.
Use the @CrossOrigin annotation on controllers or methods.
Manually set response headers via HttpServletResponse.
Create a custom filter (e.g., MyCorsFilter) and configure it in web.xml.
Below are the essential code snippets for each method.
1. Global CorsFilter
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
//1. Add CORS configuration
CorsConfiguration config = new CorsConfiguration();
// Allowed origins
config.addAllowedOrigin("*");
// Allow credentials (cookies)
config.setAllowCredentials(true);
// Allowed methods
config.addAllowedMethod("*");
// Allowed headers
config.addAllowedHeader("*");
// Exposed headers
config.addExposedHeader("*");
//2. Register mapping
UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
corsConfigurationSource.registerCorsConfiguration("/**", config);
//3. Return new CorsFilter
return new CorsFilter(corsConfigurationSource);
}
}2. WebMvcConfigurer
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowCredentials(true)
.allowedOrigins("*")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
}3. @CrossOrigin annotation
@RestController
@CrossOrigin(origins = "*")
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "hello world";
}
}
// Method‑level example
@RequestMapping("/hello")
@CrossOrigin(origins = "*")
//@CrossOrigin(value = "http://localhost:8081") // specific IP
public String hello() {
return "hello world";
}4. Manual response headers
@RequestMapping("/index")
public String index(HttpServletResponse response) {
response.addHeader("Access-Allow-Control-Origin", "*");
return "index";
}5. Custom filter
package com.mesnac.aop;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
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() {}
}
// web.xml configuration
<!-- CORS 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 END -->Reference links are provided for further reading.
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.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn 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.
