Posts Tagged ‘struts2’

用spring对struts2的Action加AOP时,不要让Action继承于ActionSupport

December 17th, 2007

用spring做为struts2的ObjectFactory,用spring来生成action,并对action的方法加上aop时,不要使Action继承于ActionSupport,否则会出现类似于以下的异常:

 java.lang.NoSuchMethodException: $Proxy84.executeList()
at java.lang.Class.getMethod(Class.java:1581)
at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.getActionMethod(AnnotationValidationInterceptor.java:55)

我的Action类继承于ActionSupport类,没有直接实现什么接口。我用AOP把事务加在了Action里的execute打头的方法前,结果,运行时就出现了上面的找不到方法的异常,如果不让Action继承于ActionSupport类就没有了这样的问题。在调试的时候,发现spring生成的代理类里面只有一个execute方法。看来spring在生成代理类时,如果找不到被代理类直接实现的接口,就会到它的超类中去找。在这个例子中,spring就找到了ActionSupport实现的Action接口。

我又试过在struts.xml里定义让struts2以接口的方式去取Action,Action实现一个自己接口,结果struts2又报另外一个错误。看来在这种情况下,只好不要让Action继承于struts2的ActionSupport类了。

  • Share/Bookmark

通过Annotation和Struts2的interceptor实现向Action中注入jndi资源

November 14th, 2007

为了实现向struts2的Action中注入ejb3,我写了一个Annotation用来定义要注入哪个ejb3,又写了一个struts2的interceptor用来实施注入。Annotation代码如下:

@Retention(value=RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD})
@Inherited
public @interface JndiLookup {
    String jndi();
    Class type();
}

Interceptor代码如下:

public class JndiLookupInterceptor implements Interceptor {

    private InitialContext contaxt;

    public void destroy() {
        ;
    }

    public void init() {
        try {
            contaxt = new InitialContext();
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    public String intercept(ActionInvocation invocation)
            throws Exception {
        Method[] methods = invocation.getAction()
        .getClass().getMethods();
        for(Method method : methods) {
            try{
                Class[] parameterTypes
            = method.getParameterTypes();
                if(parameterTypes.length != 1) {
                    continue;
                }

                JndiLookup jndiLookup
            = method.getAnnotation(JndiLookup.class);
                if(jndiLookup == null) {
                    continue;
                }
                if(jndiLookup.jndi() == null
                || jndiLookup.jndi().length() == 0) {
                    continue;
                }
                if(jndiLookup.type() == null) {
                    continue;
                }

                Object object = this.contaxt.lookup(jndiLookup.jndi());
                method.invoke(invocation.getAction(),
            new Object[] {jndiLookup.type().cast(object)});
            } catch (Exception e) {
                e.printStackTrace();
                ;
            }

        }

        return invocation.invoke();
    }

}

需要被注入的Action代码如下:

public class SomeAction {
    private DataSource ds;

    @JndiLookup(jndi="jdbc/mysqlDS", type=DataSource.class)
    public void setDs(DataSource ds) {
        this.ds = ds;
    }

    public String execute() {
        //do something about the ds
    }
}

经测试,在tomcat下注入DataSource成功了。看来Annotation和Struts2真的是个好东西呀!

  • Share/Bookmark

Java EE 的依赖注入功能有限,不能注入到非管束的普通类里面

November 13th, 2007

JavaEE的依赖誉为入功能远没有spring那样强大,只能把特定的资源注入到特定的对象里面。这些特定的资源是指ejb, timer等 java EE的标准服务,其它的乱七八糟的东西是不能注入到别的组件里的。同时,能接受注入的也只有被容器管束的servlet, filter, ejb等标准组件,普通的类也是不能享受到被注入的待遇的。结果现在用struts2时,想在struts2的action里面取得ejb,就不能走注入的这条路了,很不幸呀!怎么办呢?初步想来有这样几种方法,一种是写一个新的struts2的dispathfilter,在这个filter里注入ejb,然后分发到action里,或者写一个struts2的intercepter,用拦截器通过jndi找到ejb,再注入到action里面。嗯……,好像后一种方法相对方便点呢。

  • Share/Bookmark