2015-05-20 1 views
2

При обработке ошибок в формах в Play Framework 2 (Java) я хочу представить общее сообщение об ошибке, предупреждающее пользователя о том, что что-то пошло не так, например. "Форма X не обновляется". Один из способов сделать это, в дополнение к ошибкам для каждого поля формы, чтобы создать глобальную ошибку, а затем представить это на каждом шаблоне:Как обрабатывать глобальные ошибки в формах в Play Framework 2 (Java)

Контроллер:

if(form.hasErrors()) { 
    form.reject("Form X not updated."); // This creates a global error 
} 

Шаблон:

@if(form.hasGlobalErrors) { 
    @someFunctionToPresentErrors(from.globalError.message)) 
} 

Однако, этот идентичный фрагмент кода каждый шаблон, содержащий форму, нарушает принцип DRY.

Мой лучшее решение до сих пор, чтобы добавить сообщение об ошибке Http.Context вместо, а затем перехватывать сообщение об ошибке в главном шаблоне, который вызывается каждый шаблон:

Контроллер:

Http.Context.current().args.put("error", "Form X not updated."); 

Основной шаблон :

@if(Http.Context.current().args.containsKey("error")){ 
    @someFunctionToPresentErrors(
     Http.Context.current().args.get("error").asInstanceOf[String]) 
} 

Это лучше, потому что это позволяет мне хранить материал презентации ошибок в одном месте, но это похоже на злоупотребление Http.Context. Обратите внимание, что также может использоваться для неявной передачи переменных и дает тот же эффект, что и Http.Context, но это недопустимо при вызове badRequest(...), поскольку флэш-память должна использоваться только для перенаправления. В любом случае, я думаю, что должен быть лучший способ сделать это, используя механизм формы, предоставляемый Play Framework.

Есть ли наилучшая практика для этого?

ответ

4

Я думаю, что вы переоценивать DRY нарушения в данном случае - на самом деле я понял, что даже глобальной ошибка не настолько глобальна - на самом деле каждая форма имеет свой собственный контекст. В любом случае, чтобы сделать работу быстрее, вы можете сделать использование из template tags и Flash scope

Сначала добавьте две общие открытые методы в вашем т.е. Application контроллер

public static void flashGlobalError() { 
    flashGlobalError("Oppps... error occurred and I don't know the reason ;("); 
} 

public static void flashGlobalError(String msg) { 
    flash("globalError", msg); 
} 

затем создать tag template т.е. без параметровviews/tags/globalErrorByFlash.scala.html

@if(flash.get("globalError")) { 
    <div style="background: red"> 
     <h4>Error!</h4> 
     @flash.get("globalError") 
    </div> 
} 

и включить его в свой main шаблон (или в выбранных видах только), как:

<body> 
    @tags.globalErrorByFlash() 
    @content 
</body> 

Таким образом, каждый раз, когда вы хотите, чтобы отобразить эту ошибку вы можете просто сделать его в действии:

if(form.hasErrors()) { 
    Application.flashGlobalError(); 
    return badRequest(...); 
} 

или

if(form.hasErrors()) { 
    Application.flashGlobalError("This case is quite bit different..."); 
    return badRequest(...); 
} 

Лучшее преимущество данного подхода заключается в том, что вы не должны зависеть от Form.form(T), как вы можете использовать его в любом месте:

if (1 != 0){ 
    Application.flashGlobalError("Stupido! One isn't equal to Zero!"); 
} 

Наконец: имейте в виду, что любое значение хранится во флэш объеме жизни только по одному запросу, поэтому он может исчезать после перенаправления. Просмотр/рендеринг шаблона также подсчитывается, поэтому, если вы перенаправите ошибку на новое действие, переместите ее в контроллер, поэтому перенаправленное представление может ее увидеть.

+0

Я уже рассматривал это решение. Однако, когда вы вызываете 'badRequest()' (как и при возникновении ошибки в форме), вы не должны одновременно использовать flash. Фактически, если вы это сделаете, это приведет к предупреждению: _ Вы используете код состояния «400» с миганием, который должен использоваться только с статусом перенаправления! _. Поэтому я решил использовать 'Http.Context'rather, чем flash. Однако идея одна и та же, а именно: избегать передачи параметров вокруг. – plade

+0

Теперь я обновил вопрос с информацией о вспышке. – plade

+0

TBH Я не понимаю, для чего генерируется это предупреждение (BTW только в режиме DEV). Лично, пока он не работает (по крайней мере до 2.3.x), я собираюсь использовать его для заполнения простых сообщений даже без перенаправления. Если будущие версии отключат его - я буду искать другое решение :) – biesior