I have my Spring MVC application configured to use CORS as such:
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
This works fine for successful requests however when an exception is thrown and is picked up by my error handler, CORS headers are not added.
@ControllerAdvice
public class ApiErrorHandler {
@ExceptionHandler(value = HttpClientErrorException.class)
public ResponseEntity badRequest(Exception ex)
{
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ErrorBodyWrapper.wrapErrorInJson(ex.getMessage()));
}
}
Is there a reason CORS does not work for error handlers?
Thanks
same with you.
@Configuration
public class ManagerWarInit extends WebMvcConfigurerAdapter {
...
private static final String[] SUPPORT_METHODS = new String[] {
HttpMethod.HEAD.name(),
HttpMethod.OPTIONS.name(),
HttpMethod.GET.name(),
HttpMethod.POST.name(),
HttpMethod.PUT.name(),
HttpMethod.DELETE.name()
};
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods(SUPPORT_METHODS)
.exposedHeaders("Set-Cookie");
}
}
and globalException
@ControllerAdvice
public class ManagerGlobalException {
// @CrossOrigin(...)
@ExceptionHandler(NotLoginException.class)
public void noLogin(NotLoginException e, HttpServletResponse response)
throws IOException {
if (LOG.isDebugEnabled())
LOG.debug(e.getMessage());
if (RequestUtils.isAjaxRequest()) {
RequestUtils.toJson(notLogin(), response);
} else {
response.sendRedirect("hxxp://www.xxx.com");
}
}
}
but Cross-domain calls error by Browser(Chrome etc.)
XMLHttpRequest cannot load hxxp://127.0.0.1:8080/url... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'hxxp://127.0.0.1:3000' is therefore not allowed access.
Trying to add a @CrossOrigin
annotation on ExceptionHandler still has this error
I am dealing with this now
@ControllerAdvice
public class ManagerGlobalException {
@ExceptionHandler(NotLoginException.class)
public String notLogin(NotLoginException e) throws IOException {
if (LOG.isDebugEnabled())
LOG.debug(e.getMessage());
if (RequestUtils.isAjaxRequest()) {
return "forward:/not-login";
} else {
return "redirect:hxxp://www.xxx.com";
}
}
}
add a mapping
@RestController
public class IndexController {
@RequestMapping(value = "/not-login")
public JsonResult notLogin() {
return JsonResult.notLogin();
}
}
I think by default the only method added to the mapping is GET,
In your "addCorsMappings" try to specify the methods you want to add the header to
registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
Using Spring CorsFilter
can resolve this problem.
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(0);
return bean;
}