2013-07-26 9 views
5

私はこのようなコントローラがあります。要するにSpring MVCが@RequestMappingの後に@ModelAttributeを呼び出すことはできますか?

@Controller 
public class HomeController { 

    @RequestMapping(value = "/update", method = RequestMethod.POST) 
    public String update(@RequestParam("user") User user, ModelMap model){ 
     SaveUserToDatabase(user); 
     return "index"; 
    } 

    @ModelAttribute("user") 
    String getUser() { 
     return LoadCurrentUserFromDataBase(); 
    } 
} 

を、私の見解は、HomeControllerほぼすべてのアクションでuserをレンダリング が、私はコードにしたくないでしょう。

model.addAttribute("user", LoadCurrentUserFromDataBase()) 

代わりに、すべての私の意見にuserを公開するために、@ModelAttributeのような方法を模索しています。

しかし、ドキュメントによれば、コントローラに@ModelAttribute方法は、同じコントローラ内、@RequestMapping方法が呼び出されます。

私のコードに関してはgetUserupdateの前に呼び出されていますが、私は更新されたユーザーを取得したいと思います。

明示的にすべてのアクションでmodel.addAttributeを呼び出すことなく、アクション後user属性を公開する方法はありますか?

答えて

5

POSTを実行するたびに、リダイレクトを行います。この方法では、POSTメソッドはデータの更新のみを担当し、更新されたデータはターゲットコントローラによってロードされます。

この場合、update()メソッドはGETメソッドの前にgetUser()メソッドを呼び出す別のコントローラにリダイレクトされます。

1

ポスト/リダイレクト/ GETソリューションは有効な場合に有効です。

しかし、要求処理(ほとんどの情報の追跡)後に、すべてのコントローラが書き込む必要のあるモデル属性があるのと同様の状況がありました。私が行ったのは、追加のデータを提供する必要のあるすべてのコントローラに適用するカスタムインターフェイス(例:AdditionalModelDataSupplier)を登録することでした。インターフェイスは、このような方法でしょう。

@Override 
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, 
     final ModelAndView modelAndView) throws Exception { 

    AdditionalModelDataSupplier modelDataSupplier = findAdditionalModelDataSupplier(handler); 
    if (modelDataSupplier != null) { 
     final ModelMap modelMap = modelAndView.getModelMap(); 
     final Model targetModel; 
     if (modelMap instanceof Model) { 
      targetModel = (Model) modelMap; 
     } else { 

      // the modelmap doesn't implement model, so we need to provide a wrapper view 
      targetModel = new ForwardingModel(modelMap); 
     } 

     modelDataSupplier.provideAdditionalData(targetModel, request); 
    } 
} 
@Nullable 
private static AdditionalModelDataSupplier findAdditionalModelDataSupplier(final Object handler) { 
    if (handler instanceof AdditionalModelDataSupplier) { 
     return (AdditionalModelDataSupplier) handler; 
    } 

    if (handler instanceof HandlerMethod) { 
     HandlerMethod handlerMethod = (HandlerMethod) handler; 
     Object bean = handlerMethod.getBean(); 
     if (bean instanceof AdditionalModelDataSupplier) { 
      return (AdditionalModelDataSupplier) bean; 
     } 
    } 

    return null; 
} 

ForwardingModelクラス:

void provideAdditionalData(Model model, HttpServletRequest request); 

は今、私はpostHandle方法では、このインターフェイスのためのコントローラーBeanをチェックして、このメソッドを呼び出すことインターセプタを書きました上記のように、作成するのは簡単ではなく、すべてをModelMapに委任します)

関連する問題