2010-10-13 29 views
8

मैं अपने वसंत ढांचे में अपना टैग लिखना चाहता हूं (TagSupport बढ़ाता है)। मेरी टैग कक्षा में, कुछ सेवा का उपयोग किया जाएगा जो वसंत द्वारा ऑटो इंजेक्ट करना चाहिए। लेकिन मैं हमेशा शून्य महसूस करता हूं, ऐसा लगता है कि वसंत मेरी टैग कक्षा में सेवा उदाहरण को इंजेक्ट नहीं कर सकता है।मेरी वसंत परियोजना में टैग कैसे लिखें?

कोड निम्नलिखित की तरह है:

public class FetchTagNameTag extends TagSupport { 

    @Autowired 
    private TaskService taskService; 
    ... 

taskService हमेशा रिक्त है।

मैं इसे कैसे हल कर सकता हूं? धन्यवाद।

उत्तर

4

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

आप वसंत appcontext से सेम की पकड़ पाने के लिए की जरूरत है, तो अपने वसंत MVC नियंत्रक, एक अनुरोध विशेषता (request.setAttribute() का प्रयोग करके) के रूप में सेम स्थापित करने के लिए इतना है कि टैग वस्तु यह की पकड़ प्राप्त कर सकते हैं की जरूरत है।

+0

धन्यवाद, आप मेरे सवाल का जवाब दे दिया। – Tom

0

बाहर चेक वसंत संदर्भ डॉक्स में और वसंत स्रोत में इन वसंत संकुल:

  • org.springframework.web.servlet.tags
  • org.springframework.web.servlet.tags.form
  • यदि कुछ और नहीं है, तो वे आपको दिखाएंगे कि वसंत डेवलपर्स ने वसंत टैग कैसे लिखा था।

    +0

    धन्यवाद, मैं इसे बाद में देखूंगा। – Tom

    1

    @Configurable के साथ अपने टैग-कार्यान्वयन को एनोटेट करें और अपने स्प्रिंग-कॉन्फ़िगरेशन में <context:component-scan base-package="your.webapp"> जोड़ें।

    +0

    क्षमा करें, आपका दृष्टिकोण मेरे लिए काम नहीं करता है। क्या आप इस विधि के बारे में निश्चित हैं? – Tom

    15

    RequestContextAwareTag का उपयोग करके प्रयास करें। यह आपको RequestContext और फिर WebApplicaitonContext प्राप्त करने के तरीकों की पेशकश करेगा। here पर एक नज़र डालें।

    public static void autowireAllFor(Object target) { 
        AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor(); 
        bpp.setBeanFactory(...yourBeanFactory...); 
        bpp.processInjection(target); 
    } 
    

    और उसके बाद आपके टैग के लिए तुम कर सकते हो

    public class YourTag extends TagSupport { 
    
        @Autowired 
        private SomeBean someBean; 
    
        public YourTag() { 
         YourHelperClass.autowireAllFor(this); 
        } 
    } 
    

    इस दृष्टिकोण का स्पष्ट नुकसान आपको क्या करना है वह यह है कि:

    +0

    यह इतना आसान है और बस काम करता है। मुझे नहीं पता कि ऑटोवॉयर के लिए एमवीसी नियंत्रक का उपयोग करने का उत्तर क्यों दिया जाता है। – checklist

    +0

    न केवल यह सरल और काम करता है - यह बेहतर उत्तर है। एक अनुरोध विशेषता को सेट करने वाले नियंत्रक को शामिल करने वाले दूसरे उत्तर में टैगलिब और अन्य कोड द्वारा दस्तावेज की आवश्यकता होती है जो इस टैगलिब का उपयोग उन पृष्ठों पर करता है जो समान नियंत्रक का उपयोग नहीं करते हैं। यह काम करने के साइड इफेक्ट्स भी नहीं है, किसी को किसी नए, असंबंधित पृष्ठ पर अनुरोध विशेषता सेट करना भूल जाना चाहिए। –

    +1

    'getRequestContext()। GetWebApplicationContext()। GetBean (MyBean.class)'। आखिरकार!! – Michele

    0

    तुम कर सकते हो क्या इस तरह एक स्थिर विधि बनाने है यह प्रत्येक कन्स्ट्रक्टर के लिए है, लेकिन TagSupport के रूप में केवल एक है, यह कोई समस्या नहीं होनी चाहिए। तुम भी एक कदम आगे जाने के लिए और एक सहायक सुपर क्लास जो हमेशा autowiring की गारंटी देता है बना सकते हैं:

    public class SpringTagSupport extends TagSupport { 
        public SpringTagSupport() { 
         super(); 
         YourHelperClass.autowireAllFor(this); 
        } 
    } 
    

    बाकी SpringTagSupport से अपनी कक्षाओं का विस्तार के रूप में के रूप में आसान है।

    public abstract class SpringSuportedTag extends SimpleTagSupport{ 
    
    protected WebApplicationContext _applicationContext; 
    
    protected WebApplicationContext getSpringContext(){ 
        PageContext pageContext = (PageContext) getJspContext(); 
        if(_applicationContext==null){ 
         _applicationContext = RequestContextUtils.getWebApplicationContext(
           pageContext.getRequest(), 
           pageContext.getServletContext() 
          ); 
         initCustomBeans(); 
        } 
        return _applicationContext; 
    } 
    
    protected abstract void initCustomBeans(); 
    
    /** 
    * Deprecated for inserting extra logic. Use {@link #doTagWithSpring()} instead. 
    */ 
    @Override 
    @Deprecated 
    public void doTag() throws JspException, IOException { 
        getSpringContext(); 
        doTagWithSpring(); 
    } 
    
    
    abstract void doTagWithSpring() throws JspException, IOException; 
    } 
    

    और उपयोग::

    public class SlotTag extends SpringSuportedTag { 
    
    // @Resource(name="userDetailHolder") 
    // not work here 
    UserDetailHolder userDetail; 
    
    private String slotname; 
    
    public String getSlotname() { 
        return slotname; 
    } 
    
    public void setSlotname(String slotname) { 
        this.slotname = slotname; 
    } 
    
    @Override 
    void doTagWithSpring() throws JspException, IOException { 
        PageContext pageContext = (PageContext) getJspContext(); 
        String userDetailCode = pageContext.getAttribute(InitWidgetUserTag.KAY_USERDETAIL, PageContext.PAGE_SCOPE).toString(); 
        userDetail.init(userDetailCode); 
        String pageID = pageContext.getAttribute(InitWidgetUserTag.KAY_PAGEID, PageContext.PAGE_SCOPE).toString(); 
    
        getJspContext().getOut().println("<b>slot for user:"+userDetail.getUserId()+"</b>"); 
    } 
    
    @Override 
    protected void initCustomBeans() { 
        userDetail = (UserDetailHolder) getSpringContext().getBean("userDetailHolder"); 
    
    } 
    } 
    

    यह काम है

    +0

    हाय, धन्यवाद। जहां स्थैतिक विधि autowireAllFor होना चाहिए? – Tom

    +0

    कोई फर्क नहीं पड़ता - बस इसे कुछ उपयोगिता वर्ग में रखें। इस उदाहरण में इसे 'YourHelperClass' के अंदर चित्रित किया गया है। – mindas

    0

    सबसे पहले मैं इस बारे में। लेकिन से मुझे यह मिला: Spring supported Tag Libraries। मेरे प्रोजेक्ट में सच्चाई मैं अभी भी अपने समाधान का उपयोग करता हूं।

    0

    का उपयोग करें: -

    import org.springframework.web.servlet.tags.RequestContextAwareTag; 
    
    public class FetchTagNameTag extends RequestContextAwareTag { 
    
    // @Autowired 
    
        // private TaskService taskService; 
    
        @Override 
    
        protected int doStartTagInternal() throws Exception { 
    
    TaskService taskService= getRequestContext().getWebApplicationContext().getBean(TaskService.class); 
    
    
        return 0; 
        } 
    
    संबंधित मुद्दे