Spring-mvc'de Oturum öznitelikleri nasıl kullanılır?


108

Bu kodun bahar mvc tarzı analogunu yazmama yardım eder misin?

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

Ve @ModelAttributeek açıklama ile not verilen bir öğeyi oturuma nasıl ekleyebilir ve sonra ona erişebilirsiniz?

Yanıtlar:


185

Her yanıttan sonra nesneyi silmek istiyorsanız oturuma ihtiyacınız yoktur,

Kullanıcı oturumu sırasında nesneyi tutmak istiyorsanız, bunun birkaç yolu vardır:

  1. doğrudan oturuma bir özellik ekleyin:

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

    ve bunu denetleyiciden şu şekilde edinebilirsiniz:

    ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");
  2. Denetleyici oturumunuzu kapsamlı hale getirin

    @Controller
    @Scope("session")
  3. Nesnelerin kapsamını belirleyin, örneğin her seferinde oturumda olması gereken kullanıcı nesneniz var:

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

    daha sonra istediğiniz her denetleyiciye sınıf enjekte edin

       @Autowired
       private User user

    bu dersi oturumda tutar.

  4. AOP proxy yerleştirme: bahar -xml'de:

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

    daha sonra istediğiniz her denetleyiciye sınıf enjekte edin

    @Autowired
    private User user

5. HttpSession'ı yönteme aktarın:

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

6. @SessionAttributes ("ShoppingCart") tarafından oturumda ModelAttribute yapın:

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

veya tüm Kontrolör Sınıfına Model ekleyebilirsiniz.

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

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

her birinin avantajı ve dezavantajı vardır:

@session bulut sistemlerinde daha fazla bellek kullanabilir, oturumu tüm düğümlere kopyalar ve direct method (1 ve 5) karmaşık bir yaklaşıma sahiptir, birim testi yapmak iyi değildir.

Jsp oturumuna erişmek için

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

Jstl'de:

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

Thymeleaf'ta:

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

6
3. Denetleyiciniz tekil ise, oturum kapsamına sahip enjekte edilen bileşen için proxyMode = ScopedProxyMode.TARGET_CLASS tanımlamanız gerekir. @Scope (value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
Vadim Kolesnikov

1
İlk başta basit ve kullanımı kolay görünse de, denetleyici oturumunu kapsamlı hale getirmek buradaki en kötü seçenektir. Ancak ileride uygulamanızı ölçeklendirmek istiyorsanız, muhtemelen Redis gibi dağıtılmış bir oturum deposuna ihtiyaç duyacağınız için sorun yaşarsınız (yapışkan oturumları kullanmazsanız, kolaylık sağlamak için kullanılabilirlikten ödün verirseniz). Bu nedenle, oturum kapsamlı fasulye genellikle aptal serileştirilebilir POJO'lar olmalıdır. Bu şekilde, ihtiyaç duyulması durumunda ölçeklendirmeye hazır olursunuz.
chris

Peki ya RequestContextHolder?
user1589188

Çekirdeği enjekte etmek User, yalnızca sessionkapsamı da belirlenmiş bir sınıfta fasulyeyi çağırıyorsanız işe yarar , aksi takdirde herhangi bir oturum yoksa, o zaman, userçekirdeği başka bir sınıfa enjekte ettiğimizde @runtime bağlamında herhangi bir aktif oturum olmayacağından istisna atar. !!
Jose Mhlanga

41

Kullanım @SessionAttributes

Dokümanlara bakın: Model özniteliklerini istekler arasında HTTP oturumunda depolamak için @SessionAttributes kullanma

" Bahar MVC Modelini ve Oturum Özelliklerini Anlamak " ayrıca Spring MVC oturumlarına çok iyi bir genel bakış sağlar ve oturumlara nasıl / ne zaman @ModelAttributeaktarıldığını açıklar (denetleyici@SessionAttributes açıklama eklenmişse).

Bu makale ayrıca @SessionAttributesöznitelikleri doğrudan HttpSession'da ayarlamak yerine modelde kullanmanın daha iyi olduğunu açıklar çünkü bu, Spring MVC'nin görünümden bağımsız olmasına yardımcı olur.


Nesneleri Denetleyiciler arasında aktarmak için sessionAttributes'dan nasıl yararlanabilirsiniz?
larrytech

27

SessionAttributeek açıklama, istek nesnesinden oturum almak ve özniteliği ayarlamak yerine en basit ve anlaşılır olanıdır. Denetleyicideki modele herhangi bir nesne eklenebilir ve adı @SessionAttributesaçıklamadaki bağımsız değişkenle eşleşirse oturumda saklanır . Aşağıda örneğin personObjoturumda mevcut olacaktır.

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

}

oturumlar yalnızca aynı denetleyici örneğindeki istekler için çalışır. Ya kontrolün başka bir kontrolöre gönderilmesi gerekiyorsa, bu oturum yok edilecek ve gerekirse yeni bir tane oluşturulacaktır.
larrytech

1
@larrytech nasıl olabilir? Sanırım ikinci kontrol cihazınıza SessionAttributes eklemeyi unuttunuz
Yura

19

Aşağıdaki ek açıklamalı kod, "değer" i "ad" olarak ayarlar

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

Aynı JSP kullanımında erişmek için ${sessionScope.name}.

İçin @ModelAttributebu bkz linki


4

Bu en kolay ve en kısa yol değil mi? Biliyordum ve test ettim - burada mükemmel çalışıyor:

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

ps Buraya " Spring-mvc'de Oturum öznitelikleri nasıl kullanılır " yanıtını aramaya geldim , ancak kodumda yazdığım en bariz olanı görmeden pek çok şeyi okudum. Onu görmedim, bu yüzden yanlış olduğunu düşündüm, ama hayır değildi. Öyleyse bu bilgiyi ana soru için en kolay çözümle paylaşalım.


1
Haklısın ! Kontrolcü yöntemlerinde (GET / POST isteği)
Shessuky

1

Bunu dene...

@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

Oturum açma bilgilerime (ki bu bir önyükleme modeli) çalışırken, @sessionattributes ek açıklamasını kullandım. Ancak sorun, görünüm bir yönlendirme olduğunda ("yönlendirme: / ev"), oturuma girdiğim değerler url'de gösteriliyordu. Bazı İnternet kaynakları http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#mvc-redirecting'i izlemenizi önerir. Ancak bunun yerine HttpSession'u kullandım. Bu oturum, tarayıcıları kapatana kadar orada kalacaktır. İşte örnek kod

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

Görünüm tarafında belirli bir şeyi değiştirmezsiniz.

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

Giriş yaptıktan sonra yukarıdaki kodları web sitenizdeki herhangi bir yere ekleyin. Oturum doğru ayarlanmışsa, değerleri orada göreceksiniz. Jstl etiketlerini ve El-ifadelerini doğru bir şekilde eklediğinizden emin olun (İşte jstl etiketlerini ayarlamak için bağlantı https://menukablog.wordpress.com/2016/05/10/add-jstl-tab-library-to-you-project- doğru / )


0

Bu yöntemi kullanın, kullanımı çok basit

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

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

jsp'de bir kez kullanın ve sonra kaldırın

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

0

İlkbahar 4 Web MVC'de. Kontrolör seviyesinde @SessionAttributeile yöntemde kullanabilirsiniz@SessionAttributes

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

    GetMapping("/showOrder")
    public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
     // method body
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.