IllegalStateException при доступе к RequestAttributes, привязанным к потокам без запроса - PullRequest
0 голосов
/ 12 декабря 2018

У меня проблема с продолжительностью жизни 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, предполагая, что они действительно не уничтожаются, как это должно быть.

...