How to Solve CORS Issues in Spring Boot: Three Practical Configuration Methods

This article explains why CORS problems arise in front‑end/back‑end separation, introduces the CORS standard and request types, details the required response headers, and provides three concrete Spring Boot solutions—including global configuration, filter‑based handling, and the @CrossOrigin annotation—complete with code examples and migration notes.

ITPUB
ITPUB
ITPUB
How to Solve CORS Issues in Spring Boot: Three Practical Configuration Methods

Background

In front‑end/back‑end separated architectures the browser enforces the Same Origin Policy (SOP), which blocks requests to a different protocol, host or port. Cross‑Origin Resource Sharing (CORS) is a W3C standard that allows a server to opt‑in to cross‑origin requests by sending specific HTTP response headers.

CORS Overview

The browser automatically adds an Origin header to every XMLHttpRequest or fetch call. If the server returns the appropriate CORS headers, the browser permits the response to be accessed by JavaScript; otherwise a CORS error is raised.

Simple vs. Non‑Simple Requests

Simple request : GET, HEAD, or POST where the request headers are limited to Accept, Accept-Language, Content-Language, Last-Event-ID and Content-Type (only application/x-www-form-urlencoded, multipart/form-data or text/plain). The browser sends only the Origin header.

Non‑simple request : Any request that does not meet the simple criteria. The browser first sends a pre‑flight OPTIONS request to verify that the target server allows the requested method and headers. The actual request is sent only after a successful pre‑flight response.

Key CORS Response Headers

Access-Control-Allow-Origin

– required; either the exact value of the request’s Origin header or * to allow any origin. 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 via getResponseHeader(). Access-Control-Allow-Credentials – optional; true to allow cookies and HTTP authentication information. Access-Control-Max-Age – optional; number of seconds the pre‑flight response may be cached, reducing the number of OPTIONS requests.

Spring Boot CORS Configuration Options

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("*");
    }
}

This registers a CORS mapping for every endpoint. Since Spring 5 the WebMvcConfigurerAdapter class is deprecated; implementing WebMvcConfigurer directly is sufficient because default methods are provided by Java 8.

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);
    }
}

The filter adds the required CORS headers to every response. It works independently of Spring MVC’s built‑in CORS handling and is useful when a lightweight, servlet‑level solution is preferred.

3. @CrossOrigin annotation

public class GoodsController {
    @CrossOrigin(origins = "http://localhost:4000")
    @GetMapping("goods-url")
    public Response queryGoodsWithGoodsUrl(@RequestParam String goodsUrl) throws Exception {}
}

Applying @CrossOrigin on a controller class or on individual handler methods provides fine‑grained control. The annotation can be placed on any Spring MVC handler (class or method) and overrides global settings for the annotated element.

Practical Tips

Only one of the three approaches needs to be active; if multiple are present, the most specific configuration (nearest to the handler) wins, similar to CSS specificity.

When every request triggers a pre‑flight, configure Access-Control-Max-Age to cache the result and reduce network overhead.

Reference implementation and best‑practice examples are available at:

https://github.com/javastacks/spring-boot-best-practice

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.

BackendConfigurationCORSSpring MVCspring-boot
ITPUB
Written by

ITPUB

Official ITPUB account sharing technical insights, community news, and exciting events.

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.