2010-05-03 21 views
22

Ho un oggetto modulo che ho impostato per richiedere nel gestore di richieste GET nel mio controller Spring. Prima volta che l'utente accede alla pagina, è necessario creare un nuovo oggetto modulo e impostarlo su richiesta. Se l'utente invia un modulo, l'oggetto modulo viene popolato dalla richiesta e ora l'oggetto modulo ha tutti gli attributi di utente. Quindi il modulo viene convalidato e se la convalida è ok, allora il modulo viene salvato nel database. Se il modulo non è convalidato, voglio salvare l'oggetto modulo in sessione e quindi reindirizzare a GET pagina di gestione delle richieste. Quando la richiesta viene reindirizzata al gestore GET, deve controllare se la sessione contiene oggetto modulo.Spring Framework 3 e attributi di sessione

ho capito che c'è @SessionAttributes ("forma") l'annotazione in primavera, ma per qualche ragione non funziona seguendo, perché in un primo momento, modulo di attributo sessione è nullo e dà errore:

org.springframework.web.HttpSessionRequiredException: Session attribute 'form' required - not found in session 

Ecco il mio controller:

@RequestMapping(value="form", method=RequestMethod.GET) 
public ModelAndView viewForm(@ModelAttribute("form") Form form) { 
    ModelAndView mav = new ModelAndView("form");  
    if(form == null) form = new Form(); 
    mav.addObject("form", form); 
    return mav; 
} 

@RequestMapping(value="form", method=RequestMethod.POST) 
@Transactional(readOnly = true) 
public ModelAndView saveForm(@ModelAttribute("form") Form form) { 
    FormUtils.populate(form, request); 
    if(form.validate()) 
    { 
     formDao.save();   
    } 
    else 
    { 
     return viewForm(form); 
    } 
    return null; 
} 

risposta

24

il lavoro di @SessionAttribute è quello di legare un oggetto modello esistente alla sessione. Se non esiste ancora, è necessario definirlo. E 'inutilmente confusa, a mio parere, ma provare qualcosa di simile:

@SessionAttributes({"form"}) 
@Controller 
public class MyController { 

    @RequestMapping(value="form", method=RequestMethod.GET) 
    public ModelAndView viewForm(@ModelAttribute("form") Form form) { 
     ModelAndView mav = new ModelAndView("form");  
     if(form == null) form = new Form(); 
     mav.addObject("form", form); 
     return mav; 
    } 

    @RequestMapping(value="form", method=RequestMethod.POST) 
    @Transactional(readOnly = true) 
    public ModelAndView saveForm(@ModelAttribute("form") Form form) { 
     // ..etc etc 
    } 
} 

Si noti che il @SessionAttributes è dichiarato sulla classe, piuttosto che il metodo. Puoi metterlo dove vuoi, davvero, ma penso che abbia più senso in classe.

The documentation on this potrebbe essere molto più chiaro, a mio parere.

+0

Mi ha aiutato ma, la sua eccezione di lancio se chiamato la prima volta. – digz6666

+0

@ digz6666, vedere [# SPR-4452] (https://jira.springsource.org/browse/SPR-4452) –

+6

Sarebbe utile se la primavera implementasse un'annotazione di parametro metodo che consentisse l'accesso agli attributi di sessione (nel allo stesso modo puoi accedere ai parametri della richiesta). 'public void doSometing (@SessionAttribute (" cat ") Cat cat) {' –

32

Genera eccezione se il controller ha chiamato la prima volta anche se ha aggiunto @SessionAttributes ({"form"}) alla classe. Quindi aggiungere il seguente metodo populateForm risolverà questo problema.

@SessionAttributes({"form"}) 
@Controller 
public class MyController { 

    @ModelAttribute("form") 
    public Form populateForm() { 
     return new Form(); // populates form for the first time if its null 
    } 

    @RequestMapping(value="form", method=RequestMethod.GET) 
    public ModelAndView viewForm(@ModelAttribute("form") Form form) { 
     ModelAndView mav = new ModelAndView("form");  
     if(form == null) form = new Form(); 
     mav.addObject("form", form); 
     return mav; 
    } 

    @RequestMapping(value="form", method=RequestMethod.POST) 
    @Transactional(readOnly = true) 
    public ModelAndView saveForm(@ModelAttribute("form") Form form) { 
     // ..etc etc 
    } 
} 
+12

+1, questo è il miglior rimedio che ho visto finora, fino a quando primavera decide di aggiungere '@ModelAttribute (required = false)'. –

+0

Grazie per il suggerimento, stava davvero iniziando a essere un mal di testa – nMoncho

+0

Sì, il metodo populateForm era la chiave per me nella risoluzione di questo. Vorrei che la documentazione di primavera fosse un po 'più chiara :( – Jalpesh

1

se non v'è oggetto di sessione definito quindi penso che sta andando essere come questo:

@SessionAttributes({"form"}) 
    @Controller 
    public class MyController { 
    @RequestMapping(value="form", method=RequestMethod.GET) 
    public ModelAndView viewForm() { 
     ModelAndView mav = new ModelAndView("form");  
     if(form == null) form = new Form(); 
     mav.addObject("form", form); 
     return mav; 
    } 

    @RequestMapping(value="form", method=RequestMethod.POST) 
    @Transactional(readOnly = true) 
    public ModelAndView saveForm(@ModelAttribute("form") Form form) { 
     // ..etc etc 
    } 
} 
0

sto lottando con questo. Ho letto questo post e mi ha fatto alcune cose chiare:

Set session variable spring mvc 3

Per quanto ho capito questo in sostanza dice:

  • che la primavera mette gli oggetti specificati dal @SessionAttributes nella sessione solo per la durata tra la prima richiesta GET e la richiesta POST che viene dopo. Successivamente l'oggetto viene rimosso dalla sessione. L'ho provato in una piccola applicazione e ha approvato la dichiarazione.

Quindi, se si desidera che gli oggetti durino più a lungo in più richieste GET e POST, sarà necessario aggiungerli manualmente a HttpSession, come al solito.

1
@Controller 
@SessionAttributes("goal") 
public class GoalController { 

    @RequestMapping(value = "/addGoal", method = RequestMethod.GET) 
    public String addGoal(Model model) { 
     model.addAttribute("goal", new Goal(11)); 
     return "addGoal"; 
    } 

    @RequestMapping(value = "/addGoal", method = RequestMethod.POST) 
    public String addGoalMinutes(@ModelAttribute("goal") Goal goal) { 
     System.out.println("goal minutes " + goal.getMinutes()); 
     return "addMinutes"; 
    } 
} 

Nella pagina addGoal.jsp l'utente inserisce qualsiasi importo e invia la pagina.importo iscritto viene memorizzato in HTTP sessione a causa di

@ModelAttribute("goal") Goal goal 

e

@SessionAttributes ("obiettivo")

Senza @ModelAttribute ("obiettivo") importo iscritto dall'utente a pagina addGoal sarebbe perduto

Problemi correlati