2012-12-22 7 views
5

केवल स्प्रिंग एमवीसी मॉडल बीन का एक हिस्सा प्रदर्शित करते समय, क्या ब्राउज़र से वापस आने वाले मॉडल में केवल अपडेट करने का कोई तरीका है?स्प्रिंग एमवीसी + हाइबरनेट: ब्राउज़र से आंशिक मॉडल अपडेट

मान लीजिए कि हम एक उपयोगकर्ता वर्ग (, केवल इस उदाहरण में सार्वजनिक गुण ज़ाहिर है) करते हैं:

public class User { 
    public String firstName; 
    public String lastName; 
    public String email; 
    public Date subscriptionExpiration; 
} 

अब मैं एक JSP में इनपुट फ़ील्ड के रूप में पहले तीन गुण प्रदर्शित करने और में वस्तु को अपडेट करना चाहते तदनुसार डेटाबेस। केवल इन 3 पैरामीटर को अद्यतन किया जाना चाहिए, चौथा नहीं। इसे पूरा करने का एक तरीका

@RequestMapping("/user/{userId}", method=RequestMethod.POST) 
public String saveChanges(@PathVariable userId, User user, Model model) { 
    User oldUser = User.loadFromDB(userId); 
    oldUser.firstName = user.firstName; 
    oldUser.lastName = user.lastName; 
    oldUser.email = user.email; 
    oldUser.saveToDB(); 

    model.addAttribute("user", oldUser); 
} 

लेकिन इसका मतलब यह होगा कि सभी गुणों को हार्डकोड करना जो बदल सकता है, जो मुझे बहुत पसंद नहीं है।

क्या यह निर्धारित करने का कोई तरीका है कि उपयोगकर्ता को बदलने की अनुमति देने के आधार पर कौन से फ़ील्ड अपडेट करना है? यह तंत्र केवल यह मानने से बेहतर होना चाहिए कि अनुरोध पैरामीटर में जो कुछ भी है, बदला जा सकता है, अन्यथा कोई भी समझदार उपयोगकर्ता अनुरोध में अतिरिक्त फ़ील्ड मैन्युअल रूप से इंजेक्ट कर सकता है।

@Entity (dynamicUpdate = true) का उपयोग करके मेरी आंखों में समस्या का समाधान नहीं होता है, क्योंकि मुझे अनुरोध में पूरी उपयोगकर्ता वस्तु वापस नहीं मिल रही है, और ऐसा करने से कई सुरक्षा छेद खुल जाएंगे।

क्या मुझे वसंत में एक अच्छी सुविधा याद आ रही है या क्या इस समस्या के लिए संकल्पनात्मक रूप से हल करने का कोई अन्य तरीका है? किसी भी संकेत की बहुत सराहना की जाती है!

उत्तर

3

this question देखें कि इनइंडबिंडर का उपयोग कैसे करें ताकि पैरामीटर के अनुरोध के लिए वसंत द्वारा कुछ मॉडल फ़ील्ड को बाध्य किया जा सके। यह सुनिश्चित करने की अनुमति देता है कि subscriptionExpiration को अनुरोध पैरामीटर इंजेक्शन द्वारा संशोधित नहीं किया जा सकता है।

और the documentation देखें कि विधियों पर @ModelAttribute एनोटेशन का उपयोग कैसे करें और डेटाबेस से उपयोगकर्ता को लोड करने के लिए विधि तर्कों पर और इसे @RequestMapping विधि से पहले मॉडल में जोड़ें, और अनुरोध पैरामीटर के साथ इस उपयोगकर्ता को पॉप्युलेट करने के लिए जब @RequestMapping विधि को कॉल किया जाता है। यह उपयोगकर्ता को डीबी से प्राप्त करने की अनुमति देता है और अनुरोध से आने वाले नी मूल्यों के साथ वसंत इसे पॉप्युलेट करता है। आपको बस इतना करना है कि उपयोगकर्ता की नई स्थिति को सत्यापित करें और इसे डेटाबेस में सहेजें।

2

मैं विधि लगता है

BeanUtils.copyProperties(Object source, Object target, String[] ignoreProperties) 

आप क्या चाहते हैं नहीं करता है। यह String[] ignoreProperties में परिभाषित गुणों को छूए बिना सभी ऑब्जेक्ट्स को एक ऑब्जेक्ट से दूसरे ऑब्जेक्ट में कॉपी करता है।

दिए गए स्रोत बीन में दिए गए स्रोत बीन के संपत्ति मूल्यों को कॉपी करें, दिए गए "ignoreProperties" को अनदेखा कर दें।

नोट: स्रोत और लक्ष्य वर्गों को एक-दूसरे से मिलान करने या यहां तक ​​कि एक दूसरे से प्राप्त नहीं किया जाना चाहिए, जब तक कि संपत्तियां मिलती हैं। कोई भी बीन गुण जो स्रोत बीन का खुलासा करता है लेकिन लक्ष्य बीन चुपचाप अनदेखा नहीं किया जाएगा।

यह सिर्फ एक सुविधा विधि है। अधिक जटिल स्थानांतरण आवश्यकताओं के लिए, पूर्ण बीनवापर का उपयोग करने पर विचार करें।

API Documentation

+0

इस समय मैंने ऐसा कुछ किया है; मैं फ़ील्ड पर कस्टम एनोटेशन का उपयोग कर रहा हूं ताकि यह अपडेट किया जा सके कि उन्हें अपडेट किया जाएगा या फिर उन्हें अनदेखाप्रॉपर्टीज की सूची के साथ आने के लिए पार्स किया जा रहा है। यह अच्छी तरह से काम करता है, लेकिन मैं इसे मैन्युअल रूप से परिभाषित करने से बचना चाहता हूं। वैसे, इनपुट के लिए धन्यवाद! – usimon

0

आप पहले डेटाबेस से वस्तु को पढ़ने और फिर अनुरोध बाध्य कर सकते हैं। आप FuWeSta-Sample पर एक उदाहरण पा सकते हैं।

यह helper-bean का उपयोग करता है जिसे वसंत द्वारा प्रारंभ किया जाना चाहिए।

0

एक विकल्प आपके फॉर्म में छिपे हुए फ़ील्ड का उपयोग करना है। ड्रॉ बैक के साथ एक विकल्प लेकिन यह कुछ मामलों के लिए काम करता है

0

अच्छी सुविधा जो आप खोज रहे हैं @ModelAttribute है। मुझे लगता है कि आपका फॉर्म उपयोगकर्ता आईडी भी पोस्ट करेगा।

public class UserController { 

    @ModelAttribute 
    public User getUser(@RequestParam(value = "id", required = false) Long id) { 
     return User.loadFromDB(id); 
    } 

    @RequestMapping("/user/{id}", method=RequestMethod.POST) 
    public String saveChanges(@ModelAttribute User user, BindingResult bindingResult, Model model) { 

     if (bindingResult.hasErrors()) { 
      // return ... 
     } 

     // model.asMap().clear(); 

     user.saveToDB(); 
     // return ... 
    } 
} 
संबंधित मुद्दे