У нас есть веб-приложение с панелью мониторинга, которая постоянно проводит опрос на наличие обновлений. На стороне сервера запрос на обновления делается асинхронным, поэтому мы можем ответить, когда обновление происходит через систему прослушивателя/уведомления.
Проблема, которую мы видим, заключается в том, что при ответе на один из этих запросов опроса он может в некоторых случаях записывать запрос/ответ для ссылки с кликом.
Входящий запрос для асинхронного обновления выглядит следующим образом:
@RequestMapping("/getDashboardStatus.json")
public void getDashboardStatus(HttpServletRequest request, ...) {
final AsyncContext asyncContext = request.startAsync();
// 10 seconds
asyncContext.setTimeout(10000);
asyncContext.start(new Runnable() {
public void run() {
// .. (code here waits for an update to occur) ..
sendMostRecentDashboardJSONToResponse(asyncContext.getResponse());
if (asyncContext.getRequest().isAsyncStarted()) {
asyncContext.complete();
}
}
});
}
Что странно, что на этой панели есть ссылки, которые идут на другие страницы. Каждые ~ 100 кликов или около того, один из них вместо отображения выбранной страницы фактически отображает отправленный JSON выше!
Например, у нас есть отдельный метод MVC:
@RequestMapping("/result/{resultId}")
public ModelAndView getResult(@PathVariable String resultId) {
return new ModelAndView(...);
}
И при нажатии на ссылку на панели управления, которая посещает /result/1234
, каждая синяя луна, страница загружается с статусом 200 OK, но вместо того, чтобы содержать ожидаемый HTML, на самом деле содержит JSON для запроса на опрос!
Разрешен ли только один запрос на одного клиента? Выполняет ли запрос, инициированный щелчком ссылки, любые асинхронные запросы, которые уже находятся на стороне сервера от одного и того же клиента?
Как мы можем управлять этими запросами, чтобы гарантировать, что асинхронный ответ будет отправлен на запрос async?
Я заметил метод hasOriginalRequestAndResponse()
на объекте AsyncContext
, но мне трудно понять Javadoc, независимо от того, что я ищу.
Обновление: Я просто добавил фрагмент так:
String requestURI = ((HttpServletRequest)asyncContext.getRequest()).getRequestURI());
System.out.println("Responding w/ Dashboard to: " + requestURI);
sendMostRecentDashboardJSONToResponse(asyncContext.getResponse(), clientProfileKey);
И смог воспроизвести проблему во время правильного поведения, я вижу:
Responding w/ Dashboard to: /app/getDashboardStatus.json
Но когда я вижу, что JSON нажата на запросы, инициированные кликом, я вижу:
Responding w/ Dashboard to: null