2010-10-13 30 views
8

Tôi muốn viết thẻ của mình (mở rộng TagSupport) trong khung làm việc mùa xuân của mình. Trong lớp thẻ của tôi, sẽ sử dụng một số dịch vụ sẽ tự động chèn vào mùa xuân. Nhưng tôi luôn luôn nhận được null, có vẻ như mùa xuân không thể tiêm ví dụ dịch vụ trong lớp thẻ của tôi.Làm thế nào để viết thẻ trong dự án mùa xuân của tôi?

Mã này là như sau:

public class FetchTagNameTag extends TagSupport { 

    @Autowired 
    private TaskService taskService; 
    ... 

taskService luôn là null.

Tôi làm cách nào để giải quyết vấn đề này? Cảm ơn.

Trả lời

4

Đối tượng thẻ JSP không được Spring quản lý, chúng được quản lý bởi vùng chứa servlet. Do đó, bạn không thể tự động chuyển nội dung vào thẻ của mình.

Nếu bạn cần giữ đậu từ ngữ cảnh mùa xuân, bộ điều khiển Spring MVC của bạn cần đặt bean làm thuộc tính yêu cầu (sử dụng request.setAttribute()), để đối tượng thẻ có thể giữ nó.

+0

Cảm ơn, bạn đã trả lời câu hỏi của tôi. – Tom

0

Kiểm tra những gói mùa xuân trong các tài liệu tham khảo mùa xuân và trong nguồn suối:

  • org.springframework.web.servlet.tags
  • org.springframework.web.servlet.tags.form
  • Nếu không có gì khác, chúng sẽ hiển thị cho bạn cách các nhà phát triển mùa xuân viết các thẻ spring.

    +0

    Cảm ơn, tôi sẽ kiểm tra sau. – Tom

    1

    Chú thích Triển khai thẻ của bạn với @Configurable và thêm <context:component-scan base-package="your.webapp"> vào Cấu hình Spring của bạn.

    +0

    Xin lỗi, cách tiếp cận của bạn không hiệu quả với tôi. Bạn có chắc chắn về phương pháp này không? – Tom

    15

    Hãy thử bằng cách sử dụng RequestContextAwareTag. Nó sẽ cung cấp cho bạn các phương thức để có được RequestContext và sau đó là WebApplicaitonContext. Hãy xem here.

    +0

    điều này thật đơn giản và chỉ hoạt động. Tôi không biết tại sao câu trả lời cho việc sử dụng bộ điều khiển MVC để autowire được bình chọn. – checklist

    +0

    Không chỉ đơn giản và hoạt động - đó là câu trả lời tốt hơn. Câu trả lời khác liên quan đến việc thiết lập bộ điều khiển thuộc tính yêu cầu yêu cầu tài liệu trong thẻ taglib và mã bổ sung bởi bất kỳ ai sử dụng thẻ taglib này trên các trang không sử dụng cùng một bộ điều khiển. Nó cũng có tác dụng phụ không hoạt động nếu ai đó quên đặt thuộc tính yêu cầu trên một trang mới, không có liên quan. –

    +1

    'getRequestContext(). GetWebApplicationContext(). GetBean (MyBean.class)'. Cuối cùng !! – Michele

    0

    gì bạn có thể làm là tạo ra một phương pháp tĩnh như thế này:

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

    và sau đó cho thẻ của bạn, bạn có thể làm

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

    nhiên, nhược điểm của phương pháp này là bạn phải làm điều này cho mọi nhà xây dựng, nhưng vì TagSupport chỉ có một, nên nó không phải là một vấn đề. Bạn có thể đi dù chỉ một bước xa hơn và tạo ra một lớp cha helper mà luôn luôn đảm bảo autowiring:

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

    Phần còn lại là dễ dàng như việc mở rộng các lớp học của bạn từ SpringTagSupport.

    +0

    Xin chào, cảm ơn. Trường hợp phương thức tĩnh autowireAllFor nên là? – Tom

    +0

    Không quan trọng - chỉ cần giữ nó trong một lớp tiện ích nào đó. Trong ví dụ này, nó được hình bên trong 'YourHelperClass'. – mindas

    0

    Trước tiên tôi viết những dòng này:

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

    Và sử dụng:

    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"); 
    
    } 
    } 
    

    Đó là công việc. Nhưng hơn tôi thấy điều này: Spring supported Tag Libraries. Sự thật trong sự ủng hộ của tôi, tôi vẫn sử dụng giải pháp riêng.

    0

    Sử dụng: -

    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; 
        } 
    
    Các vấn đề liên quan