I have a Spring Boot Rest application where I need to allow CORS requests.
Requests use the common path <host>:<port>/api/...
and so far I only have two resources:
package my.controllers;
@RestController
@RequestMapping(path="/", produces="application/json")
public class DataController {
@GetMapping("/")
public ApiResponse<Map<String, Object>> getValues() {
// ...
}
@GetMapping("/sub")
public ApiResponse<String> getValuesSub() {
// ...
}
Here are two example requests from the Javascript client running at http://localhost:3000/
:
fetch('http://localhost:2001/api/').then(/* ... */);
fetch('http://localhost:2001/api/sub')).then(/* ... */);
If I add the @CrossOrigin(origins = "*")
annotation to the controller, CORS requests work fine; if I replace it implementing WebMvcConfigurer.addCorsMappings()
though:
@ComponentScan(basePackages={ "my.controllers" })
@Configuration
public class WebappConfig implements WebMvcConfigurer {
// ...
@Override
public void addCorsMappings(CorsRegistry registry) {
LogManager.getLogger(getClass()).info("CORS settings");
registry.addMapping("/api/**").allowedOrigins("*").maxAge(3600);
}
CORS requests fail, and I get (in Firefox, Chrome shows a similar error message):
CORS header 'Access-Control-Allow-Origin' missing
I see the log entry, so the method is surely invoked.
I've seen other questions mentioning Spring Security or Spring Data (I use none), so here's my dependencies list in case I'm missing something:
- spring-boot-starter-web
- spring-boot-starter-tomcat
- spring-boot-starter-log4j2
- spring-boot-configuration-processor
- commons-lang3
- commons-beanutils
What's the right way to set CORS settings to the whole application, without using the @CrossOrigin
annotation on each controller?
UPDATE
I'm initializing a Rest servlet like this:
@Bean
public ServletRegistrationBean<DispatcherServlet> registerDispatcherServlet(DispatcherServlet servlet) {
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(servlet);
servlet.setContextConfigLocation("");
registration.addUrlMappings("/api/*");
registration.setLoadOnStartup(1);
return registration;
}
The logs says:
Servlet dispatcherServlet mapped to [/api/*]
Servlet dispatcherServlet mapped to [/]
Servlet dispatcherServlet was not registered (possibly already registered?)
Could it be that the given Cors settings are going to the mentioned unregistered servlet?