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.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Implementing CORS Cross‑Origin Requests in Java Backend (Spring Boot)

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring BootCORSCross-OriginWeb Security
Java Architect Essentials
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.