2010-10-13 11 views
8

Quiero escribir mi etiqueta (extiende TagSupport) en mi marco de primavera. En mi clase de etiqueta, usaré algún servicio que debería inyectarse automáticamente antes de la primavera. Pero siempre me sale nulo, parece que Spring no puede inyectar una instancia de servicio en mi clase de etiqueta.¿Cómo escribir la etiqueta en mi proyecto de primavera?

El código es el siguiente:

public class FetchTagNameTag extends TagSupport { 

    @Autowired 
    private TaskService taskService; 
    ... 

taskService siempre es nula.

¿Cómo puedo resolver esto? Gracias.

Respuesta

4

Los objetos de etiqueta JSP no son gestionados por Spring, sino que son administrados por el contenedor de servlet. Como resultado, no puede conectar cosas automáticamente a sus etiquetas.

Si necesita agarrar frijoles del appcontext de primavera, entonces su controlador Spring MVC necesita establecer el bean como un atributo de solicitud (usando request.setAttribute()), para que el objeto de etiqueta pueda obtenerlo.

+0

Gracias, su respuesta a mi pregunta. – Tom

0

Salida estos paquetes de resortes en los documentos de referencia en la primavera y la fuente de la primavera:

  • org.springframework.web.servlet.tags
  • org.springframework.web.servlet.tags.form
  • Si nada más, estos le mostrarán cómo los desarrolladores de primavera escribieron las etiquetas de primavera.

    +0

    Gracias, lo veré más tarde. – Tom

    1

    Anote su implementación de etiquetas con @Configurable y agregue <context:component-scan base-package="your.webapp"> a su configuración de resorte.

    +0

    Lo siento, su enfoque no funciona para mí. ¿Estás seguro de este método? – Tom

    15

    Intente utilizando RequestContextAwareTag. Le ofrecerá métodos para obtener RequestContext y luego WebApplicaitonContext. Eche un vistazo al here.

    +0

    esto es tan simple y simplemente funciona. No sé por qué se vota la respuesta para usar el controlador MVC para el autoenvío. – checklist

    +0

    No solo es simple y funciona: es la mejor respuesta. La otra respuesta que implica que el controlador establezca un atributo de solicitud requiere documentación en el taglib y código adicional por parte de cualquier persona que use este taglib en páginas que no usen el mismo controlador. También tiene los efectos secundarios de que no funciona si alguien olvida establecer el atributo de solicitud en una nueva página no relacionada. –

    +1

    'getRequestContext(). GetWebApplicationContext(). GetBean (MyBean.class)'. ¡¡Finalmente!! – Michele

    0

    Lo que podría hacer es crear un método estático como sigue:

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

    y después de su etiqueta que podría hacer

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

    La desventaja obvia de este enfoque es que usted tiene que hacer esto para cada constructor, pero como TagSupport solo tiene uno, no debería ser un problema. Usted puede ir un paso más allá y crear una superclase auxiliar que garantiza siempre autowiring:

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

    El resto es tan fácil como extender sus clases de SpringTagSupport.

    +0

    Hola, gracias. Donde debería estar el método estático autowireAllFor? – Tom

    +0

    No importa, solo guárdelo en una clase de utilidad. En este ejemplo, se representa dentro de 'YourHelperClass'. – mindas

    0

    Primero escribir esto:

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

    y uso:

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

    Es un trabajo. Pero que encontré esto: Spring supported Tag Libraries. La verdad en mi progecto, sigo usando mi propia solución.

    0

    Uso: -

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