У меня есть следующая настройка контроллера в Spring 3.0.5. Tomcat Webserver 7.0.14 с хостом Windows 7.
@Controller
@RequestMapping (value="myForm")
public class SubmitClassController {
//Status object with getters and setters
Status myStatus= newStatus();
@RequestMapping (method=RequestMethod.GET)
public String getMyForm (Model getModel){
//setup form
//very simple adds one attribute to the model and returns view
}
@RequestMapping (value="/myFormStatus",method=RequestMethod.POST)
public @ResponseBody Status getStatus(){
//Ajax responder handles a null (empty) request and responds with results of status obj
//Has System.out.println prior to return that shows variables when processed correctly
System.out.printlin ("vars are: "+myStatus.getStatus()+" "+myStatus.getCurStep()+" "+myStatus.getTotSteps());
return myStatus;
}
@RequestMapping (method=RequestMethod.POST)
public String create (@Valid MyFormText submitText ...){
// processes the form submitted and sets status object variables while doing so .
//many steps each one is bascily query a remote DB wait for response, add response to the set repeat. After each query myStatus has its status,curStap and totstep set.
}
}
Я выполняю запрос ajax из Firefox или IE следующим образом. Результат тот же
Ext.Ajax.request({
url: './myForm/myFormStatus',
method: 'POST',
success: function(result, request) {
var json = Ext.decode(result.responseText);
pbar.updateProgress(json.step / json.steps, 'Working on ' + json.status + ' Step ' + json.step + ' of ' + json.steps + '...');
},
failure: function(result, request) {
Ext.MessageBox.alert('Failed runner', result.responseText);
}
});
Ответчик Ajax работает правильно, за исключением случаев, когда он вызывается во время метода POST "create". Поэтому я запускаю ajax-запрос в цикле, в то время как метод create (который обрабатывает POST) не выполняется, он возвращает нормально. Однако во время выполнения create Ajax-ответы являются прерывистыми, и Ajax-запросы часто не отвечают. Сервер не блокируется и не останавливается, а просто перестает отвечать на метод состояния, в то время как метод create что-то делает.
Я попытался заменить большую часть создания циклами, которые заполняют массивы. Я получил больше ответов ajax, но не один рядом с одним, в лучшем случае получил 20-30 ответов из 100. Я также протестировал изменение значений для объекта состояния, чтобы убедиться, что значения вернут действительный JSON. Они все работали. Выполняя тест, в котором я только что заполнил древовидные карты и массивы, я также наблюдал за Jconsole и менеджером задач на наличие признаков ограничения ресурсов. HTe JVM никогда не использовала более 50% доступной памяти, а более эффективные операции ввода-вывода, ОЗУ или ЦП были где-то близко к загрузке.
Очевидно, что-то здесь не так. Я попытался присоединить аннотацию @Async к контроллеру Ajax и к обработчику POST, но, похоже, это не внесло никаких изменений. Я также пытался выставить тайм-ауты и автоматически прерывать запрос.
Из 100 запросов Ajax я получаю один ответ ... остальные, кажется, заблокированы. Либо до вызова блока создания, либо после, ответы будут мгновенными. Я не должен перегружать браузер. Рассматриваемый запрос ajax срабатывает один раз в четверть секунды (средство обновления индикатора выполнения). Даже если я уменьшу количество запросов Ajax до 1 в секунду (или даже 1 в 2 с), результат будет тем же. Вызовы ajax выполняются вовремя, поэтому сторона JS работает как положено.
Я использовал wireshark, чтобы я мог видеть входящий запрос ajax. Я могу учесть большинство запросов ajax в том, что я вижу, как они достигают сервера. Я вижу, как они попадают в обработчик, но сообщения об устранении неполадок (System.out.println) появляются только тогда, когда метод create не занят. Понятно, что «занято» означает обработку результатов запросов, которые он делает, а «не занято» означает ожидание ответа. Никакие защелки или семафоры не используются. Добавление аннотации Spring @Async не имело никакого значения.
Кто-нибудь знает, что здесь происходит? Кажется, что-то блокируется и мешает ответу? Контроллер заблокирован для одного потока?