自动连线的空指针异常 [英] Autowired Null Pointer Exception

查看:90
本文介绍了自动连线的空指针异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个过滤器,用于将请求保存到数据库.但是我在自动连线的字段:inboundRequestLogStore上得到了NullPointerException.

I have a filter to save requests to DB. But I get NullPointerException on autowired field: inboundRequestLogStore.

我已经尝试过从Filter bean类中使用一些bean的建议? (I've added SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, filterConfig.getServletContext()); to the filter init method and defined a bean in my root-context.xml ),现在它适用于RequestLogFilter类.但是,在InboundRequestLogStore类中,我有另一个自动连线的fileService,用于将实体保存到DB,现在,我得到了NullPointerEception.为什么我有NPE以及如何解决?我在项目的其他部分具有相同的服务/组件,并且它们可以自动连接服务,而不会出现任何问题.我仅使用过滤器时会遇到麻烦.

I've tried the suggestion from 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 ) and now it works for the RequestLogFilter class. But, in the InboundRequestLogStore class I have another autowired filed logService to save my entity to DB and now at this point I get NullPointerEception. Why I have the NPE and how to resolve it? I have the same services/components in another parts of my project and they autowires services without any problems. I have troubles only using the filter.

@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);
            }
            }
    }
}

StackTrace

StackTrace

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,那么我得到

If use DelegatingFilterProxy then I get

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>

root-context.xml

root-context.xml

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

组件(标有bean的ID)

Components (marked with bean's id)

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

-

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

@在RequestLogFilter上可配置不起作用.

@Configurable on the RequestLogFilter not working.

结果

ikettu ,谢谢!

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

after some attempts I've achieved autowired fields not to be nullable. I've added beans to the 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>

在类中,我使用此类参数创建了构造函数

In classes I've created constructors with params like this

private LogServic logService;

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

在LogService中

In the LogService

private EntityManagerFactory emf;

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

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

But when I tried to save my entity to DB nothing has happened. If I tried to flush a batch of inserts and release memory

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

然后发生NotOpenedTransaction(这样,我不介意)异常

then NotOpenedTransaction(like this, I can't call to mind) exception has occured

我对所有内容都感到厌倦,并创建了一个拦截器.并且所有的工作都是完美的.如果任何人都可以解释过滤器有什么问题,请发表评论.

I'm tired of all and have created an interceptor. And all works perfetcly. If anyone can explain what was the problem with the filter please comment.

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>

推荐答案

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

Most probably you now initialize servlet filter as normal java class and not as initialized bean.

请使用 DelegatingFilterProxy 用春豆做天鹅绒过滤器

Please use DelegatingFilterProxy to have spring beans as serlvet filters

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

这篇关于自动连线的空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆