6

के बीच अंतर मैं हाल ही में स्प्रिंग एमवीसी सीखने की कोशिश कर रहा हूं। ऐसा लगता है कि मैं @ModelAttribute एनोटेशन और HttpSession की कार्यक्षमताओं को अच्छी तरह से समझ में नहीं आया।स्प्रिंग एमवीसी - HttpSession.setAttribute और model.addObject

@SessionAttributes({"shoppingCart", "count"}) 
public class ItemController { 

@ModelAttribute("shoppingCart") 
public List<Item> createShoppingCart() { 
    return new ArrayList<Item>(); 
} 

@ModelAttribute("count") 
public Integer createCount() { 
    return 0; 
} 

@RequestMapping(value="/addToCart/{itemId}", method=RequestMethod.GET) 
public ModelAndView addToCart(@PathVariable("itemId") Item item, 
     @ModelAttribute("shoppingCart") List<Item> shoppingCart, @ModelAttribute("count") Integer count) { 

    if(item != null) { 
     shoppingCart.add(item); 
     count = count + 1; 
    } 

    return new ModelAndView(new RedirectView("showAllItems")).addObject("count", count); 
} 

@RequestMapping(value="/deleteFromCart/{itemId}", method=RequestMethod.GET) 
public ModelAndView deleteFromCart(@PathVariable("itemId") Item item, 
     HttpSession session) { 

    List<Item> list = (List<Item>) session.getAttribute("shoppingCart"); 
    list.remove(item); 
    //session.setAttribute("shoppingCart", list); 

    Integer count = (Integer) session.getAttribute("count"); 
    count = count - 1; 
    session.setAttribute("count", count); 

    return new ModelAndView(new RedirectView("showAllItems")); 
} 

शॉपिंगकार्ट और गिनती सत्र विशेषताएँ हैं।

समस्या हटाएं FromCart विधि में है। मुझे सत्र से पुन: असाइन करें सत्र में ओवरराइट करें। लेकिन मैं जेएसपी पर अद्यतन मूल्य देख नहीं सकता। हालांकि, अद्यतन शॉपिंग कार्ट ऑब्जेक्ट को अद्यतन किया जा सकता है, हालांकि मैं सत्र ऑब्जेक्ट को ओवरराइट नहीं करता (क्योंकि ऑब्जेक्ट वही ऑब्जेक्ट है जो पहले से ही सत्र में है)।

लेकिन गिनती क्यों अपडेट नहीं की गई है, हालांकि मैं session.setAttribute के साथ इसे ओवरराइट करता हूं? जब मैं मॉडल पर नया गिनती ऑब्जेक्ट जोड़ता हूं (model.addObject ("गिनती", गिनती)) तो मैं गिनती के अद्यतन मूल्य को देख सकता हूं। लेकिन session.setAttribute क्यों नतीजा देता है?

उत्तर

10

सबसे पहले, @SessionAttribute को http सत्र का उपयोग करने की आवश्यकता नहीं है। यह SessionAttributeStore का उपयोग करता है जिसमें इसके बैकिंग स्टोरेज के रूप में कुछ भी हो सकता है। केवल डिफ़ॉल्ट कार्यान्वयन http सत्र का उपयोग करता है।

आपका कोड अपेक्षित काम क्यों नहीं करता है @SessionAttribute काम करता है।

एक नियंत्रक विधि से पहले @SessionAttributes में सूचीबद्ध, सब कुछ शुरू हो जाती है अपने मामले {"warenkorb", "count"} में, सत्र से पढ़ सकते हैं और मॉडल में जोड़ा जाता है।

विधि वापस लौटने के बाद सत्र को विधि में मॉडल में जोड़े गए सभी चीज़ों के साथ अपडेट किया गया है।

.addObject("count", count) 

-> गणना मॉडल में और बाद में सत्र में जोड़ा जाता है।

session.setAttribute("count", count) 

-> गणना सत्र में जोड़ा गया है लेकिन मॉडल के लिए नहीं। किसी भी नियंत्रक विधि के अगले आमंत्रण से पहले इसे मॉडल में जोड़ा जाएगा। लेकिन अभी के लिए मॉडल में अभी भी पुराना count है। और मॉडल जो अनुरोध में जोड़ा जाता है। और यदि अनुरोध दायरे में एक विशेषता पाई जा सकती है तो जेएसपी इस बात की परवाह नहीं करता कि सत्र में क्या है।

आप @SessionAttributes और @ModelAttribute (सामान्य रूप में या वसंत MVC) का उपयोग करते हैं तो HttpSession या HttpRequest प्रयोग से बचें। यहां तक ​​कि HttpResponse सीमित उपयोग का है। Spring MVC की सुंदरता को गले लगाओ :)

+0

तो मूल रूप से; एक नियंत्रक विधि लागू करने से पहले, सत्र मॉडल अद्यतन करता है। विधि के बाद, मॉडल सत्र अद्यतन करता है। तो एकमात्र पल, जब सत्र और मॉडल दोनों में एक ही विशेषता है, तो नियंत्रक विधि में अलग-अलग मान हो सकते हैं। आपका बहुत बहुत धन्यवाद। – akcasoy

2

model.addObject अनुरोध स्कोप पर ऑब्जेक्ट रखता है जबकि HTTPsession.setAttribute इसे सत्र स्कोप में रखता है। और चूंकि जेएसपी पर चर अगले क्रम पर हल किए गए हैं: पृष्ठ स्कोप -> अनुरोध क्षेत्र -> सत्र स्कोप -> एप्लिकेशन स्कोप, आपको जो मिलता है वह आपको मिलता है।

+0

की प्रतिलिपि से निपट रहे हैं, लेकिन मैंने दोनों गुणों को @ सत्र एट्रिब्यूट्स ({"warenkorb", "count"} के साथ सत्र विशेषताओं के रूप में परिभाषित किया है)। जब मैं session.setAttribute ("गिनती", गिनती) के साथ विशेषता गणना को ओवरराइट करता हूं, तो क्या इसे सत्र स्कोप के साथ विशेषता नहीं बदलनी चाहिए? हो सकता है कि मुझे इस सवाल को "setAttribute और addObject" के बीच का अंतर नहीं लिखा हो, लेकिन हटाए गए 2 सत्र ऑब्जेक्ट्स के बीच अंतर हटाएं, जो दोनों अलग-अलग तरीकों से होते हैं (warenkorb अपडेट किया गया है, गिनती अभी भी पुरानी गिनती वस्तु है) । – akcasoy

+0

फुह, आखिरकार इसे सुलझाया .. अपने विधि हस्ताक्षर को 'सार्वजनिक मॉडल में बदलें और हटाएं हटाएंप्रमबास्केट (@ पाथवायरबल इंटीजर स्थिति, @ मॉडेल एट्रिब्यूट ("वेरेनकोर्ब") सूची वारेनकोर्ब, @ मॉडेल एट्रिब्यूट ("गिनती") पूर्णांक गिनती, मॉडल मैप मॉडलमैप) और सत्र में विशेषता सेट करें: 'modelMap.addAttribute (" गिनती ", - गणना);' – Patison

+0

हाँ, और मैंने इस पृष्ठ को रीफ्रेश नहीं किया :) – Patison

0

जावा विधि पैराम मानों द्वारा पारित किए जाते हैं। आप इस पैरामीटर को असाइन कर सकते हैं जो आप विधि के अंदर चाहते हैं, लेकिन इसके बाहर इसका प्रभाव नहीं होगा।आप जिस विधि को पैरा

संबंधित मुद्दे