JBoss下布署Spring2.5和Struts2系统
目前在做JBoss下布署String2.5 & Struts2集成的工程,在工程中用Spring2.5 的component scan, Struts2 的convention 和 rest plugins。在JBoss下部署都有問題:
Spring 2.5 component scan所有annotation標(biāo)注的component都無法找到。原因是JBoss用了VFS,所以在Spring中找不到。
解 決方法:使用jboss的 spring-int-vfs 中提供的 org.jboss.spring.vfs.context.VFSClassPathXmlApplicationContext。這個(gè)包可以在 http://sourceforge.net/projects/jboss/files/JBoss-Spring%20Integration/
下載到,在頁(yè)面中部,可以找到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類的內(nèi)容如下,這里只是簡(jiǎn)單的解析WEB-INF/classes下的類,因?yàn)槲覜]用到j(luò)ar包需要被認(rèn)為action的情況,所以簡(jiǎn)化。
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();
??? }
???
}
為了調(diào)試方便,可以打開org.apache.struts2.convention log level為debug,然后你就可以清晰地看到哪些action被認(rèn)出來了。
總結(jié)
以上是生活随笔為你收集整理的JBoss下布署Spring2.5和Struts2系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于多人操作数据的处理策略
- 下一篇: CAS Tomcat配置