框架本身已提供了一个servlet DispatchServlet, 它会依据初始化参数构造一个WEB执行器。 在运行时,所有到这个servlet的请求都会被交给这个WEB执行器来处理。
它还提供了一些用于扩展和整合其他框架(比如Spring、Velocity、FreeMarker)的初始化参数。
你只需要将这个servlet添加到应用的web.xml中, 配置一些初始化参数,然后设置它可以处理URL即可。
下面是一个配置示例:
<servlet> <servlet-name>dispatchServlet</servlet-name> <servlet-class>org.soybeanMilk.web.servlet.DispatchServlet</servlet-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>soybean-milk-config</param-name> <param-value>/WEB-INF/soybean-milk-config.xml</param-value> </init-param> <init-param> <param-name>external-resolver-factory-key</param-name> <param-value>mySpringAppContextResolverFactory</param-value> </init-param> <init-param> <param-name>webObjectSoruce-factory-class</param-name> <param-value>my.MyWebObjectSourceFactory</param-value> </init-param> <init-param> <param-name>application-executor-key</param-name> <param-value>myWebExecutor</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatchServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
上面这个示例包含了DispatchServlet允许的所有初始化参数:
- encoding
- soybean-milk-config
- external-resolver-factory-key
- webObjectSoruce-factory-class
- application-executor-key
下面将详细介绍这几个初始化参数的作用:
设置servlet编码。
如果你没有定义这个初始化参数,框架将使用默认的“UTF-8”编码。
指定框架配置文件的位置。它可以是类路径的资源文件,比如“my/config/soybean-milk.cfg.xml”; 也可以是应用的“/WEB-INF”目录下的文件,比如“/WEB-INF/cfg/soybean-milk.cfg.xml”。
如果你没有定义这个初始化参数,框架将会从从默认的“/WEB-INF/soybean-milk.config.xml”配置文件初始化。
external-resolver-factory-key(可选)
指定外部解决对象工厂在应用(ServletContext)中的关键字。 如果你设置了这个初始化参数,DispatchServlet将会从应用中查找外部解决对象工厂并将它整合到框架中。
你可以使用这个初始化参数来整合其他框架,比如IOC容器Spring和Guice。
下面是一个整合Spring的过程示例:
首先,定义一个解决对象工厂类:
public class SpringResolverFactory implements ResolverFactory
{
private BeanFactory beanFactory;
public MySpringResolverFactory(BeanFactory beanFactory)
{
this.beanFactory=beanFactory;
}
@Override
public Object getResolver(Serializable resolverId)
{
return beanFactory == null ? null : beanFactory.getBean(resolverId);
}
}
定义一个应用监听器,并把它配置在web.xml中Spring初始化监听器之后:
public class SpringResolverFactoryInitListener implements ServletContextListener
{
public void contextDestroyed(ServletContextEvent event)
{
}
public void contextInitialized(ServletContextEvent event)
{
ServletContext context=event.getServletContext();
BeanFactory springContext=WebApplicationContextUtils.getWebApplicationContext(context);
SpringResolverFactory srf=new SpringResolverFactory(springContext);
context.setAttribute("springAppContextResolverFactory",rf);
}
}
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>my.SpringResolverFactoryInitListener</listener-class>
</listener>
然后,将你的DispatchServlet初始化参数external-resolver-factory-key的值设置为“springAppContextResolverFactory”。
这样,你就可以在框架配置文件<invoke>标签的resolver属性中使用在Spring中定义的那些<bean>的id了。
webObjectSoruce-factory-class(可选)
设置自定义的WEB对象源工厂。 设置它,你可以让框架使用你自定义的WEB对象源。 比如,自定义一个支持更多作用域的WEB对象源,从而使调用方法的参数和返回结果支持更多的作用域。
你可以使用这个初始化参数来整合其他视图层框架,比如Velocity和FreeMarker。
下面是整合Velocity的过程示例:
首先,定义如下MyWebObjectSourceFactory类
package my;
public class MyWebObjectSourceFactory implements WebObjectSourceFactory
{
@Override
public WebObjectSource create(HttpServletRequest request, HttpServletResponse response,
ServletContext application)
{
MyWebObjectSource os=new MyWebObjectSource(request, response, application);
Context vc=new VelocityContext();
os.setVelocityContext(vc);
request.setAttribute("myVelocityContext", vc);
return os;
}
protected static class MyWebObjectSource extends WebObjectSource
{
private Context velocityContext;
public Context getVelocityContext() {
return velocityContext;
}
public void setVelocityContext(Context velocityContext) {
this.velocityContext = velocityContext;
}
@Override
protected Object getWithUnknownScope(String scope, String keyInScope, Class<?> objectType)
{
if("vm".equals(scope))
return velocityContext.get(keyInScope);
else
return super.getWithUnknownScope(scope, keyInScope, objectType);
}
@Override
protected void setWithUnknownScope(String scope, String keyInScope, Object obj)
{
if("vm".equals(scope))
velocityContext.put(keyInScope, obj);
else
super.setWithUnknownScope(scope, keyInScope, obj);
}
//...
}
}
并将DispatchServlet初始化参数webObjectSoruce-factory-class的值设置为“my.MyWebObjectSourceFactory”。
然后,编写如下Velocity视图处理Servlet用于处理*.vm请求
public class MyVelocityViewServlet extends HttpServlet
{
//...
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
Context vc=(Context)req.getAttribute("myVelocityContext");
//...
}
//...
}
完成!
现在,如果你这样配置动作
<action name="/myVelocityTest.do">
<invoke>
vm.myResult = myResolver.method( vm.arg0, request.arg1 );
</invoke>
<target url="/myVelocityTest.vm" />
</action>
那么你将可以在“myVelocityTest.vm”模板中使用“myResult”对象。
设置DispatchServlet创建的WEB执行器在应用(ServletContext)中的保存关键字,这样你便可以在需要时访问到此框架的所有内容。
如果你没有定义这个初始化参数,DispatchServlet将不会在应用中保存它创建的WEB执行器。