日期:2014-05-17  浏览次数:20953 次

Apache tiles中用URL加载资源

URL是URI的特殊类型,统一资源定位符作用就是要将具体的资源和加载资源的方式解耦。

http://stackoverflow.com/questions/861500/url-to-load-resources-from-the-classpath-in-java

?

比如,需要得到资源的流,只需要在连接参数中设置protocol这个参数就能够加载到任意位置的比特流。除了比特流职位其他还还有 最后资源最后修改时间,创建时间等都能通过URL来取到。

?

但是,在使用URL来加载资源也是有前提的,必须要先了解URL和他所依赖的一些类的体系结构,不然在使用过程中不是任何资源都能加载的。比如执行下面这段代码:

public static void main(String[] args) throws Exception {
		new URL("classpath:tiles-conf/tiles-defs.xml").openConnection();
	}

?

在console上会输出下面的错误信息:

?

Exception in thread "main" java.net.MalformedURLException: unknown protocol: classpath
?at java.net.URL.<init>(Unknown Source)
?at java.net.URL.<init>(Unknown Source)
?at java.net.URL.<init>(Unknown Source)
?at com.koubei.profile.util.Test.main(Test.java:19)

我试验了一下无论是将这段代码用java程序启动还是放在tomcat中跑都是会抛出相同的异常?

?

但是在使用tiles框架过程中,使用在加载tiles的配置文件使用的是如下配置,在web.xml中:

<context-param>
		<param-name>org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG</param-name>
		<param-value>classpath:tiles-conf/tiles-defs.xml</param-value>
</context-param>

?

?

会抛出这样的错误信息,说明classpath的protocol是识别的,问题的关键是找不到资源

?

?

2011-08-04 09:21:45,136 org.apache.tiles.impl.BasicTilesContainer.initializeDefinitionsFactory(BasicTilesContainer.java:398) - WARN - Unable
?to find configured definition 'classpath:tiles-conf/tiles-defs.xml'

?

问题的关键是从利用ServletContext加载资源是只能从web当前“/”根目录开始加载,如果要从classpath中加载的话就找不到了。解决的办法是添加两个类:?

import org.apache.struts2.tiles.StrutsTilesContainerFactory;
import org.apache.tiles.TilesContainer;
import org.apache.tiles.TilesException;
import org.apache.tiles.impl.BasicTilesContainer;

/**
 * @author 百岁 (莫正华 baisui@taobao.com)
 * 
 *         2011-8-4 上午11:09:55
 */
public class KoubeiStrutsTilesContainerFactory extends
		StrutsTilesContainerFactory {

	@Override
	public TilesContainer createTilesContainer(Object context)
			throws TilesException {

		BasicTilesContainer container = new KoubeiTilesContainer();
		initializeContainer(context, container);
		return container;
	}
}

?

import java.util.Map;

import org.apache.tiles.TilesException;
import org.apache.tiles.definition.DefinitionsFactory;
import org.apache.tiles.impl.BasicTilesContainer;

/**
 * @author 百岁 (莫正华 baisui@taobao.com)
 * 
 *         2011-8-4 上午10:50:41
 */
public class KoubeiTilesContainer extends BasicTilesContainer {

	@Override
	protected void initializeDefinitionsFactory(
			DefinitionsFactory definitionsFactory, String resourceString,
			Map<String, String> initParameters) throws TilesException {

		definitionsFactory.addSource(KoubeiTilesContainer.class
				.getResource("/tiles-conf/tiles-defs.xml"));
		

		super.initializeDefinitionsFactory(definitionsFactory, resourceString,
				initParameters);
	}
}

?然后在web.xml中配置一个配置节点,就可以让tiles来从classpath下来加载配置信息了。

	<context-param>
		<param-name>org.apache.tiles.factory.TilesContainerFactory</param-name>
		<param-value>com.koubei.profile.tiles.KoubeiStrutsTilesContainerFactory</param-value>
	</context-param>

?