Java 使用CompletableFuture时,HttpServletRequest标头将消失
首先,我为这样一个含糊不清的问题道歉。我不熟悉Java中的异步编程(因此,CompletableFuture),我正在尝试使用Spring的Java 使用CompletableFuture时,HttpServletRequest标头将消失,java,asynchronous,servlets,completable-future,Java,Asynchronous,Servlets,Completable Future,首先,我为这样一个含糊不清的问题道歉。我不熟悉Java中的异步编程(因此,CompletableFuture),我正在尝试使用Spring的@Async功能来处理它 我有以下AsyncConfig.java @Configuration public class AsyncConfiguration { private static final Logger LOG = LogManager.getLogger(AsyncConfiguration.class); @Bean
@Async
功能来处理它
我有以下AsyncConfig.java
@Configuration
public class AsyncConfiguration {
private static final Logger LOG = LogManager.getLogger(AsyncConfiguration.class);
@Bean("asyncExecutor")
public Executor asyncExecutor() {
LOG.info("Configuring ASYNC Executor");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(1);
executor.setMaxPoolSize(2);
executor.setQueueCapacity(2);
executor.setThreadNamePrefix("AsyncThread--");
executor.initialize();
LOG.info("ASYNC Executor Configuration Complete");
return executor;
}
}
现在我有两个过滤器,ApiUsageLimitFilter带@Order(1)
和RequestResponseLoggingFilter带@Order(2)
在ApiUsageLimitFilter.java
的doFilter
中,我有以下代码:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
LOG.info("API Filter Request handled by Thread {} -> {}", Thread.currentThread().getName(),
Thread.currentThread().getId());
final HttpServletRequest httpServletRequest = HttpServletRequest.class.cast(request);
HttpServletResponse httpServletResponse = HttpServletResponse.class.cast(response);
try {
LOG.info("Checking usgae limit for IP: {}", httpServletRequest.getHeader("X-Real-IP"));
apiUsageMonitorService.isAllowed(httpServletRequest) //Some method that returns a CompletableFuture<Boolean>
.thenCompose((allowed) -> {
if (allowed.equals(Boolean.TRUE)) {
LOG.info("IP: {} allowed", httpServletRequest.getHeader("X-Real-IP")); // Value is NULL
try {
chain.doFilter(httpServletRequest, httpServletResponse);
} catch (IOException | ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} else {
LOG.warn("IP: {} reached its usage limit. Blocking any further calls",
httpServletRequest.getHeader("X-Real-IP"));
return apiUsageMonitorService.remainingTTL(httpServletRequest);
}
}).thenAccept((remainingTTL) -> {
System.out.println("This gets executed");
if (remainingTTL != null) {
System.out.println("SOme of this gets executed");
try {
ApiResponse errorResponse = new ApiResponse();
errorResponse.setStatus(ApiRequestStatus.FAILURE);
errorResponse.setMessage(
"You have reached the API usage limit. Only 10 requests allowed per hour. Please try after the time specified in Retry-After header");
errorResponse.setErrorCode(ApiRequestErrorCode.API_USAGE_LIMIT_REACHED);
String errorResponseString = getResponseAsString(errorResponse);
LOG.info("Error response as String:{}", errorResponseString);
httpServletResponse.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
Long remainingSeconds = TimeUnit.MILLISECONDS.toSeconds(remainingTTL);
httpServletResponse.setHeader("Retry-After", remainingSeconds.toString() + " seconds");
httpServletResponse.getWriter().write(errorResponseString);
} catch (Exception e) {
// TODO: handle exception
}
}
});
这里怎么了?是不是当
CompletableFuture
完成时,请求对象早已消失,因为过滤器实现了同步方法?如果是,我如何处理这个问题?我必须以异步方式使用它在调用异步lambda之前,您是否尝试获取头值?无论如何,恐怕您需要调用request.getAsyncContext()并实现AsyncListener才能使异步逻辑工作。在调用async lambda之前,您是否尝试获取头值?无论如何,恐怕您需要调用request.getAsyncContext()并实现AsyncListener以使异步逻辑工作。
i.turls.lib.filters.ApiUsageLimitFilter : API Filter Request handled by Thread http-nio-8080-exec-3 -> 58
2020-02-23 23:12:53.721 INFO 28774 --- [nio-8080-exec-3] i.turls.lib.filters.ApiUsageLimitFilter : Checking usgae limit for IP: 122.168.23.274
2020-02-23 23:12:53.721 INFO 28774 --- [ AsyncThread--1] i.t.l.s.i.ApiUsageMonitorServiceImpl : Running Async Method on Thread AsyncThread--1 -> 70
2020-02-23 23:12:53.721 INFO 28774 --- [ AsyncThread--1] i.t.l.s.i.ApiUsageMonitorServiceImpl : Checking API usage for IP: 122.168.23.274
2020-02-23 23:12:53.729 INFO 28774 --- [ AsyncThread--1] i.t.l.s.i.ApiUsageMonitorServiceImpl : Creating new entry with IP 122.168.23.274
2020-02-23 23:12:53.738 INFO 28774 --- [ AsyncThread--1] i.turls.lib.filters.ApiUsageLimitFilter : IP: null allowed