为什么HttpServletRequest在collection.parallelStream()中为null

时间:2016-07-29 02:39:51

标签: java spring-boot

我使用的是spring-boot 1.2.7,我尝试在parallelStream().forEach(o -> addAddtionalData(id))中使用它时遇到了NullPointerException,但stream()没问题,我认为这可能是一个线程问题,但我可以& #39;解释得很好,有人可以帮我指导一下吗?

private void addAddtionalData(Long id){

    // request is null but not the first time loop in parallel stream
    HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    boolean isSecure = request.isSecure();    
    // some code 
}

例外:

[ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for 
servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException: null
java.lang.NullPointerException: null
     at com.app.service.QuoteService.setAdditionalData(QuoteService.java:103) ~[classes/:na]
     at com.app.service.QuoteService.lambda$getAllQuotes$41(QuoteService.java:80) ~[classes/:na]
     at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[na:1.8.0_60]
     at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374) ~[na:1.8.0_60]
     at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_60]
     at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291) ~[na:1.8.0_60]
     at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731) ~[na:1.8.0_60]
     at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) ~[na:1.8.0_60]
     at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) ~[na:1.8.0_60]
     at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) ~[na:1.8.0_60]
     at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) ~[na:1.8.0_60]

1 个答案:

答案 0 :(得分:1)

RequestContextHolder使用ThreadLocal来查找上下文对象。

  

Holder类以线程绑定 RequestAttributes对象的形式公开Web请求。

使用并行流意味着您的代码在不同的线程中运行,因此没有上下文对象。

在开始流处理之前,您应该获得isSecure值。