2010-11-04 1 views
5

У меня есть фильтры, подобные тем, которые определены ниже. Они запускают один и тот же блок кода в разных местах, поэтому, чтобы он был DRY, я реорганизовал этот код в метод, называемый doResponse().Вызов render() из метода фильтра-фильтра в Grails

class MyFilters { 

    def filters = { 
     web(uri: '/web/**') { 
      before = { 

       // Do Stuff 
       if (condition) { 
        doResponse(request, response, params) 
       } 
       return true 
      } 
      after = { 
       if (condition) { 
        doResponse(request, response, params) 
       } 
       else { 
        // Do Stuff 
        doResponse(request, response, params) 
       } 

      } 
      afterView = { 
      } 
     } 
    } 

    boolean doResponse(request, response, params) { 
    // Do Stuff 
     render(status: statusCode, contentType: "text/xml", encoding: "ISO-8859-1", text: text) 
    // Do post-render stuff 
     return false 
    } 
} 

Однако у этого есть неприятный побочный эффект. Кажется, что метод render() доступен только из закрытия фильтра. Есть ли (аккуратный) способ для вызова render() из doResponse()?

Edit: Я получаю ошибку есть:

groovy.lang.MissingMethodException: Нет подписи метода: MyFilters.render() применяется для типов аргументов: значения (java.util.LinkedHashMap): [[статус : 500, contentType: text/xml, encoding: ISO-8859-1, текст: ...]]

ответ

8

Pass объект, который определяет метод render(..) к методу doRespond(..), и вызвать метод render(..) на этом объекте.

Закрытие имеет implicit variables, включая их owner, который относится к закрытию родителя; так что мы можем передать, что:

if (condition) { 
    doResponse(owner, request, response, params) 
} 

doRespond(..) метод:

boolean doResponse(webFilter, request, response, params) { 
    // Do Stuff 
    webFilter.render(status: statusCode, contentType: 
     "text/xml", encoding: "ISO-8859-1", text: text) 
    // Do post-render stuff 
    return false 
} 
+0

hi Я попытался это сделать, но получение: java.lang.NullPointerException: Невозможно установить свойство «viewName» на нулевом объекте на java.lang.Thread.run (Thread.java:680) –

0

Не удалось передать ссылку на функцию render функции doResponse?

т.е.:

if(condition) { 
    doResponse(request, response, params, this.&render) 
} 

и

boolean doResponse(request, response, params, renderFn) { 
// Do Stuff 
    renderFn(status: statusCode, contentType: "text/xml", encoding: "ISO-8859-1", text: text) 
// Do post-render stuff 
    return false 
} 
+0

К сожалению, это похоже на вызов render() непосредственно из doResponse(). Я получаю ту же ошибку. – Einar

+0

Darn. Не могли бы вы добавить ошибку, которую вы получили в текст вопроса? –

+0

Конечно. Кажется, что SO сокращает последние части текста исключения, но этого должно быть достаточно. – Einar

0

Вы можете попробовать это решение.

Изменение doResponse к закрытию:

def doResponse = { 
     render(status: statusCode, contentType: "text/xml", encoding: "ISO-8859-1", text: text) 
     return false 
} 

Вызов doResponse (от закрытия фильтра):

def doResponseClosure = doResponse.clone() 
doResponseClosure.delegate = delegate 
// if it doesn't work, try adding: doResponseClosure.owner = owner 
return doResponseClosure() 

Клонирование делается из соображений параллелизмом.

Я успешно использовал этот метод в других DSL-системах Grails, таких как закрытие критериев.

+0

Спасибо.Это работает, но решение robbberts требует немного меньше кода. – Einar

Смежные вопросы