Как запретить Grails отображать представление по умолчанию?

#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() .

http://grails.org/doc/latest/ref/Controllers/render.html

Комментарии:

1. Согласно вашей ссылке, я попытался добавить «render (text: ‘привет’)» в качестве последней строки индексного метода моего контроллера, но я все еще получал ту же ошибку.

2. Пожалуйста, не обращайте внимания на предыдущий комментарий. То, что вы предложили, сработало — в моем коде была еще одна ошибка, которая не позволяла решению работать.

Ответ №2:

Похоже, что большая часть кода контроллера, который работает с ModelAndView , следит за тем, было ServletResponse зафиксировано или нет.

Я бы предположил, что вы могли бы вызвать response.flushBuffer() в конце действия вашего контроллера. Это приведет к тому, что ответ будет помечен как зафиксированный, и контроллер не вернет ModelAndView.

Альтернативой мог бы быть вызов response.outputStream.flush() , который также привел бы к фиксации ответа. Это то, что я обычно в конечном итоге делаю после ручной работы с ответом (например, для загрузки файлов).

Примечание: Я не уверен, относится ли это к сфере «лучших практик» — обычно вы должны полагаться на контейнер для обработки очистки потоков сервлета. Вполне возможно, что при этом возникнут непреднамеренные побочные эффекты. Вероятно, вам придется протестировать это и посмотреть, что произойдет с вашим приложением и контейнером, в котором вы его запускаете.

Ответ №3:

Я думаю, вы пытаетесь сделать что-то противоречащее дизайну приложения MVC. Контроллеры существуют для того, чтобы отправлять вас куда-то на основе параметров. Может быть, вы могли бы вместо этого рассмотреть возможность использования Сервиса с помощью AJAX-вызова. Или, если действие вашего контроллера изменяет данные, которые вы хотите отобразить, вы могли бы просто перенаправить обратно на страницу, с которой пришел вызов. Начните здесь:

http://grails.org/doc/1.0.x/guide/6. The Web Layer.html

http://grails.org/doc/1.0.x/guide/8. The Service Layer.html

Комментарии:

1. эти ссылки на документацию устарели

Ответ №4:

Я думаю, что Grails, возможно, перенаправляет в index.gsp, потому что это происходит по умолчанию, когда вы не возвращаете значение.

Поэтому, я думаю, вам следует return null в конце закрытия индекса сообщить grails, что вы уже записали все, что хотели, в выходной поток.

Комментарии:

1. Я протестировал это, и когда я вернулся null , он все еще пытался отобразить представление по умолчанию. Однако, если я изменил response выходной поток, возврат null был эффективным (хотя явный возврат null может быть ненужным, если Grails просто просматривает isCommitted статус ответа).

Ответ №5:

попробуйте этот рендеринг (view: «/название страницы», модель: [текст: «привет»)

ПРИМЕЧАНИЕ: если вы хотите отобразить шаблон, вместо «view» вы ставите «template»