Verwendung von Sitzungsattributen in Spring-mvc


108

Könnten Sie mir helfen, Analog zu diesem Code im Spring MVC-Stil zu schreiben?

 session.setAttribute("name","value");

Und wie füge @ModelAttributeich der Sitzung ein Element hinzu, das mit Anmerkungen versehen ist, und erhalte dann Zugriff darauf?

Antworten:


185

Wenn Sie nach jeder Antwort ein Objekt löschen möchten, benötigen Sie keine Sitzung.

Wenn Sie das Objekt während der Benutzersitzung behalten möchten, gibt es verschiedene Möglichkeiten:

  1. Fügen Sie der Sitzung direkt ein Attribut hinzu:

    @RequestMapping(method = RequestMethod.GET)
    public String testMestod(HttpServletRequest request){
       ShoppingCart cart = (ShoppingCart)request.getSession().setAttribute("cart",value);
       return "testJsp";
    }

    und Sie können es von Controller wie folgt erhalten:

    ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");
  2. Machen Sie Ihre Controller-Sitzung umfangreich

    @Controller
    @Scope("session")
  3. Umfang der Objekte, z. B. haben Sie ein Benutzerobjekt, das sich jedes Mal in der Sitzung befinden sollte:

    @Component
    @Scope("session")
    public class User
     {
        String user;
        /*  setter getter*/
      }

    Fügen Sie dann Klasse in jeden Controller ein, den Sie möchten

       @Autowired
       private User user

    das hält den Unterricht in der Sitzung.

  4. Die AOP-Proxy-Injektion: im Frühjahr -xml:

    <beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
      <bean id="user"    class="com.User" scope="session">     
          <aop:scoped-proxy/>
      </bean>
    </beans>

    Fügen Sie dann Klasse in jeden Controller ein, den Sie möchten

    @Autowired
    private User user

5.Pass HttpSession to method:

 String index(HttpSession session) {
            session.setAttribute("mySessionAttribute", "someValue");
            return "index";
        }

6.Make ModelAttribute in Sitzung von @SessionAttributes ("ShoppingCart"):

  public String index (@ModelAttribute("ShoppingCart") ShoppingCart shoppingCart, SessionStatus sessionStatus) {
//Spring V4
//you can modify session status  by sessionStatus.setComplete();
}

oder Sie können Modell zur gesamten Controller-Klasse hinzufügen, wie z.

@Controller
    @SessionAttributes("ShoppingCart")
    @RequestMapping("/req")
    public class MYController {

        @ModelAttribute("ShoppingCart")
        public Visitor getShopCart (....) {
            return new ShoppingCart(....); //get From DB Or Session
        }  
      }

Jeder hat Vor- und Nachteile:

@session verwendet möglicherweise mehr Speicher in Cloud-Systemen, kopiert die Sitzung auf alle Knoten, und die direkte Methode (1 und 5) hat einen chaotischen Ansatz. Ein Unit-Test ist nicht sinnvoll.

So greifen Sie auf die Sitzung jsp zu

<%=session.getAttribute("ShoppingCart.prop")%>

in Jstl:

<c:out value="${sessionScope.ShoppingCart.prop}"/>

in Thymeleaf:

<p th:text="${session.ShoppingCart.prop}" th:unless="${session == null}"> . </p>

6
3. Wenn Ihr Controller Singleton ist, müssen Sie proxyMode = ScopedProxyMode.TARGET_CLASS für injizierte Komponenten mit Sitzungsbereich definieren. @Scope (value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
Vadim Kolesnikov

1
Das Festlegen des Bereichs der Controller-Sitzung ist hier die schlechteste Option, obwohl sie zunächst einfach und benutzerfreundlich aussieht. Wenn Sie Ihre Anwendung jedoch in Zukunft skalieren möchten, treten Probleme auf, da Sie wahrscheinlich einen verteilten Sitzungsspeicher wie Redis benötigen (es sei denn, Sie verwenden Sticky-Sitzungen und opfern die Verfügbarkeit aus Bequemlichkeitsgründen). Daher sollten Beans mit Sitzungsbereich im Allgemeinen dumme serialisierbare POJOs sein. Auf diese Weise sind Sie auf das Scale-out vorbereitet, falls dies erforderlich sein sollte.
Chris

Was ist mit RequestContextHolder?
user1589188

Das Injizieren der UserBean funktioniert nur, wenn Sie die Bean in einer Klasse aufrufen, für die ebenfalls ein sessionGültigkeitsbereich besteht. Wenn sonst keine Sitzung vorhanden ist, wird eine Ausnahme ausgelöst, da im Kontext @runtime keine aktive Sitzung vorhanden ist, wenn die userBean in eine andere Klasse injiziert wird !!
Jose Mhlanga vor

41

Verwenden @SessionAttributes

Weitere Informationen finden Sie in den Dokumenten: Verwenden von @SessionAttributes zum Speichern von Modellattributen in der HTTP-Sitzung zwischen Anforderungen

" Grundlegendes zu Spring MVC-Modell und Sitzungsattributen " bietet auch einen sehr guten Überblick über Spring MVC-Sitzungen und erklärt, wie / wann @ModelAttributes in die Sitzung übertragen werden (wenn der Controller mit @SessionAttributesAnmerkungen versehen ist).

In diesem Artikel wird auch erläutert, dass es besser ist, @SessionAttributesdas Modell zu verwenden, als Attribute direkt in der HttpSession festzulegen, da dies Spring MVC dabei hilft, ansichtsunabhängig zu sein.


Wie können Sie die sessionAttributes nutzen, um Objekte zwischen Controllern zu übertragen?
Larrytech

27

SessionAttributeAnnotation ist am einfachsten und unkompliziertesten, anstatt eine Sitzung vom Anforderungsobjekt und vom Einstellungsattribut abzurufen. Jedes Objekt kann dem Modell in der Steuerung hinzugefügt werden und wird in der Sitzung gespeichert, wenn sein Name mit dem Argument in der @SessionAttributesAnmerkung übereinstimmt . Im Folgenden wird zB personObjin der Sitzung verfügbar sein.

@Controller
@SessionAttributes("personObj")
public class PersonController {

    @RequestMapping(value="/person-form")
    public ModelAndView personPage() {
        return new ModelAndView("person-page", "person-entity", new Person());
    }

    @RequestMapping(value="/process-person")
    public ModelAndView processPerson(@ModelAttribute Person person) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("person-result-page");

        modelAndView.addObject("pers", person);
        modelAndView.addObject("personObj", person);

        return modelAndView;
    }

}

Sitzungen funktionieren nur für Anforderungen innerhalb derselben Controller-Instanz. Was passiert, wenn die Steuerung an einen anderen Controller gesendet werden muss? Diese Sitzung wird zerstört und bei Bedarf eine neue erstellt.
Larrytech

1
@larrytech wie könnte es sein? Ich denke, Sie haben gerade vergessen, SessionAttributes zu Ihrem zweiten Controller hinzuzufügen
Yura

19

Der unten angegebene kommentierte Code würde "Wert" auf "Name" setzen.

@RequestMapping("/testing")
@Controller
public class TestController {
@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request){
    request.getSession().setAttribute("name", "value");
    return "testJsp";
  }
}

Um in JSP darauf zuzugreifen, verwenden Sie ${sessionScope.name}.

Für den @ModelAttributesiehe diesen Link


4

Ist es nicht so einfach und am kürzesten ? Ich wusste es und habe es einfach getestet - hier funktioniert es perfekt:

@GetMapping
public String hello(HttpSession session) {
    session.setAttribute("name","value");
    return "hello";
}

ps Ich bin hierher gekommen, um nach einer Antwort auf " Verwendung von Sitzungsattributen in Spring-mvc " zu suchen , habe aber so viele gelesen, ohne das offensichtlichste zu sehen, das ich in meinen Code geschrieben hatte. Ich habe es nicht gesehen, also dachte ich, es sei falsch, aber nein, das war es nicht. Teilen wir dieses Wissen mit der einfachsten Lösung für die Hauptfrage.


1
Du hast recht ! Das habe ich mir gedacht, da Sie auf alle HTTP-Objekte zugreifen können, die wir direkt benötigen, wenn Sie sie in Controller-Methoden deklarieren (GET / POST-Anforderung)
Shessuky

1

Versuche dies...

@Controller
@RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {

    @ModelAttribute("types")

    public Collection<PetType> populatePetTypes() {
        return this.clinic.getPetTypes();
    }

    @RequestMapping(method = RequestMethod.POST)
    public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
        new PetValidator().validate(pet, result);
        if (result.hasErrors()) {
            return "petForm";
        }else {
            this.clinic.storePet(pet);
            status.setComplete();
            return "redirect:owner.do?ownerId="
                + pet.getOwner().getId();
        }
    }
}

0

Beim Versuch, mich anzumelden (was ein Bootstrap-Modal ist), habe ich die Annotation @sessionattributes verwendet. Das Problem war jedoch, dass es sich bei der Ansicht um eine Umleitung handelt ("Weiterleitung: / home"). Die Werte, die ich in die Sitzung eingegeben habe, werden in der URL angezeigt. Einige Internetquellen schlagen vor, http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#mvc-redirecting zu folgen. Stattdessen habe ich die HttpSession verwendet. Diese Sitzung wird so lange stattfinden, bis Sie die Browser schließen. Hier ist ein Beispielcode

        @RequestMapping(value = "/login")
        @ResponseBody
        public BooleanResponse login(HttpSession session,HttpServletRequest request){
            //HttpServletRequest used to take data to the controller
            String username = request.getParameter("username");
            String password = request.getParameter("password");

           //Here you set your values to the session
           session.setAttribute("username", username);
           session.setAttribute("email", email);

          //your code goes here
}

Sie ändern nichts auf der Ansichtsseite.

<c:out value="${username}"></c:out>
<c:out value="${email}"></c:out>

Fügen Sie nach der Anmeldung die oben genannten Codes an einer beliebigen Stelle auf Ihrer Website hinzu. Wenn die Sitzung korrekt eingestellt ist, werden dort die Werte angezeigt. Stellen Sie sicher , dass Sie die jstl Tags und El- Ausdrücke korrekt hinzugefügt (Hier Link zum Set jstl Tags https://menukablog.wordpress.com/2016/05/10/add-jstl-tab-library-to-you-project- richtig / )


0

Verwendung Diese Methode ist sehr einfach und benutzerfreundlich

HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getNativeRequest();

                                                            request.getSession().setAttribute("errorMsg", "your massage");

in jsp einmal verwenden, dann entfernen

<c:remove var="errorMsg" scope="session"/>      

0

Im Frühjahr 4 Web MVC. Sie können @SessionAttributein der Methode mit @SessionAttributesin Controller-Ebene verwenden

@Controller
@SessionAttributes("SessionKey")
public class OrderController extends BaseController {

    GetMapping("/showOrder")
    public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
     // method body
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.