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.

Top Architect
Top Architect
Top Architect
Implementing CORS Cross‑Origin Requests in Java Backend (Spring MVC)

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.

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.

JavaspringCORSCross-Originfilter
Top Architect
Written by

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.

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.