2013-06-13 10 views
5

Der Einfachheit halber werden diese Code-Snippets gekürzt. Der Zweck davon ist, einen GET-Parameter zu nehmen, ihn für die Sitzung zu setzen und mit dem entfernten URL-Parameter zurück zum GET zu leiten. Im Grunde, URI-Bereinigung. Wenn es einen besseren/einfacheren Weg gibt, dies zu tun, würde ich mich freuen, es zu hören.Warum werden SessionAttributes bei GET Redirect gelöscht?

Ich habe einen Controller als solche definiert:

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

} 

Wie der Code sagt, irgendwie myParam1 wird un-Set, wenn die Umleitung erfolgt. Ich kann das beheben, indem ich eine ModelMap an die handleUrlParam Methode übergebe und manuell myParam1 zu den Flash-Attributen hinzufüge, aber das scheint den Zweck in meinen Gedanken zu besiegen.

Warum wird die SessionAttributemyParam1 nach der Weiterleitung entfernt?

Gibt es eine bessere Möglichkeit, Parameter aus dem URI zu ziehen und sie in die Sitzung zu setzen?

UPDATE

So scheint es, dass, wann immer Sie RedirectAttributes überhaupt verwenden zu können, müssen Sie alle SessionAttribute s Sie auf den FlashAttributes in die Umleitung tragen wollen sicherstellen, setzen oder sonst gehen sie verloren. Ich stelle mir vor, dies passiert, weil SessionAttribute s von der ModelMap (die durch FlashAttributes bei der Verwendung ersetzt wird) gezogen werden. Ist das ein Fehler im Frühling oder absichtliches Verhalten? Wenn es beabsichtigt ist, kann jemand erklären warum? Ich dachte, SessionAttribute s sollten bis zum Abschluss der Konversationssitzung eingeschaltet bleiben.

Similar StackOverflow post here.

Nachtrag

Im Lichte der akzeptierten Antwort vorgesehen ist, bin ich immer noch so ratlos, wie ich die URI-Parameter löschen kann, während sie auf der Sitzung des Benutzers setzen. Eine Option, die ich in Betracht gezogen habe, ist, einen Wrapper für die semi-primitiven Objekte (java.lang.Integer, java.lang.String) zu erstellen, die ich speichern möchte, weil sie nicht in die URI-Zeichenkette eingefügt werden, aber das scheint Hacky zu sein mich. Wenn jemand GET-Parameter besser akzeptiert, sie in der Benutzersitzung speichert und diese aus der Adressleiste des Benutzers löscht (was eine Umleitung erfordert), werde ich sie gerne verwenden.

+0

Ich weiß nicht, was Sie falsch machen, aber ich habe nur Ihre Konfiguration repliziert und es funktioniert wie erwartet. Beide Attribute enden in der Sitzung (was für den zweiten seltsam sein könnte, da es ein Flash-Attribut sein sollte). –

+0

Ungerade. Ich gab im Grunde nach und legte beide als Flash-Attribute und es funktioniert gut. Es vereitelt den Zweck der Verwendung von '@ SessionAttribute', aber für reguläre' GET' Anfragen funktioniert es wie erwartet. Danke, dass du dich darum gekümmert hast. – Andy

+0

Etwas, das ich gerade dachte, unterscheidet sich von den meisten Menschen Konfigurationen ist die Verwendung von 'BeanDefinition.SCOPE_PROTOTYPE'. Hast du das benutzt und hast immer noch richtiges Verhalten? Ich bin neugierig, ob die Erstellung/Verwendung eines neuen Controller-Objekts hier Teil des Problems sein könnte. Aufgrund unserer Abfangjäger- und Kontrollerstruktur müssen wir frische Objekte verwenden, aber es war nur ein Gedanke, ob es für mein eigenartiges Verhalten verantwortlich sein könnte. – Andy

Antwort

5

Also sah ich mir den Code und das Internet an, um herauszufinden, warum es nicht funktioniert.

Spring verfügt über zwei vollständig separate Modellkarten - eine für die Standardansichtsdarstellung und die andere, wenn eine Umleitung ausgegeben wird. Dies kann in ModelAndViewContainer beobachtet werden.

Die Persistenz des Sitzungsattributs ist nun based on the result from mavContainer#getModel(). Bei Umleitungsszenarien gibt dies das Umleitungsmodell zurück. Daher ist alles, was Sie auf dem Standard setzen Model/ModelMap ist verloren.

Dies ist sinnvoll, wenn über Standardmodellattribute gesprochen wird. Das Modell dient hauptsächlich dazu, Objekte an Ansichten zu übergeben. Bei der Verwendung von Weiterleitungen handelt es sich um eine völlig andere Situation. Sie möchten Objekte per HTTP-Redirect übertragen - daher das getrennte string- und flashbasierte Modell.

Allerdings habe ich das Gefühl, dass sie Session-Attribute vergessen haben, wenn designing this feature. Es gibt einige nette discussion in Spring's Jira, aber keiner von ihnen adressiert dieses spezifische Problem.

Also ja ... das könnte ein Thema für Spring's Jira sein. Und es kann als Fehler klassifiziert werden, da dies verhindert, dass jemand Sitzungsmodellattribute bei Verwendung von Redirect festlegen kann. Forcing Spring, um Ihre Sitzung Attribut über RedirectAttributes#addFlashAttribute zu speichern ist IMO ein Hack und eine Art Bug auf eigene.

+0

Während ich mit Ihrem Kommentar darüber einverstanden bin, dass es sich um einen Hack handelt, muss ich die URI-Parameter immer noch aus der Adresszeile des Benutzers entfernen. Gibt es einen weniger "hacky" Weg dies zu tun als wie ich es gerade versuche? – Andy

+0

Auch, danke, dass Sie sich das angeschaut haben. Ihre Erklärung ist sehr gründlich und macht vollkommen Sinn. :) – Andy

Verwandte Themen