【问题标题】:rest service works when deployed in Eclipse but not in TomcatREST 服务在 Eclipse 中部署时有效,但在 Tomcat 中无效
【发布时间】:2016-08-04 18:18:00
【问题描述】:

我用 Spring 实现了 REST Web 服务。当我将它作为 Spring Boot 应用程序部署在 Eclipse 中时,它可以工作。但是,当我将它部署在同一台机器上的 Tomcat 7 中时,它不起作用。错误信息如下:

XMLHttpRequest cannot load http://localhost:8080/ristoreService/oauth/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8081' is therefore not allowed access.

我的 CORS 过滤器如下所示:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CORSFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8081");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, "
                + "Origin,Access-Control-Request-Method, Access-Control-Request-Headers, Authorization");
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

如果我注释掉response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8081");,我仍然会得到同样的错误。即使我在 Eclipse 中部署,如果没有这条线,它也不会工作。为什么部署在同一个ip不同环境下会有不同的表现?

编辑: 我用休息客户端测试器“CocoaRestClient”测试了网址http://localhost:8080/ristoreService/oauth/token,得到了404。所以我编了一个显然不存在的网址http://localhost:8080/xxxxx并在UI(angularjs)中运行它,再次得到CORS错误。我认为这个错误有点误导,毕竟是404。但是为什么在Tomcat的webapps下以ristoreService.war的名称成功部署war时它会抱怨找不到?

【问题讨论】:

  • @Ulises 在我的帖子中提到了Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8081' is therefore not allowed access.

标签: eclipse spring rest tomcat xmlhttprequest


【解决方案1】:

尝试使用 FilterRegistrationBean。在 Java Config 中看起来像这样:

@Bean
public FilterRegistrationBean authorizationFilter(){
    FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
    filterRegBean.setFilter(authorizationFilter);
    List<String> urlPatterns = new ArrayList<String>();
    urlPatterns.add("/v1/*");
    filterRegBean.setUrlPatterns(urlPatterns);
    return filterRegBean;
}

您为什么不使用 Spring Boot 的 CORS 功能?它已经支持开箱即用,您只需对其进行配置。您可以像这样全局启用它:

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*");
            }
        };
    }

【讨论】:

  • Spring Boot 自己的 corsConfigurer 应该和我的 CORSFilter 一样工作,对吧?我在我的应用程序中添加了 CorsMapping,但仍然出现同样的错误。只是意识到这个错误可能不是它的意思。因为我在休息客户端测试器中测试了相同的 url 并得到 404。毕竟这可能不是 CORS 问题。但为什么是 404?
  • 您可能没有在 tomcat 中设置正确的上下文路径。你是如何配置tomcat的?
  • 我没有为上下文路径做任何配置。一切都是默认的。
  • 这是从哪里来的? ristoreService
  • 什么意思?我创建的 Web 服务使用名称 ristoreSerivice.war 进行部署。我将战争复制到tomcat下的webapps dir。我没有web.xml。会不会是这个原因?
【解决方案2】:

根据How to deploy Spring Boot application,我必须做主应用来扩展SpringBootServletInitializer。一旦我添加了它,它就可以工作了。

【讨论】:

  • 好的,是的,我认为这是理所当然的,我想我可以问。
  • 如果不是秘密,你能通过 git 分享这个解决方案吗?
【解决方案3】:

为了解决 CORS 问题,我使用了@CrossOrigin。而且我没有实现自己的 CORS 过滤器。无论如何,spring 已经提供了很少的addition solutions for CORS issue

如果你只需要你的过滤器,你可以这样使用它:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.addFilterBefore(yourFilter);
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2017-08-31
    相关资源
    最近更新 更多