struts2利用FilterDispatcher来拦截请求,然后进行请求的分发,在FilterDispatcher的#init()方法里,实现了配置文件的读入。
代码如下:
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
dispatcher = createDispatcher(filterConfig);
dispatcher.init();
String param = filterConfig.getInitParameter("packages");
String packages = "org.apache.struts2.static template org.apache.struts2.interceptor.debugging";
if (param != null) {
packages = param + " " + packages;
}
this.pathPrefixes = parse(packages);
}
-------------------------------------------------------------------------------------------------
先调用#createDispatcher()来创建一个Dispatcher对象,并将FilterConfig中的属性读出,代码如下:
protected Dispatcher createDispatcher(FilterConfig filterConfig) {
Map params = new HashMap();
for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) {
String name = (String) e.nextElement();
String value = filterConfig.getInitParameter(name);
params.put(name, value);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}
在#createDispatcher()中,将Filter的配置中的所有属性都写入一个HashMap并作为参数传递给Dispatcher的构造函数。
-------------------------------------------------------------------------------------------------
再回到#init()函数中,创建完Dispatcher对象后,紧接着调用Dispatcher的#init()方法。代码如下:
public void init() {
if (configurationManager == null) {
configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
}
init_DefaultProperties(); // [1]
init_TraditionalXmlConfigurations(); // [2]
init_LegacyStrutsProperties(); // [3]
init_ZeroConfiguration(); // [4]
init_CustomConfigurationProviders(); // [5]
init_MethodConfigurationProvider();
init_FilterInitParameters(); // [6]
init_AliasStandardObjects(); // [7]
Container container = init_PreloadConfiguration();
init_CheckConfigurationReloading(container);
init_CheckWebLogicWorkaround(container);
}
首先实例化一个ConfigurationManager对象。
然后就是调用一系列的#init_*()方法了。
-------------------------------------------------------------------------------------------------
●第一个是
private void init_DefaultProperties() {
configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
}
这个方法中是将一个DefaultPropertiesProvider对象追加到ConfigurationManager对象内部的ConfigurationProvider队列中。
DefaultPropertiesProvider的#register()方法可以载入org/apache/struts2/default.properties中定义的属性。
-------------------------------------------------------------------------------------------------
●第二个是
private void init_TraditionalXmlConfigurations() {
String configPaths = initParams.get("config");
if (configPaths == null) {
configPaths = DEFAULT_CONFIGURATION_PATHS;
}
String[] files = configPaths.split("[url=file://\\s*[,]\\s]\\s*[,]\\s[/url]*");
for (String file : files) {
if (file.endsWith(".xml")) {
if ("xwork.xml".equals(file)) {
configurationManager.addConfigurationProvider(new XmlConfigurationProvider(
file, false));
} else {
configurationManager
.addConfigurationProvider(new StrutsXmlConfigurationProvider(file,
false, servletContext));
}
} else {
throw new IllegalArgumentException("Invalid configuration file name");
}
}
}
这里负责载入的是FilterDispatcher的配置中所定义的config属性。
如果用户没有定义config属性,struts默认会载入DEFAULT_CONFIGURATION_PATHS这个值所代表的xml文件。
它的值为"struts-default.xml,struts-plugin.xml,struts.xml"。也就是说框架默认会载入这三个项目xml文件。
下一步框架会逐个判断每个config属性中定义的文件。如果文件名为"xwork.xml",框架会用XmlConfigurationProvider类去处理,反之则用StrutsXmlConfigurationProvider类去处理。
-------------------------------------------------------------------------------------------------
●第三个是
private void init_LegacyStrutsProperties() {
configurationManager.addConfigurationProvider(new LegacyPropertiesConfigurationProvider());
}
向ConfigurationManager加入了一个LegacyPropertiesConfigurationProvider。
-------------------------------------------------------------------------------------------------
●第四个是
private void init_ZeroConfiguration() {
String packages = initParams.get("actionPackages");
if (packages != null) {
String[] names = packages.split("[url=file://\\s*[,]\\s]\\s*[,]\\s[/url]*");
// Initialize the classloader scanner with the configured packages
if (names.length > 0) {
ClasspathConfigurationProvider provider = new ClasspathConfigurationProvider(names);
provider.setPageLocator(new ServletContextPageLocator(servletContext));
configurationManager.addConfigurationProvider(provider);
}
}
}
这次处理的是FilterDispatcher的配置中所定义的actionPackages属性。传说中的Struts 2 零配置。
该参数的值是一个以英文逗号(,)隔开的字符串,每个字符串都是一个包空间,Struts 2框架将扫描这些包空间下的Action类。
-------------------------------------------------------------------------------------------------
●第五个是
private void init_CustomConfigurationProviders() {
String configProvs = initParams.get("configProviders");
if (configProvs != null) {
String[] classes = configProvs.split("[url=file://\\s*[,]\\s]\\s*[,]\\s[/url]*");
for (String cname : classes) {
try {
Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
ConfigurationProvider prov = (ConfigurationProvider) cls.newInstance();
configurationManager.addConfigurationProvider(prov);
} catch (InstantiationException e) {
throw new ConfigurationException("Unable to instantiate provider: " + cname, e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Unable to access provider: " + cname, e);
} catch (ClassNotFoundException e) {
throw new ConfigurationException("Unable to locate provider class: " + cname, e);
}
}
}
}
此方法处理的是FilterDispatcher的配置中所定义的configProviders属性。负责载入用户自定义的ConfigurationProvider。
-------------------------------------------------------------------------------------------------
●第六个是
private void init_FilterInitParameters() {
configurationManager.addConfigurationProvider(new ConfigurationProvider() {
public void destroy() {
}
public void init(Configuration configuration) throws ConfigurationException {
}
public void loadPackages() throws ConfigurationException {
}
public boolean needsReload() {
return false;
}
public void register(ContainerBuilder builder, LocatableProperties props)
throws ConfigurationException {
props.putAll(initParams);
}
});
}
此方法用来处理FilterDispatcher的配置中所定义的所有属性。
-------------------------------------------------------------------------------------------------
●第七个是
private void init_AliasStandardObjects() {
configurationManager.addConfigurationProvider(new BeanSelectionProvider());
}
-------------------------------------------------------------------------------------------------
执行完七个init_*方法后,Dispatcher的#init()会接着调用#init_PreloadConfiguration(),构建一个用于依赖注射的Container对象。
private Container init_PreloadConfiguration() {
Configuration config = configurationManager.getConfiguration();
Container container = config.getContainer();
boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class,
StrutsConstants.STRUTS_I18N_RELOAD));
LocalizedTextUtil.setReloadBundles(reloadi18n);
ObjectTypeDeterminer objectTypeDeterminer = container
.getInstance(ObjectTypeDeterminer.class);
ObjectTypeDeterminerFactory.setInstance(objectTypeDeterminer);
return container;
}
此方法首先获取到ConfigurationManager中的Configuration对象,在#getConfiguration()内部,调用上边6步添加到ConfigurationManager的ConfigurationProviders的#register()方法。
public synchronized Configuration getConfiguration() {
if (configuration == null) {
setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
try {
configuration.reload(getConfigurationProviders());
} catch (ConfigurationException e) {
setConfiguration(null);
throw e;
}
} else {
conditionalReload();
}
return configuration;
}
其中的重点就是DefaultConfiguration的#reload()方法。
public synchronized void reload(List providers) throws ConfigurationException {
packageContexts.clear();
loadedFileNames.clear();
ContainerProperties props = new ContainerProperties();
ContainerBuilder builder = new ContainerBuilder();
for (ConfigurationProvider configurationProvider : providers)
{
configurationProvider.init(this);
configurationProvider.register(builder, props);
}
props.setConstants(builder);
builder.factory(Configuration.class, new Factory() {
public Configuration create(Context context) throws Exception {
return DefaultConfiguration.this;
}
});
try {
// Set the object factory for the purposes of factory creation
ObjectFactory.setObjectFactory(new ObjectFactory());
container = builder.create(false);
objectFactory = container.getInstance(ObjectFactory.class);
ObjectFactory.setObjectFactory(objectFactory);
for (ConfigurationProvider configurationProvider : providers)
{
container.inject(configurationProvider);
configurationProvider.loadPackages();
}
rebuildRuntimeConfiguration();
} finally {
ObjectFactory.setObjectFactory(null);
}
}
分享到:
相关推荐
1. **struts-default.xml**:这是Struts2的核心配置文件,位于`struts2-core.jar`库的`/org/apache/struts2/defaults`包内。它包含了框架的基本设置,如拦截器栈、默认Action配置等。 2. **struts-plugin.xml**:这...
本文将围绕“Struts2配置文件传值中文乱码”这一主题,深入探讨其成因、解决方案以及相关的配置细节,旨在帮助开发者有效解决中文乱码问题,提升用户体验。 ### Struts2框架简介 Struts2是Apache组织下的一个开源...
### Struts2 配置文件详解 #### 一、引言 在Struts2框架的应用开发过程中,配置文件起到了至关重要的作用。Struts2主要依赖于两种基于XML的配置文件:`web.xml` 和 `struts-config.xml`(通常命名为 `struts.xml`)...
确保配置文件的路径相对于`WEB-INF/classes`是可访问的,这样才能使Struts2成功读取并解析配置,从而正常运行应用程序。 总结一下,当遇到Struts2配置文件位置更改问题时,应遵循以下步骤: 1. 确保新的`struts....
- 这是Struts配置文件的根元素,其配置类为org.apache.struts.config.ModuleConfig。该元素下有8个子元素,每个都扮演着不同的角色,如数据源配置、全局异常处理、全局转发等。 #### 2. **Data-Sources元素** - `...
在Struts2的配置文件(struts.xml)中添加相应的配置。 3. **设置Content-Type和Content-Disposition**: - 在Action类中,使用`ValueStack`或`ActionContext`来设置HTTP响应的`Content-Type`和`Content-...
文件上传需要配置Struts2的配置文件,通常为`struts.xml`。在这个配置文件中,需要定义一个或多个与Action类对应的Action配置,设置`result`来指定成功后跳转的页面。同时,我们还需要配置`struts.multipart.saveDir...
2. **配置struts.xml**:在Struts2的配置文件中,我们需要为这个Action添加相应的配置,指定返回的`StreamingResult`结果类型和对应的视图。 ```xml <param name="contentType">application/octet-stream ...
2.能够对上传路径进行配置文件指定(upload.properties),使用了一些类似单例模式的静态代码块 3.Struts2进行下载处理,能对上传的所有文件进行下载(多个) 4.文件保存的名称UUID生成,不过显示并下载的名称都是原...
然后,在struts.xml配置文件中启用`struts.multipart.parser`参数为`copy`,这样Struts2会自动处理文件上传。 ```xml <constant name="struts.multipart.parser" value="copy"/> ``` 在Action类中,你可以这样...
接着,我们需要在Struts配置文件(struts.xml)中配置Action,确保它能够处理文件上传的请求。配置通常包括Action的名称、对应的类以及结果页面。例如: ```xml <result name="success">/success.jsp ...
在`struts.xml`配置文件中添加以下配置: ```xml <constant name="struts.multipart.enabled" value="true"/> <constant name="struts.multipart.maxSize" value="20971520"/> <!-- 20MB --> ``` 这里我们启用了...
自己学会的,保存的学习网页,给大家分享 struts2 国际化
Struts2是一个强大的Java EE平台上的MVC框架,它的设计目标是简化Web应用程序的...以上便是Struts2配置文件的使用和代码详解,通过理解这一框架的工作原理和优势,开发者可以更加高效地利用Struts2来构建Web应用程序。
3. 配置文件:如struts.xml,配置Struts2的动作映射和结果类型,确保上传请求能被正确路由到对应的Action。 4. Servlet或Filter:可能用于处理文件上传的细节,如设置最大文件大小限制、处理多部分请求等。 5. 下载...
#### 一、Struts配置文件的重要性与作用 Struts框架作为SSH(Struts+Spring+Hibernate)三大框架之一,在企业级Web应用开发中扮演着核心角色。Struts配置文件是Struts框架的灵魂所在,它不仅控制着框架的初始化流程...
在Java编程中,读取配置文件是常见的任务,主要用于存储应用程序的设置或环境变量,以方便管理和维护。Java提供了一个内置的`java.util.Properties`类,用于处理`.properties`文件,这种格式通常用来存储键值对,即...
#### 一、Struts配置文件的重要性与作用 Struts框架作为Java Web开发领域中的一种流行MVC(Model-View-Controller)框架,它提供了一种结构化的方式来构建Web应用程序。在Struts框架中,`struts-config.xml`配置...
首先,你需要在项目的配置文件(如struts.xml)中启用文件上传的支持,并配置相应的拦截器。接着,在Action类中创建一个字段来接收上传的文件,Struts2会自动将文件内容绑定到这个字段上。 例如,你可以创建一个名...