Попытка ответить на мой собственный вопрос привела меня к следующему коду:
public void endFlow() {
if (context != null && definition != null) {
ExternalContextHolder.setExternalContext(contex.getExternalContext());
context.removeAllFlowExecutionSnapshots();
context.endActiveFlowSession(definition.getId(), definition.getAttributes());
Flow flow = (Flow)definition;
flow.destroy();
}
}
Строка ExternalContextHolder ... позволяет избежать NPE, снимки удаляются, а поток сеанса также завершается, однако возникли новые вопросы
- зачем нужен ExternalContextHolder? это нормально?
Ниже приведено какое-то странное (или нормальное?) Поведение, которое я получаю
Предположим, я запустил поток e1s1 на вкладке браузера 1, а также e2s1 на другой вкладке, теперь, если я нахожусь на e2s1 и нажимаю кнопку «Далее» на моем мастере, я получаю e2s2 (это правильно), теперь, если я удаляю снимки выполнения которые принадлежат e1s1, они удаляются без проблем, но если перейти на вкладку, где находится e2s2, и я нажимаю кнопку «предыдущий», чтобы я мог вернуться к предыдущему снимку, снимок e2s1 также пропал, я имею в виду, что удаление снимка не должно быть чем-то «за» исполнение». Я проверил новый код для удаления выполнения потока (используя метод removeFlowExecution из класса FlowExecutionRepository), но сейчас я не буду его показывать, вместо этого я буду ждать, если кто-то может бросить несколько указателей. В любом случае, если ничего не обнаружится, я буду держать кого-то заинтересованным в петле.
Еще раз я отвечаю на мой вопрос, надеюсь, это последний ответ.
Q: зачем нужен ExternalContextHolder?
Ответ: согласно моему небольшому опыту, ExternalContextHolder, вероятно, помимо прочего, необходим, чтобы у Spring был доступ (HttpServletRequest и HttpServletResponse) к данным, отправляемым тем, кто выполняет запрос.
В конце концов, удаление flowexecution из фильтра может показаться хорошей идеей, но webflow дает нам еще лучший подход, я имею в виду создание подкласса FlowExecutionListenerAdapter, и в этом случае мы переопределили метод «void requestSubmitted (контекст RequestContext)», а здесь я проверьте, есть ли у текущего пользователя доступ к roomId, а затем я вызову метод endFlow (см. код ниже)
public void endFlow(ExternalContext externalContext) {
FlowUrlHandler handler = flowController.getFlowUrlHandler();
HttpServletRequest request = (HttpServletRequest) externalContext.getNativeRequest();
String stringKey = handler.getFlowExecutionKey(request);
if (stringKey != null) {
FlowExecutorImpl flowExecutor = (FlowExecutorImpl) flowController.getFlowExecutor();
FlowExecutionRepository repository = flowExecutor.getExecutionRepository();
FlowExecutionKey key = repository.parseFlowExecutionKey(stringKey);
ExternalContextHolder.setExternalContext(externalContext);
FlowExecutionLock lock = null;
try{
lock = repository.getLock(key);
}catch(NoSuchFlowExecutionException nsfee){
return;
}
lock.lock();
try {
FlowExecution flowExecution = repository.getFlowExecution(key);
repository.removeFlowExecution(flowExecution);
} finally {
lock.unlock();
}
}
}
flowController (org.springframework.webflow.mvc.servlet.FlowController) добавляется пружиной и добавляется в наш файл конфигурации веб-потока.
Приведенный выше код полностью удаляет выполнение потока, и если пользователь пытается вернуться к предыдущему потоку, скажем, e1s1, тогда веб-поток автоматически создает новое выполнение потока e2s1, и вот оно.
В случае, если вы хотите использовать подход фильтра, все, что вам нужно в методе doFilter, это this
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String roomId = req.getParameter("roomId");
ExternalContext externalContext = new ServletExternalContext(
this.servletContext, req, resp);
if (roomId != null) {
if (!currentUserHasAccess(roomId)) {
flowExecutionManager.endFlow();
return;
}
}
chain.doFilter(request, response);
this.servletContext, полученный с помощью filterConfig.getServletContext ()