【问题标题】:Exception instantiating filter in Spring MVC web-appSpring MVC web-app中的异常实例化过滤器
【发布时间】:2013-12-02 21:39:07
【问题描述】:

我需要在使用 Spring MVC 实现的 RESTful 服务中启用跨域资源共享。该服务工作正常,但现在我需要访问另一个域的资源。

我发现一些帖子建议在我的网络应用中添加过滤器。所以我添加了这部分:

过滤器类

package org.canvassservice.filters;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.filter.OncePerRequestFilter;

public class CorsFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request,
            HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        response.addHeader("Access-Control-Allow-Origin", "*");
        if (request.getHeader("Access-Control-Request-Method") != null
                && "OPTIONS".equals(request.getMethod())) {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Methods",
                    "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers",
                    "X-Requested-With,Origin,Content-Type, Accept");
        }
        filterChain.doFilter(request, response);
    }

}

在 web.xml 中

<filter>
    <filter-name>corsFilter</filter-name>
    <filter-class>org.springframework.web.filter.OncePerRequestFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>corsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

application.context

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <context:annotation-config />

    <context:component-scan base-package="org.canvassservice.controllers" />

    <mvc:annotation-driven />

    <bean id="corsFilter" class="org.canvassservice.filters.CorsFilter" />

</beans>

但是当我运行我的应用程序时,我得到了这个异常(在 Tomcat 日志中):

GRAVE: Exception starting filter corsFilter java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:30)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:355)
    at java.lang.Class.newInstance(Class.java:308)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:115)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4071)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4725)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

没有解释清楚的原因。对这个问题有任何想法吗?


更新

我尝试使用DelegatingFilterProxy 代替OncePerRequestFilter,在application.context 中声明过滤器bean,但抛出了一个新异常:

GRAVE: Exception starting filter corsFilter
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'corsFilter' is defined
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1108)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)
    at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:323)
    at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235)
    at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:194)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:295)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:422)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:115)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4071)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4725)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)

【问题讨论】:

    标签: java exception servlets spring-mvc filter


    【解决方案1】:

    这不会在过滤器中提供 IOC 可用性,请使用

    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    

    【讨论】:

      【解决方案2】:

      如果您指定,您不能期望创建 CorsFilter 实例

      <filter>
          <filter-name>corsFilter</filter-name>
          <filter-class>org.springframework.web.filter.OncePerRequestFilter</filter-class>
      </filter>
      

      您专门告诉容器实例化OncePerRequestFilter

      您提出的解决方案有效

      <filter>
          <filter-name>corsFilter</filter-name>
          <filter-class>org.canvassservice.filters.CorsFilter</filter-class>
      </filter>
      

      容器将实例化CorsFilter 实例并将其注册为Filter。但是,您将无法利用 Spring 的生命周期事件和注入,因为该实例不是 Spring 托管 bean。

      相反,如果您需要所有设置魔法,您可以使用DelegatingFilterProxyDelegatingFilterProxy 代表 到 Spring ApplicationContext 中定义的 Filter bean。

      您可以使用名称为targetBeanName 的过滤器&lt;init-param&gt; 来指定要委托给的bean 的ID。如果不指定,它将使用&lt;filter-name&gt;中定义的名称。

      【讨论】:

      • 所以CorsFilter 应该扩展DelegatingFilterProxy 而不是OncePerRequestFilter
      • @davioooh 不。保持原样。只需指定 bean 的名称。而不是为OncePerRequestFilter 设置一个&lt;filter&gt; 条目,而是为DelegatingFilterProxy 设置一个。
      • 现在我得到了一个新的异常GRAVE: Exception starting filter corsFilter org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'corsFilter' is defined。注意我在application.context 中声明了过滤器 bean
      • @davioooh 你能把你剩下的web.xml 贴出来吗?我认为它可能在错误的上下文中寻找。
      • 你说得对,我在错误的上下文中声明了我的 bean!非常感谢!
      【解决方案3】:

      我解决了用具体实现替换过滤器类的问题:

      <filter>
          <filter-name>corsFilter</filter-name>
          <filter-class>org.canvassservice.filters.CorsFilter</filter-class>
      </filter>
      

      我还从 application.context 文件中删除了 bean 声明。

      我不知道这是否是解决此问题的最佳方法,但它确实有效。

      【讨论】:

        猜你喜欢
        • 2016-11-19
        • 1970-01-01
        • 2017-04-27
        • 1970-01-01
        • 2016-05-27
        • 2014-05-20
        • 1970-01-01
        • 2013-04-05
        • 1970-01-01
        相关资源
        最近更新 更多