日期:2014-05-17 浏览次数:20860 次
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>
?