我简化了我们的生产应用程序以重现错误。
这是一个用于计算传入请求计数的演示应用程序。
当我调试项目时,我可以看到Null Pointer Exception
被抛出
manager.incrementRequestCounter(url)
类中的CounterMetricsFilter
行如下所示。那是因为我autowired
的经理是NULL。
但是,autowired
中的同一位经理CounterController
不为空。我通过调试器确认了这一点。
这里有什么问题?可以filters
不是beans
吗?如何在web.xml
应用程序中使用Spring MVC
来实现此功能。
由于
Controller
@Controller
@RequestMapping("/counter")
public class CounterController {
@Autowired
CounterManager manager;
@RequestMapping(value = "/counterMetrics", method = RequestMethod.GET)
@ResponseBody
public Map getFeatureStatus(final HttpServletResponse response) {
System.out.println("returning feautre status");
return manager.getQueryCounts();
}
}
Manager
@Service
public class CounterManager {
private Map<String,Integer> queryCounts =
new ConcurrentHashMap<String,Integer>(1000);
int threshold;
long timestamp;
@Autowired
public CounterManager(@Value("${healthThreshold: 10}")
int threshold) {
this.threshold = threshold * MEGABYTES;
this.timestamp = System.currentTimeMillis();
}
public void incrementRequestCounter(String urlPath){
Integer oldVal, newVal;
do {
oldVal = queryCounts.get(model);
newVal = (oldVal == null) ? 1 : (oldVal + 1);
} while (!queryCounts.replace(model, oldVal, newVal));
}
public Map<StatusUrlModel, Integer> getQueryCounts() {
return queryCounts;
}
}
Filter
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class CounterMetricsFilter extends OncePerRequestFilter {
@Autowired
CounterManager manager;
public CounterMetricsFilter(){
}
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain chain) throws ServletException,
IOException {
String path = new UrlPathHelper().getPathWithinApplication(request);
try {
chain.doFilter(request, response);
}
finally {
recordMetrics(request, path);
}
}
private void recordMetrics(String path) {
try {
manager.incrementRequestCounter(url);
}
catch (Exception ex){
System.out.println("exception is thrown " + ex.getCause());
ex.printStackTrace();
}
}
}
更新:
在控制台上打印以下内容:
exception is thrown null
(来自上面的CounterMetricsFilter)。
堆栈跟踪:
java.lang.NullPointerException
at com.myapp.filter.CounterMetricsFilter.recordMetrics(CounterMetricsFilter.java:81)
at com.myapp.filter.CounterMetricsFilter.doFilterInternal(CounterMetricsFilter.java:63)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.myapp.filter.RequestWrapperFilter.doFilter(RequestWrapperFilter.java:24)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.myapp.filter.GCCORSFilter.doFilter(GCCORSFilter.java:37)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:3)
过滤器由servlet容器实例化,因此@Autowired
无效。
您可以使用DelegatingFilterProxy
让Spring实例化过滤器:
<filter>
<filter-name>counterMetricsFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
答案 1 :(得分:-1)
我认为您需要删除默认构造函数并仅保留具有@Autowired
依赖关系的构造函数。否则,@Component
很可能是使用默认构造函数创建的,并且依赖项不是@Autowired
。
即。只需删除这段代码:
public CounterMetricsFilter(){
}