2009-09-03 11 views
13

W jakich okolicznościach akta @SessionAttributes zostają wyczyszczone? Podczas próby użycia dwóch modeli na stronie odkryłem pewne niejasne zachowanie.Kiedy zostaną usunięte @SessionAttributes w SpringMVC? (Z próbką kodu)

Kiedy zrobić GET POST a następnie za pomocą tego kontrolera ...

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

... object2 zostanie usunięte z modelu. Nie istnieje już jako @ AkcjaAtrybut i nie można uzyskać do niej dostępu na mojej stronie widoku.

Jednak jeśli podpis drugiego sposobu jest modyfikowany do tego ...

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

... potem object2 nie uzyskać usunięte z modelu i jest dostępny na mojej stronie widoku.

Javadoc dla @SessionAttributes mówi:

... atrybuty zostaną usunięte po handler wskazuje zakończenie jego konwersacji sesji.

Ale nie widzę, jak wskazałem zakończenie sesji konwersacji w pierwszym przykładzie, ale nie w drugim przykładzie.

Czy ktoś może wyjaśnić to zachowanie lub jest to błąd?

+0

Ten problem został rozwiązany w Spring 3.0RC1. Zobacz http://jira.springsource.org/browse/SPR-6084 Dzięki Juergen! –

Odpowiedz

14

wskazać zakończenie rozmowy przez wywołanie

SessionStatus.setComplete

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

powiedział, że nie widzę, dlaczego warto być tracąc jeden atrybut modelu, a nie inny.

Czy próbowali robić coś takiego:

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

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

i zobaczyć, jak to porównuje objęcia atrybuty w modelu ręcznie.

+1

Próbowałem Twojej sugestii - i zadziwiająco działa! Teraz jestem naprawdę zdezorientowany. Dlaczego istnieje różnica w ręcznym ustawianiu atrybutu modelu i ustawianiu go za pomocą @ModelAttribute? –

+2

Niestety, zrobiłem boo-boo. Z pliku referencyjnego (3.0.0.M3): "Uwaga: Metody oznaczone adnotacją @ModelAttribute zostaną wykonane przed wybraną metodą obsługi przypisanej adnotacji @RequestMapping". Tak więc powodem działania jest to, że metody object1 i object2 są wykonywane przed metodami get i post. To może być to, czego chcesz, ale podejrzewam, że nie. – ptomli

+0

Tak, zdałem sobie sprawę, że zaraz po opublikowaniu mojego komentarza. Mogę to podnieść ze Spring, ponieważ nie widzę żadnego rozsądnego wytłumaczenia tego zachowania. –

1

można usunąć pojedynczy ModelAttribute poziomu sesji tak:

Biorąc ModelMap model, HttpSession session i zrobić:

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