2010-05-03 10 views
22

Mam obiekt formularza, który ustawiłem do żądania w obsłudze żądania GET w moim kontrolerze Spring. Pierwszy użytkownik, który wchodzi na stronę, powinien utworzyć nowy obiekt formularza i ustawić żądanie. Jeśli użytkownik wysyła formularz, to obiekt formularza jest wypełniany z żądania, a teraz obiekt formularza ma wszystkie atrybuty użytkownika. Następnie formularz jest sprawdzany i jeśli sprawdzanie poprawności jest prawidłowe, formularz jest zapisywany w bazie danych. Jeśli formularz nie jest sprawdzany, chcę zapisać obiekt formularza do sesji, a następnie przekierować do strony obsługi żądań GET. Po przekierowaniu żądania do modułu obsługi GET należy sprawdzić, czy sesja zawiera obiekt formularza.Spring Framework 3 i atrybuty sesji

I zorientowali się, że nie ma @SessionAttributes („Formularz”) adnotacji na wiosnę, ale z jakiegoś powodu po robi praca, bo w czasie pierwszego, forma atrybut sesja jest null i daje błąd:

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

Oto mój kontroler:

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

Odpowiedz

24

zadaniem @SessionAttribute jest powiązać istniejący obiekt modelu do sesji. Jeśli jeszcze nie istnieje, musisz go zdefiniować. To niepotrzebnie skomplikowane, moim zdaniem, ale spróbuj coś takiego:

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

Należy pamiętać, że @SessionAttributes jest zadeklarowany na klasy, a nie metody. Możesz umieścić to, gdzie chcesz, ale wydaje mi się, że ma to więcej sensu w klasie.

The documentation on this może być znacznie jaśniejsze, moim zdaniem.

+0

Pomogło mi to, ale wyjątek wyrzucania, jeśli został wywołany po raz pierwszy. – digz6666

+0

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

+6

Byłoby użyteczne, gdyby wiosna miała zaimplementować adnotację do parametru metody, która umożliwiała dostęp do atrybutów sesji (w w ten sam sposób można uzyskać dostęp do parametrów żądania). 'public void doSometing (@SessionAttribute (" cat ") Cat cat) {' –

32

Zgłasza wyjątek, jeśli kontroler zadzwonił po raz pierwszy, mimo że dodał @ SessionAtrybuty ({"formularz"}) do klasy. Więc dodaj następującą metodę populateForm naprawi to.

@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, jest to najlepsze obejście, jakie widziałem do tej pory, do wiosny postanawia dodać '@ModelAttribute (required = false)'. –

+0

Dzięki za podpowiedź To naprawdę zaczęło być bólem głowy – nMoncho

+0

Tak, metoda populateForm była dla mnie kluczem w rozwiązaniu tego problemu. Życzenie wiosny dokumentacji było nieco jaśniejsze :( – Jalpesh

1

jeśli nie ma zdefiniowany przedmiot sesja więc myślę To będzie tak:

@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

jestem zmaga się z tym również. Czytałem ten artykuł i to pewne rzeczy wyraźniej:

Set session variable spring mvc 3

O ile zrozumiałem, że to po prostu mówi:

  • że wiosna stawia obiekty określone przez @SessionAttributes do sesji tylko dla czas między pierwszym żądaniem GET a żądaniem POST, które następuje po nim. Następnie obiekt jest usuwany z sesji. Próbowałem go w małej aplikacji i zatwierdził oświadczenie.

Tak więc, jeśli chcesz mieć obiekty, które dłużej trwają przez wiele żądań GET i POST, będziesz musiał jak zwykle dodać je ręcznie do HttpSession.

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

Na stronie addGoal.jsp użytkownik wprowadza dowolną kwotę i przesyła stronę.Wysłany kwota jest przechowywana w sesji HTTP z powodu

@ModelAttribute("goal") Goal goal 

i

@SessionAttributes ("cel")

Bez @ModelAttribute ("cel") kwota wpisana przez użytkownika na stronie addGoal byłoby stracone

Powiązane problemy