2013-06-13 10 views
5

Dla uproszczenia te fragmenty kodu zostaną skrócone. Ma to na celu pobranie parametru GET, ustawienie go w sesji i przekierowanie z powrotem do GET z usuniętym parametrem url. Zasadniczo, czyszczenie URI. Jeśli jest lepszy/prostszy sposób na zrobienie tego, byłbym zadowolony, słysząc to.Dlaczego atrybuty SessionAttributes są wyczyszczone w przekierowaniu GET?

Mam kontroler zdefiniowany jako takie:

@Controller 
@RequestMapping("/path/page.xhtml") 
@Scope(BeanDefinition.SCOPE_PROTOTYPE) 
@SessionAttributes({ "myParam1", "myParam2" }) 
public class MyController { 

    @RequestMapping(method = RequestMethod.GET, params = { "urlParam2" }) 
    public String handleUriParam(@RequestParam(value = "urlParam2", required = false) 
           final Long urlParam2, 
           final RedirectAttributes redirs) { 
    // at this point, myParam1 is set on the session. 
    // now set the param as a flash attrib with the name of the session variable 
    redirs.addFlashAttribute("myParam2", urlParam2); 
    return "redirect:/path/page.xhtml"; 
    } 

    @RequestMapping(method = RequestMethod.GET, params = {}) 
    public String doGetStuff(ModelMap model) { 
    // do stuff using myParam1 and myParam2. 
    // problem is, myParam2 is on the session, but myParam1 is not! 
    } 

} 

jak kod mówi, jakoś myParam1 jest istota un-set, gdy przekierowanie dzieje. Mogę to naprawić, przekazując ModelMap do metody handleUrlParam i ręcznie dodając myParam1 do atrybutów flash, ale wydaje mi się, że w moim umyśle pokonałem cel.

Dlaczego usunięto SessionAttributemyParam1 po przekierowaniu?

Czy istnieje lepszy sposób na pobieranie parametrów z identyfikatora URI i umieszczanie ich w sesji?

UPDATE

Wygląda więc na to, że przy każdym użyciu RedirectAttributes w ogóle, należy upewnić się, można umieścić dowolny SessionAttribute s chcesz nosić do przekierowania na FlashAttributes albo zostaną one utracone. Wyobrażam sobie, że tak się dzieje, ponieważ SessionAttribute s są ściągane z ModelMap (która jest zastępowana przez FlashAttributes, gdy jest używana). Czy to błąd na wiosnę czy zamierzone zachowanie? Jeśli jest to celowe, czy ktoś może wyjaśnić dlaczego? Myślałem, że powinny pozostać włączone, dopóki nie zostaną usunięte po zakończeniu sesji konwersacji.

Similar StackOverflow post here.

Uzupełnienie

W świetle przyjętej odpowiedzi udzielonej, nadal jestem zakłopotany, jak mogę usunąć parametry URI kładąc je na sesji użytkownika. Jedną z opcji, którą rozważałem, jest utworzenie wrappera dla obiektów półpreparatywnych (java.lang.Integer, java.lang.String) Próbuję przechowywać, ponieważ nie zostaną one umieszczone w łańcuchu URI, ale wydaje się, że jest to hacky mnie. Jeśli ktokolwiek ma lepszy sposób na zaakceptowanie parametrów GET, zapisanie ich w sesji użytkownika i wyczyszczenie ich z paska adresu użytkownika (co będzie wymagać przekierowania), chętnie go użyję.

+0

Nie wiem, co robisz źle, ale właśnie replikowałem twoją konfigurację i działa zgodnie z oczekiwaniami. Oba atrybuty kończą się na sesji (co może być dziwne dla drugiego, ponieważ miał być atrybutem flash). –

+0

Nieparzysta. Zasadniczo poddałem się i ustawiłem oba jako atrybuty flash i działa dobrze. W pewnym sensie jest to sprzeczne z celem używania '@ SessionAttribute', ale dla zwykłych żądań' GET' działa zgodnie z oczekiwaniami. Dzięki za zaglądanie w to. – Andy

+0

Coś, o czym właśnie pomyślałem, różni się od konfiguracji większości ludzi, to użycie 'BeanDefinition.SCOPE_PROTOTYPE'. Czy używałeś tego i nadal otrzymujesz poprawne zachowanie? Jestem ciekawy, czy tworzenie/używanie nowego obiektu kontrolera może być częścią problemu tutaj. Ze względu na nasze interceptory i strukturę kontrolera musimy używać świeżych obiektów, ale to była tylko myśl, czy może to być wina mojego dziwnego zachowania. – Andy

Odpowiedz

5

Szukałem więc kodu i Internetu, aby dowiedzieć się, dlaczego to nie działa.

Wiosna ma dwie całkowicie oddzielne mapy modeli - jedną do renderowania w widoku standardowym, a drugą po wydaniu przekierowania. Można to zaobserwować w ModelAndViewContainer.

Zachowanie atrybutów sesji trwa based on the result from mavContainer#getModel(). W przypadku scenariuszy przekierowań zwraca to model przekierowania. W związku z tym wszystko, co ustawisz w standardzie, zostanie utracone.

Ma to sens, gdy mówimy o standardowych atrybutach modelu. Model służy głównie do przekazywania obiektów do widoków. Podczas korzystania z przekierowań masz do czynienia z zupełnie inną sytuacją. Chcesz przenosić obiekty przez przekierowanie HTTP - stąd oddzielony ciąg znaków i model oparty na pamięci flash.

Jednak mam wrażenie, że zapomnieli o atrybutach sesji, gdy designing this feature. Jest kilka fajnych discussion in Spring's Jira, jednak żadna z nich nie rozwiązuje tego problemu.

Tak, tak ... to może być temat wiosennej Jiry. I to może zostać sklasyfikowany jako błąd, ponieważ zapobiega to ustawianiu atrybutów modelu sesji podczas korzystania z przekierowania. Zmuszanie Springa do przechowywania atrybutu sesji przez RedirectAttributes#addFlashAttribute jest IMO hackem i rodzajem błędu na własnym.

+0

Chociaż zgadzam się z twoim komentarzem na temat tego, że jest hackerem, nadal muszę wyczyścić parametry URI z paska adresu użytkownika. Czy jest mniej "hacky" to zrobić, niż jak obecnie próbuję? – Andy

+0

Dziękuję również za rozpatrzenie tego. Twoje wyjaśnienie jest bardzo dokładne i ma sens. :) – Andy

Powiązane problemy