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
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值