First Request must be generated by your browser by default as a contract of CORS. This request is addressed by Spring's CORS Processor due to the presence of preflight headers.
If Spring allows it by sending proper Headers then browser will generate your actual request which will be addressed by your rest controller.
Now if you still want to handle preflight request by yourself then you must extend CORSConfiguration class and override its methods.
Note: - Even if you do this then also your browser will raise two request.
First will be addressed by your custom overridden methods and second by your controller.
In general there is no need to define controller for OPTIONS as you will not need OPTIONS request in your application. It is automatically raised by browser if required[as per CORS Contract] and it will be handled by springs CORS Processor.
Configuring CORS (If you are not using Spring-security module) :
There are 3 ways
Using annotaion @Crossorigin [per rest-api or per rest controller
basis]
Using Global CORS Configuration
Extending CorsFilter
Way 1 (@CrossOrigin)
This annotation can be applied to either class or on method.
example :--
@RestController
@CrossOrigin(origins = {"http://localhost:8585"}, maxAge = 4800, allowCredentials = "false")
public class FetchOnPremData {
@RequestMapping(value = "/fetchData/{jiraid}", method = RequestMethod.OPTIONS)
public int options(@PathVariable String jiraid ,HttpServletResponse response) {
response.setHeader("Access-Control-Allow-Methods","GET,HEAD,POST");
response.setHeader("Allow", "HEAD,GET,PUT,OPTIONS");
response.setHeader("Access-Control-Allow-Origin","*");
return 234;
}
}
or on method :
@RestController
public class FetchOnPremData {
@CrossOrigin
@RequestMapping(value = "/fetchData/{jiraid}", method = RequestMethod.GET)
public int options(@PathVariable String jiraid ,HttpServletResponse response) {
// your code
return 234;
}
Way 2 : Global Cors Configuration
If you want to enable cors support for all of your rest controllers then use this option.
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}
Way 3 : Using CorsFilter
If you want greater control then you can can prefer this.
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
// This bean will override default cors filter
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
configuration.setAllowedMethods(Arrays.asList("GET","POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Configuring CORS (If you are using Spring-Security module) :
Then in addition to using any of the above mentioned ways you will have to add the following to your configuration :
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// by default uses a Bean by the name of corsConfigurationSource
.cors().and()
...
}
}
references :
Spring Security CORS Configuration documentation
Spring MVC CORS Configuration documentation