2009-09-03 18 views
13

In quali circostanze esatte @SessionAttributes viene cancellato? Ho scoperto alcuni comportamenti confusi quando provo a utilizzare due modelli in una pagina.Quando vengono rimossi @SessionAttributes in SpringMVC? (Con esempio di codice)

Quando faccio un GET seguito da un POST utilizzando questo controller ...

@Controller 
@RequestMapping("/myPage*") 
@SessionAttributes(value = {"object1", "object2"}) 
public class MyController { 

    @RequestMapping(method = RequestMethod.GET) 
    public String get(Model model) { 
     model.addAttribute("object1", new Object1()); 
     model.addAttribute("object2", new Object2()); 
     return "myPage"; 
    } 

    @RequestMapping(method = RequestMethod.POST) 
    public String post(@ModelAttribute(value = "object1") Object1 object1) { 
     //do something with object1 
     return "myPage"; 
    } 
} 

... oggetto2 ottiene cancellati dal modello. Non esiste più come @SessionAttribute e non è possibile accedere alla mia pagina di visualizzazione.

Tuttavia, se la firma del secondo metodo viene modificato per questo ...

public String post(@ModelAttribute(value = "object1") Object1 object1, 
        @ModelAttribute(value = "object2") Object2 object2) { 

... poi oggetto2 non ottiene cancellati dal modello ed è disponibile sulla mia pagina di visualizzazione.

Il Javadoc per @SessionAttributes dice:

... attributi saranno rimossi una volta il gestore indica il completamento della sua sessione di conversazione.

Ma non vedo come ho indicato il completamento della sessione conversazionale nel primo esempio ma non nel secondo esempio.

Qualcuno può spiegare questo comportamento o è un bug?

+0

Questo problema è stato risolto nella primavera 3.0RC1. Vedi http://jira.springsource.org/browse/SPR-6084 Grazie Juergen! –

risposta

14

È indicare il completamento della conversazione chiamando

SessionStatus.setComplete

public void post(...., SessionStatus status) { 
    status.setComplete(); 
} 

Detto questo, non vedo il motivo per cui si dovrebbe essere perdendo un attributo di modello e non il contrario.

Hai provato a fare qualcosa di simile:

@ModelAttribute("object1") 
public Object object1() { return new Object(); } 

@ModelAttribute("object2") 
public Object object2() { return new Object(); } 

E vedere come che confronta a mettere gli attributi nel modello a mano.

+1

Ho provato il tuo suggerimento - e incredibilmente funziona! Ora sono davvero confuso. Perché c'è una differenza nell'impostare manualmente l'attributo del modello e impostarlo usando @ModelAttribute? –

+2

Ahimè, ho fatto un boo-boo. Dal riferimento (3.0.0.M3): "Nota: i metodi annotati @ModelAttribute verranno eseguiti prima del metodo del gestore annotato @RequestMapping scelto". Quindi la ragione per cui funziona è che i metodi object1 e object2 vengono eseguiti prima dei metodi get e post. Questo potrebbe effettivamente essere quello che vuoi, ma non sospetto. – ptomli

+0

Sì, l'ho capito subito dopo aver postato il mio commento. Potrei sollevarlo con Spring perché non vedo alcuna spiegazione ragionevole per questo comportamento. –

1

È possibile rimuovere solo ModelAttribute livello di sessione in questo modo:

Dato ModelMap model, HttpSession session e si fa:

if (categoryId != null) 
    model.addAttribute("categoryId", categoryId); 
else { 
    model.remove("categoryId"); 
    session.removeAttribute("categoryId"); 
} 
Problemi correlati