#grails
#grails
Вопрос:
Я использую Grails 1.2.1. У меня есть этот метод в моем контроллере …
class SocialMediaCacheProxyController {
def index = {
def url = params.url
if (params.dumpAll != null) {
transportCacheService.processCacheDump(request.getRemoteAddr(), response)
} else if (url != null) {
doCacheTransport(request, response)
} // if
}
Проблема в том, что оба пути выполнения записывают содержимое в ответ. Тем не менее, я думаю, что Grails пытается отобразить страницу в конце метода index, потому что я неоднократно получаю приведенную ниже ошибку после вызова этого метода …
1339754 [http-8080-4] ERROR org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/socialmediaproxy].[default] - Servlet.service() for servlet default threw exception
java.lang.IllegalStateException: response.getWriter() called after response.getOutputStream()
at org.codehaus.groovy.grails.web.sitemesh.GrailsPageResponseWrapper$GrailsBuffer.getWriter(GrailsPageResponseWrapper.java:284)
at org.codehaus.groovy.grails.web.sitemesh.GrailsPageResponseWrapper$3.activateDestination(GrailsPageResponseWrapper.java:125)
Есть идеи, как я могу заставить Grails прекратить рендеринг чего-либо после завершения моего метода? Спасибо, — Дэйв
Ответ №1:
Если вы не укажете Grails, что отображать, он будет отображаться на основе соглашения. В вашем случае он ищет index.gsp. Контроллеры должны что-то возвращать. В этом весь смысл. Таким образом, вы можете либо использовать соглашение и создать index.gsp, который возвращается, либо вы можете вручную реализовать метод render() .
Комментарии:
1. Согласно вашей ссылке, я попытался добавить «render (text: ‘привет’)» в качестве последней строки индексного метода моего контроллера, но я все еще получал ту же ошибку.
2. Пожалуйста, не обращайте внимания на предыдущий комментарий. То, что вы предложили, сработало — в моем коде была еще одна ошибка, которая не позволяла решению работать.
Ответ №2:
Похоже, что большая часть кода контроллера, который работает с ModelAndView
, следит за тем, было ServletResponse
зафиксировано или нет.
Я бы предположил, что вы могли бы вызвать response.flushBuffer() в конце действия вашего контроллера. Это приведет к тому, что ответ будет помечен как зафиксированный, и контроллер не вернет ModelAndView.
Альтернативой мог бы быть вызов response.outputStream.flush()
, который также привел бы к фиксации ответа. Это то, что я обычно в конечном итоге делаю после ручной работы с ответом (например, для загрузки файлов).
Примечание: Я не уверен, относится ли это к сфере «лучших практик» — обычно вы должны полагаться на контейнер для обработки очистки потоков сервлета. Вполне возможно, что при этом возникнут непреднамеренные побочные эффекты. Вероятно, вам придется протестировать это и посмотреть, что произойдет с вашим приложением и контейнером, в котором вы его запускаете.
Ответ №3:
Я думаю, вы пытаетесь сделать что-то противоречащее дизайну приложения MVC. Контроллеры существуют для того, чтобы отправлять вас куда-то на основе параметров. Может быть, вы могли бы вместо этого рассмотреть возможность использования Сервиса с помощью AJAX-вызова. Или, если действие вашего контроллера изменяет данные, которые вы хотите отобразить, вы могли бы просто перенаправить обратно на страницу, с которой пришел вызов. Начните здесь:
Комментарии:
1. эти ссылки на документацию устарели
Ответ №4:
Я думаю, что Grails, возможно, перенаправляет в index.gsp, потому что это происходит по умолчанию, когда вы не возвращаете значение.
Поэтому, я думаю, вам следует return null
в конце закрытия индекса сообщить grails, что вы уже записали все, что хотели, в выходной поток.
Комментарии:
1. Я протестировал это, и когда я вернулся
null
, он все еще пытался отобразить представление по умолчанию. Однако, если я изменилresponse
выходной поток, возврат null был эффективным (хотя явный возвратnull
может быть ненужным, если Grails просто просматриваетisCommitted
статус ответа).
Ответ №5:
попробуйте этот рендеринг (view: «/название страницы», модель: [текст: «привет»)
ПРИМЕЧАНИЕ: если вы хотите отобразить шаблон, вместо «view» вы ставите «template»