У меня проблема с продолжительностью жизни RequestAttributes при использовании их в потоках, которые не являются потоками запроса.
У меня есть приложение, которое выполняет некоторые операции через соединение websockets (STOMP) во время HTTP-запроса.Я реализовал код обработки STOMP, используя StompFrameHandler , который при получении нового кадра вызывает метод handleFrame () в выделенном потоке.Код в этом методе (не запущенный в потоке запроса) должен получить доступ к RequestAttributes.
public class DataFrameHandler implements StompFrameHandler{
@Override
public void handleFrame(StompHeaders headers, Object payload) {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
// The following line throws IllegalStateException when accessed during the second request...
Object attribute = attributes.getAttribute("attributeName", RequestAttributes.SCOPE_REQUEST);
...
}
...
}
Атрибуты установлены в классе, расширяющем HandlerInterceptorAdapter (так что они могут быть установлены в начале запросаи убрал в конце).
@Component
public class RequestInterceptor extends HandlerInterceptorAdapter {
private MyAttributeFactory myAttributeFactory;
@Autowired
public DbConnectionInterceptor(MyAttributeFactory myAttributeFactory) {
this.myAttributeFactory = myAttributeFactory;
}
/**
* Executed before request handler is executed
**/
@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) {
Object myAttribute = myAttributeFactory.build();
requestContextHolder.setAttribute("attributeName", myAttribute, true);
}
/**
* Executed after the whole request is finished
**/
@Override
public void afterCompletion(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final Exception ex) {
requestContextHolder.removeAttribute("attributeName");
}
}
Я извлекаю RequestAttributes через RequestContextHolder Поскольку RequestAttributes связаны с потоками, я вижу, что новая копия RequestAttributes создается, когда StompFrameHandler должен получить к ним доступ.
Это прекрасно работает с первым HTTP-запросом, однако к тому времени, когда приходит второй HTTP-запрос и вызывается StompFrameHandler, он все еще использует экземпляр RequestAttributes из предыдущего HTTP-запроса, который теперь больше не работает.активен и выдает следующее исключение при доступе:
java.lang.IllegalStateException: Cannot ask for request attribute - request is not active anymore!
Как я могу убедиться, что копия RequestAttributes в потоке обработки STOMP очищена в конце HTTP-запроса?
PS: я попытался использовать registerDestructionCallback, но обратный вызов вызывается только для атрибутов потока запроса, а не для тех, которые связаны с потоком обработчика STOMP, предполагая, что они действительно не уничтожаются, как это должно быть.