2013-07-26 11 views
5

Ho un regolatore di come questo:Potrebbe Spring MVC chiamare @ModelAttribute dopo @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(); 
    } 
} 

In breve, le mie opinioni renderebbe user in quasi ogni azioni HomeController, ma io non voglio il codice:

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

in ogni azione, invece, sto cercando un modo come @ModelAttribute per esporre user a tutti i miei punti di vista.

Tuttavia, secondo i documenti, @ModelAttribute metodi in un controller vengono richiamati prima@RequestMapping metodi, all'interno dello stesso controllore.

Come per il mio codice, getUser viene chiamato prima dello update, ma mi piacerebbe ottenere l'utente aggiornato.

Esiste un modo per esporre l'attributo userdopo azioni senza chiamare esplicitamente model.addAttribute in ogni azioni?

risposta

5

Ogni volta che si esegue un POST, effettuare un reindirizzamento. In questo modo, il tuo metodo POST sarà responsabile dell'aggiornamento dei dati e i dati aggiornati verranno caricati dal controller di destinazione.

In questo caso, il metodo update() reindirizza a un altro controller che chiamerebbe il metodo getUser() prima del suo metodo GET.

1

La soluzione Post/redirect/GET è valida se funziona per voi.

Tuttavia, ho avuto una situazione simile in cui avevo attributi di modello che dovevano essere scritti da tutti i miei controller, dopo l'elaborazione delle richieste (informazioni di tracciamento per lo più). Quello che ho fatto è stato registrare un'interfaccia personalizzata (ad esempio AdditionalModelDataSupplier), che applico a tutti i controller che devono fornire dati aggiuntivi. L'interfaccia avrebbe un metodo come questo:

void provideAdditionalData(Model model, HttpServletRequest request); 

Ora, ho scritto un intercettore che nel metodo postHandle controlla il fagiolo Controller per questa interfaccia e chiama questo metodo:

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

(classe ForwardingModel menzionato sopra è banale da creare, semplicemente delega tutto allo ModelMap)

Problemi correlati