【问题标题】:Autowired Null Pointer Exception自动装配空指针异常
【发布时间】:2017-12-27 03:38:09
【问题描述】:

我有一个过滤器可以将请求保存到数据库。但我在自动装配字段上得到 NullPointerException:inboundRequestLogStore。

我已经尝试了来自 Using some beans in Filter bean class? (I've added SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext()); to the filter init method and defined a bean in my root-context.xml ) 的建议,现在它适用于 RequestLogFilter 类。但是,在 InboundRequestLogStore 类中,我有另一个自动连接的归档 logService 来将我的实体保存到 DB,现在我得到了 NullPointerEception。为什么我有 NPE 以及如何解决它?我在项目的其他部分有相同的服务/组件,它们自动连接服务没有任何问题。我只使用过滤器有问题。

@Component
public class RequestLogFilter implements Filter {

    @Autowired
    private InboundRequestLogStore inboundRequestLogStore;

    public RequestLogFilter() {

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
         SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext());
    }


    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest requestToCache = new ContentCachingRequestWrapper((HttpServletRequest) request);
         HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);
        chain.doFilter(request, responseCopier);
        responseCopier.flushBuffer();
        if (request.getAttribute(InboundRequestAspect.INBOUND_LOG_MARKER) != null) {

            InboundRequestLogRecord logRecord = new InboundRequestLogRecord();

                setters....

            inboundRequestLogStore.add(logRecord);
        }
    }
}

--

@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {

    private ConcurrentLinkedQueue<InboundRequestLogRecord> queue = new ConcurrentLinkedQueue<>();

    @Autowired
    private LogService logService;

    @Override
    public void afterPropertiesSet() throws Exception {
        reseterPool = new ScheduledThreadPoolExecutor(1);
        reseterPool.scheduleWithFixedDelay(new LogRequestSaveQueueTask(), startupDelay, sleepTimeout, TimeUnit.SECONDS);
    }   

    public InboundRequestLogStore() {

    }

    public void add(InboundRequestLogRecord logRequest) {
        queue.add(logRequest);
    }

    private class LogRequestSaveQueueTask implements Runnable {
        @Override
        public void run() {
            try {
                if (queue.size() > 0) {
                    List<InboundRequestLogRecord> logRequestList = new ArrayList<>();
                    InboundRequestLogRecord obj;
                    while((obj = queue.poll()) != null) {
                        logRequestList.add(obj);
                    }
                    if (!logRequestList.isEmpty()) {
                        logService.save(logRequestList);
                    }
                }
            } catch(Exception e) {
                logger.error(e.getMessage(), e);
            }
            }
    }
}

堆栈跟踪

java.lang.NullPointerException: null
    at com.my.project.services.log.InboundRequestLogStore$LogRequestSaveQueueTask.run(InboundRequestLogStore.java:71) [classes/:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_131]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:1.8.0_131]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:1.8.0_131]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:1.8.0_131]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [?:1.8.0_131]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [?:1.8.0_131]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_131]

-

    <context:component-scan base-package="com.my.project" />

-

    <bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />

如果使用 DelegatingFilterProxy 那么我得到 ​​p>

SEVERE: Servlet.service() for servlet [appServlet] in context with path [] threw exception
java.lang.NullPointerException
    at com.my.project.config.filter.RequestLogFilter.doFilter(RequestLogFilter.java:121)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

web.xml

<filter>
        <filter-name>requestLogFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>requestLogFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

根上下文.xml

<bean id="inboundRequestLogStore" class="com.my.project.services.log.InboundRequestLogStore" />   
<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter" />

组件(标有 bean 的 id)

@Component("inboundRequestLogStore")
public class InboundRequestLogStore implements InitializingBean {

-

@Component("requestLogFilter")
public class RequestLogFilter implements Filter {

RequestLogFilter 上的@Configurable 不起作用。

结果

ikettu,谢谢!

经过一些尝试,我实现了自动装配字段不可为空。 我已将 bean 添加到 root-context.xml

<bean id="requestLogFilter" class="com.my.project.config.filter.RequestLogFilter">
    <constructor-arg ref="inboundRequestLogStore"/>
</bean>

<bean id="inboundRequestLogStore" class="com.my.project.service.InboundRequestLogStore">
    <constructor-arg ref="logService"/>
</bean> 

<bean id="logService" class="com.my.project.service.LogService"> 
    <constructor-arg ref="entityManagerFactory"/> 
</bean>

在类中,我使用这样的参数创建了构造函数

private LogServic logService;

public InboundRequestLogStore(LogServic logService) {
    this.logService = logService;
} ....

在日志服务中

private EntityManagerFactory emf;

public void setEntityManagerFactory(EntityManagerFactory emf) {
    this.emf = emf;
}

但是当我尝试将我的实体保存到数据库时,什么都没有发生。如果我尝试刷新一批插入并释放内存

entityManager.flush();
entityManager.clear();

然后NotOpenedTransaction(像这样,我想不起来)异常发生了

我厌倦了所有并创建了一个拦截器。一切都完美无缺。如果有人可以解释过滤器的问题,请发表评论。

Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/root-context.xml</param-value>
    </context-param>

    <!-- Creates the Spring Container shared by all Servlets and Filters -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Processes application requests -->
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

<!--    <filter> -->
<!--        <filter-name>requestLogFilter</filter-name> -->
<!--        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> -->
<!--        if set this parameter to true then filter init & destroy methods will be called  -->
<!--        <init-param> -->
<!--            <param-name>targetFilterLifecycle</param-name> -->
<!--            <param-value>true</param-value> -->
<!--        </init-param> -->
<!--    </filter> -->
<!--    <filter-mapping> -->
<!--        <filter-name>requestLogFilter</filter-name> -->
<!--        <url-pattern>/*</url-pattern> -->
<!--    </filter-mapping> -->

</web-app>

【问题讨论】:

  • 请添加堆栈跟踪。组件扫描的配置和包名

标签: spring nullpointerexception autowired


【解决方案1】:

您现在很可能将 servlet 过滤器初始化为普通的 java 类,而不是初始化的 bean。

请使用DelegatingFilterProxy 将 spring bean 用作 serlvet 过滤器

查看文章https://dzone.com/articles/what-does-spring-delegatingfilterproxy-do

【讨论】:

  • 我也试过这个,我得到了 SEVERE: Servlet.service() for servlet [appServlet] 在路径 [] 的上下文中在 com.my.project.config 抛出异常 java.lang.NullPointerException。 filter.RequestLogFilter.doFilter(RequestLogFilter.java:121) at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
  • 如何从 servlet 初始化 spring 上下文?您是否正确设置了 ContextLoaderListener? docs.spring.io/spring/docs/current/spring-framework-reference/…
  • 我使用 ContextLoaderListener 和 contextConfigLocation 参数。我添加了完整的 web.xml
猜你喜欢
  • 2017-11-20
  • 2014-10-07
  • 2017-10-22
  • 2012-02-21
  • 2015-11-16
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
相关资源
最近更新 更多