2013-07-26 2 views
5

У меня есть контроллер, как это:Может ли Spring MVC вызывать @ModelAttribute после @RequestMapping?

@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(); 
    } 
} 

Короче говоря, мои взгляды будут оказывать user почти каждого действий в HomeController, , но я не хочу, чтобы код:

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

в каждом действии вместо этого я ищу способ, как @ModelAttribute, выставить user ко всем моим взглядам.

Тем не менее, в соответствии с Документами, @ModelAttribute методы в контроллере вызывается перед@RequestMapping методы, в пределах того же контроллера.

Что касается моего кода, то getUser вызывается до update, но я хотел бы получить обновленного пользователя.

Есть ли способ, чтобы выставить user атрибут после действий без явного вызова model.addAttribute в каждом действиях?

ответ

5

Каждый раз, когда вы делаете POST, сделайте переадресацию. Таким образом, ваш метод POST будет отвечать только за обновление данных, а обновленные данные будут загружаться целевым контроллером.

В этом случае метод update() будет перенаправлен на другой контроллер, который будет вызывать метод getUser() до его метода GET.

1

Решение Post/redirect/GET действует, если оно работает для вас.

Однако, у меня была аналогичная ситуация, когда у меня были атрибуты модели, которые должны были быть написаны всеми моими контроллерами после обработки запроса (в основном, информация для отслеживания). Я сделал регистрацию пользовательского интерфейса (например, AdditionalModelDataSupplier), который я применяю ко всем контроллерам, которым необходимо предоставить дополнительные данные. Интерфейс будет иметь метод, как это:

void provideAdditionalData(Model model, HttpServletRequest request); 

Теперь я написал перехватчик, что в методе postHandle проверяет компонент контроллера для этого интерфейса и вызывает этот метод:

@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 класса упомянутое выше, тривиально для создания, оно просто делегирует все на ModelMap)

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