Come utilizzare gli attributi di sessione in Spring-mvc


108

Potresti aiutarmi a scrivere l'analogo in stile Spring mvc di questo codice?

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

E come aggiungere un elemento annotato tramite @ModelAttributeannotazione alla sessione e quindi accedervi?

Risposte:


185

Se vuoi eliminare un oggetto dopo ogni risposta non hai bisogno della sessione,

Se vuoi mantenere l'oggetto durante la sessione utente, ci sono alcuni modi:

  1. aggiungi direttamente un attributo alla sessione:

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

    e puoi ottenerlo dal controller in questo modo:

    ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");
  2. Rendi la sessione del controller con ambito

    @Controller
    @Scope("session")
  3. Definisci l'ambito degli oggetti, ad esempio hai un oggetto utente che dovrebbe essere in sessione ogni volta:

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

    quindi inserisci la classe in ogni controller che desideri

       @Autowired
       private User user

    che mantiene la classe in sessione.

  4. L'iniezione di proxy AOP: in primavera -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>

    quindi inserisci la classe in ogni controller che desideri

    @Autowired
    private User user

5.Pass HttpSession al metodo:

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

6.Make ModelAttribute nella sessione di @SessionAttributes ("ShoppingCart"):

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

oppure puoi aggiungere il modello all'intera classe controller come,

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

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

ognuno ha vantaggio e svantaggio:

@session può utilizzare più memoria nei sistemi cloud, copia la sessione su tutti i nodi e il metodo diretto (1 e 5) ha un approccio disordinato, non va bene lo unit test.

Per accedere alla sessione jsp

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

in Jstl:

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

in Foglia di timone:

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

6
3. Se il controller è singleton, è necessario definire proxyMode = ScopedProxyMode.TARGET_CLASS per il componente iniettato con ambito di sessione. @Scope (value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
Vadim Kolesnikov,

1
Rendere la sessione del controller con scope è l'opzione peggiore qui, anche se all'inizio sembra semplice e facile da usare. Ma se vuoi ridimensionare la tua applicazione in futuro, ti imbatterai in problemi poiché probabilmente avrai bisogno di un archivio di sessioni distribuito come Redis (a meno che non utilizzi sessioni permanenti, sacrificando la disponibilità per comodità). Pertanto, i bean con ambito di sessione dovrebbero generalmente essere POJO serializzabili stupidi. In questo modo sei pronto per lo scale-out in caso di necessità.
chris

Che dire di RequestContextHolder?
user1589188

L'iniezione del Userbean funzionerà solo se si sta chiamando il bean in una classe che è anch'essa con sessionscope, altrimenti se non esiste alcuna sessione, verrà generata un'eccezione poiché non ci sarebbe alcuna sessione attiva nel contesto @ runtime quando iniettiamo il userbean in un'altra classe !!
Jose Mhlanga il

41

Uso @SessionAttributes

Vedere la documentazione: Utilizzo di @SessionAttributes per memorizzare gli attributi del modello nella sessione HTTP tra le richieste

" Comprensione del modello Spring MVC e degli attributi di sessione " fornisce anche un'ottima panoramica delle sessioni Spring MVC e spiega come / quando i messaggi di posta @ModelAttributeelettronica vengono trasferiti nella sessione (se il controller è @SessionAttributesannotato).

L'articolo spiega anche che è meglio usare @SessionAttributessul modello invece di impostare gli attributi direttamente su HttpSession perché ciò aiuta Spring MVC a essere indipendente dalla visualizzazione.


Come puoi sfruttare i sessionAttributes per trasferire oggetti tra controller?
larrytech

27

SessionAttributel'annotazione è la più semplice e diretta invece di ottenere la sessione dall'oggetto richiesta e dall'impostazione dell'attributo. Qualsiasi oggetto può essere aggiunto al modello nel controller e verrà memorizzato nella sessione se il suo nome corrisponde all'argomento nell'annotazione @SessionAttributes. Di seguito, ad esempio, personObjsarà disponibile in sessione.

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

}

le sessioni funzionano solo per le richieste all'interno della stessa istanza del controller. Se il controllo deve essere inviato a un altro controller, questa sessione verrà distrutta e se necessario ne verrà creata una nuova.
larrytech

1
@larrytech come potrebbe essere? Penso che tu abbia appena dimenticato di aggiungere SessionAttributes al tuo secondo controller
Yura

19

Il codice annotato di seguito imposterebbe "valore" su "nome"

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

Per accedere allo stesso in JSP utilizzare ${sessionScope.name}.

Per @ModelAttributevedere questo link


4

Non è più facile e più breve in questo modo? Lo sapevo e l'ho appena testato - funziona perfettamente qui:

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

ps Sono venuto qui cercando una risposta su " Come usare gli attributi di sessione in Spring-mvc ", ma ne ho letti tanti senza vedere il più ovvio che avevo scritto nel mio codice. Non l'ho visto, quindi ho pensato che fosse sbagliato, ma no, non lo era. Quindi condividiamo quella conoscenza con la soluzione più semplice per la domanda principale.


1
Hai ragione ! questo è quello che stavo pensando dato che puoi accedere a tutti gli oggetti Http di cui abbiamo bisogno direttamente quando li dichiari nei metodi del controller (richiesta GET / POST)
Shessuky

1

Prova questo...

@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

Quando provo al mio accesso (che è un modale bootstrap), ho usato l'annotazione @sessionattributes. Ma il problema era quando la vista è un reindirizzamento ("reindirizzamento: / home"), i valori che ho inserito nella sessione vengono visualizzati nell'URL. Alcune fonti Internet suggeriscono di seguire http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#mvc-redirecting Ma ho usato invece HttpSession. Questa sessione sarà disponibile fino alla chiusura dei browser. Ecco il codice di esempio

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

Non si cambia cosa specifica sul lato di visualizzazione.

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

Dopo il login, aggiungi i codici di cui sopra in qualsiasi punto del tuo sito web. Se la sessione è impostata correttamente, vedrai i valori lì. Assicurati di aver aggiunto correttamente i tag jstl e le espressioni El (ecco il link per impostare i tag jstl https://menukablog.wordpress.com/2016/05/10/add-jstl-tab-library-to-you-project- correttamente / )


0

Usa Questo metodo molto semplice facile da usare

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

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

in jsp una volta utilizzare quindi rimuovere

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

0

In Spring 4 Web MVC. È possibile utilizzare @SessionAttributenel metodo con @SessionAttributesin Livello controller

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

    GetMapping("/showOrder")
    public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
     // method body
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.