JBoss下布署Spring2.5和Struts2系统

目前在做JBoss下布署String2.5 & Struts2集成的工程,在工程中用Spring2.5 的component scan, Struts2 的convention 和 rest plugins。在JBoss下部署都有问题:

Spring 2.5 component scan所有annotation标注的component都无法找到。原因是JBoss用了VFS,所以在Spring中找不到。
解 决方法:使用jboss的 spring-int-vfs 中提供的 org.jboss.spring.vfs.context.VFSClassPathXmlApplicationContext。这个包可以在 http://sourceforge.net/projects/jboss/files/JBoss-Spring%20Integration/
下载到,在页面中部,可以找到JBoss-Spring Integration。下面是我的一段代码:

                ApplicationContext appContext = null;
        switch(serverType) {

        case tomcat:

            appContext = new ClassPathXmlApplicationContext(configFiles);

            break;

        case jboss:

            appContext = new VFSClassPathXmlApplicationContext(configFiles);

            break;

        }





Struts2 convention, 原因也是JBoss用了VFS,于是URL的protocol都变成了vfsfile, vfszip等等。查看xword的源码,在类com.opensymphony.xwork2.util.finder.ClassFinder的 122行左右,里面是写死的,"jar".equals(location.getProtocol(),  "file".equals(location.getProtocol()。
解决方法:由于不能影响到非jboss server,如tomcat,所以不好改写ClassFinder。采用改写struts2 convention插件的方案,替换org.apache.struts2.convention.ActionConfigBuilder如下:

File: src/plugins/convention/src/main/resources/struts-plugin.xml

<bean type="org.apache.struts2.convention.ActionConfigBuilder" class="com.playphone.struts.convention.MyActionConfigBuilder"/>


MyActionConfigBuilder类的内容如下,这里只是简单的解析WEB-INF/classes下的类,因为我没用到jar包需要被认为action的情况,所以简化。



package com.playphone.struts.convention;



import java.net.MalformedURLException;

import java.net.URL;

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;



import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

import org.apache.struts2.convention.ActionNameBuilder;

import org.apache.struts2.convention.InterceptorMapBuilder;

import org.apache.struts2.convention.PackageBasedActionConfigBuilder;

import org.apache.struts2.convention.ResultMapBuilder;

import org.apache.struts2.convention.StringTools;



import com.opensymphony.xwork2.ObjectFactory;

import com.opensymphony.xwork2.config.Configuration;

import com.opensymphony.xwork2.inject.Inject;

import com.opensymphony.xwork2.util.finder.ClassFinder;

import com.opensymphony.xwork2.util.finder.Test;



import com.playphone.spring.EnvVariable;

import com.playphone.spring.ServerType;



/**

* Solve the problem that could not found action under JBoss.

*

* @author <a href="mailto:sunyi4j@gmail.com">Roy</a> on Jul 6, 2009

*/

public class MyActionConfigBuilder extends PackageBasedActionConfigBuilder {

private static Log log = LogFactory.getLog(MyActionConfigBuilder.class);



private static final String BASE_FILE = "appContext.xml";



    private String[] actionPackages;

    private String[] packageLocators;



/**

     * Constructs actions based on a list of packages.

     *

     * @param configuration         The XWork configuration that the new package configs and action configs

     *                              are added to.

     * @param actionNameBuilder     The action name builder used to convert action class names to action

     *                              names.

     * @param resultMapBuilder      The result map builder used to create ResultConfig mappings for each

     *                              action.

     * @param interceptorMapBuilder The interceptor map builder used to create InterceptorConfig mappings for each

     *                              action.

     * @param objectFactory         The ObjectFactory used to create the actions and such.

     * @param redirectToSlash       A boolean parameter that controls whether or not this will create an

     *                              action for indexes. If this is set to true, index actions are not created because

     *                              the unknown handler will redirect from /foo to /foo/. The only action that is created

     *                              is to the empty action in the namespace (e.g. the namespace /foo and the action "").

     * @param defaultParentPackage  The default parent package for all the configuration.

     */

    @Inject

    public MyActionConfigBuilder(

            Configuration configuration,

            ActionNameBuilder actionNameBuilder,

            ResultMapBuilder resultMapBuilder,

            InterceptorMapBuilder interceptorMapBuilder,

            ObjectFactory objectFactory,

                                    @Inject("struts.convention.redirect.to.slash") String redirectToSlash,

                                    @Inject("struts.convention.default.parent.package") String defaultParentPackage) {

     super(

       configuration,

       actionNameBuilder,

       resultMapBuilder,

       interceptorMapBuilder,

       objectFactory,

       redirectToSlash,

       defaultParentPackage);

    }

   

    /**

     * @param actionPackages (Optional) An optional list of action packages that this should create

     *                       configuration for.

     */

    @Inject(value = "struts.convention.action.packages", required = false)

    public void setActionPackages(String actionPackages) {

     super.setActionPackages(actionPackages);

        if (!StringTools.isTrimmedEmpty(actionPackages)) {

            this.actionPackages = actionPackages.split("//s*[,]//s*");

        }

    }



    /**

     * @param packageLocators (Optional) A list of names used to find action packages.

     */

    @Inject(value = "struts.convention.package.locators", required = false)

    public void setPackageLocators(String packageLocators) {

     super.setPackageLocators(packageLocators);

        this.packageLocators = packageLocators.split("//s*[,]//s*");

    }



    @Override

@SuppressWarnings("unchecked")

protected Set<Class> findActions() {

  if(EnvVariable.getServerType() == ServerType.tomcat) {

   return super.findActions();

  } else {

   Set<Class> classes = new HashSet<Class>();

   try {

    ClassFinder finder = new ClassFinder(getClassLoaderForFinder(), buildUrls(), true);



    // named packages

    if (actionPackages != null) {

     for (String packageName : actionPackages) {

      Test<ClassFinder.ClassInfo> test = getPackageFinderTest(packageName);

      classes.addAll(finder.findClasses(test));

     }

    }



    // package locators

    if (packageLocators != null) {

     for (String packageLocator : packageLocators) {

      Test<ClassFinder.ClassInfo> test = getPackageLocatorTest(packageLocator);

      classes.addAll(finder.findClasses(test));

     }

    }

   } catch (Exception ex) {

    if (log.isErrorEnabled()) {

     log.error("Unable to scan named packages", ex);

    }

   }



   return classes;

  }

}



    private List<URL> buildUrls() throws MalformedURLException {

  List<URL> urls = new ArrayList<URL>();



  URL classesUrl = getClassLoader().getResource(BASE_FILE);

  if(classesUrl == null) {

   throw new IllegalStateException("File appContext.xml was not found. The folder WEB-INF/classes discovery base on file classes/appContext.xml.");

  }



  String baseFilePath = classesUrl.getFile();

  URL url = new URL("file", "", baseFilePath.substring(0, baseFilePath.indexOf(BASE_FILE)));

  if (log.isInfoEnabled()) {

   log.info("Struts2 ActionConfigBuilder, classes directory: " + url.getFile());

  }

 

  urls.add(url);

  return urls;

}

   

    private ClassLoader getClassLoader() {

     return Thread.currentThread().getContextClassLoader();

    }

   

}







为了调试方便,可以打开org.apache.struts2.convention log level为debug,然后你就可以清晰地看到哪些action被认出来了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值