This framework has a built-in servlet DispatchServlet for integration. It can construct an WebExecutor from its init parameters, and dispatching all requests to this WebExecutor at runtime.

It also has some init parameters for extending, or intergrating with other frameworks (Such as Spring, Velocity, Freeemarker).

You only need to add this servlet into you web.xml, then set some init parameters and the URL it can processing.

The following is an example:

<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-object-factory</param-name>
		<param-value>mySpringAppContextResolverObjectFactory</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>

It contains all the init parameters the servlet supported:

The following are detail specification of these init parameters:

encoding (Optional)

Set the encoding of this servlet.

If you did not set it, "UTF-8" will be used as default.

soybean-milk-config (Optional)

Set the configuration file of this framework. It can be a file in classpath (such as "my/config/soybean-milk.cfg.xml"), or a file in "/WEB-INF" folder of your application (such as "/WEB-INF/cfg/soybean-milk.cfg.xml").

If you did not set it, "/WEB-INF/soybean-milk.cfg.xml" will be used as default.

external-resolver-object-factory (Optional)

Set the external ResolverObjectFactory key in your application (ServletContext). If you set this parameter, the DispatchServlet will find external ResolverObjectFactory with this key and integrate it.

You can integrate other IOC container (such as Spring or Guice) by setting this init parameter.

The following is a example of Spring integration:

First, you must write a ResolverObjectFactory class:

public class SpringResolverObjectFactory implements ResolverObjectFactory
{
	private BeanFactory beanFactory;
	
	public MySpringResolverObjectFactory(BeanFactory beanFactory)
	{
		this.beanFactory=beanFactory;
	}
	
	@Override
	public Object getResolverObject(Serializable resolverObjectId)
	{
		return beanFactory == null ? null : beanFactory.getBean(resolverObjectId);
	}
	
	@Override
	public void addResolverObject(Serializable resolverObjectId, Object resolverObject){}
}

and a ServletContext listener with adding it after Spring init listener in web.xml:

public class SpringResolverObjectFactoryInitListener implements ServletContextListener
{
	public void contextDestroyed(ServletContextEvent event)
	{
		
	}
	
	public void contextInitialized(ServletContextEvent event)
	{
		ServletContext context=event.getServletContext();
		
		BeanFactory springContext=WebApplicationContextUtils.getWebApplicationContext(context);
		SpringResolverObjectFactory srf=new SpringResolverObjectFactory(springContext);
		
		context.setAttribute("springAppContextResolverObjectFactory",rf);
	}
}

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>my.SpringResolverObjectFactoryInitListener</listener-class>
</listener>

Then, setting external-resolver-object-factory value to be "springAppContextResolverObjectFactory".

Now, you can use any id of <bean> defined in Spring as the resolver attribute of <invoke>.

For example, if there is a bean in Spring like this:

<bean id="helloWorldBean">  
	....
</bean> 

Then, you can define its action like this:

<action name="/helloWorld.do">  
	<invoke> request.message=helloWorldBean.helloWorld() </invoke>  
	<target url="/helloWorld.jsp" />  
</action> 

There is also a very simple way, by overriding the getInitExternalResolverObjectFactory() method of DispatchServlet class:

package my.web;
public class DispatchServlet extends org.soybeanMilk.web.servlet.DispatchServlet
{
	private static final long serialVersionUID = 1L;
	
	@Override
	protected ResolverObjectFactory getInitExternalResolverObjectFactory()
			throws ServletException
	{
		final BeanFactory beanFactory=
			WebApplicationContextUtils.getWebApplicationContext(getServletContext());
		
		return new ResolverObjectFactory()
		{
			@Override
			public Object getResolverObject(Serializable resolverObjectId)
			{
				if(beanFactory == null)
					return null;
				
				try
				{
					return beanFactory.getBean(resolverObjectId.toString());
				}
				catch(Exception e)
				{
					return null;
				}
			}
			
			@Override
			public void addResolverObject(Serializable resolverObjectId, Object resolverObject){}
		};
	}
}

Then, you just need to use this DispatchServlet instead:

<servlet>
	<servlet-name>dispatchServlet</servlet-name>
	<servlet-class>my.web.DispatchServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

webObjectSoruce-factory-class (Optional)

Set the customized WebObjectSourceFactory. You can make the framework to use your own WebObjectSource by setting this init parameter. For example, you can define an WebObjectSource that supporting more scopes, so that they can be used in the Invoke method arguments or result keywords.

You can use this init parameter to integrate some other View frameworks, such as Velocity or FreeMarker.

The following is a example of Velocity integration:

First, write a MyWebObjectSourceFactory class as following

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 DefaultWebObjectSource
	{
		private Context velocityContext;
		
		public Context getVelocityContext() {
			return velocityContext;
		}
		public void setVelocityContext(Context velocityContext) {
			this.velocityContext = velocityContext;
		}
		
		@Override
		protected Object getObjectWithScopeUnknownKey(String key, Type expectType)
			throws ObjectSourceException
		{
			if(key.startWith("vm."))
				return velocityContext.get(key.subString(3));
			else
				return super.getObjectWithScopeUnknownKey(key, expectType);
		}
		
		@Override
		protected void setObjectWithScopeUnknownKey(String key, Object value)
			throws ObjectSourceException
		{
			if(key.startWith("vm."))
				velocityContext.put(key.subString(3), value);
			else
				super.setObjectWithScopeUnknownKey(key, value);
		}
		
		//...
	}
}
And set the value of webObjectSoruce-factory-class to be "my.MyWebObjectSourceFactory".

Then, write a Servlet for processing Velocity request of "*.vm"

public class MyVelocityViewServlet extends HttpServlet
{
	//...
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		Context vc=(Context)req.getAttribute("myVelocityContext");
		
		//...
	}
	
	//...
}

That's OK!

Now, if you have an Action like this :

<action name="/myVelocityTest.do">
    <invoke>
        vm.myResult = myResolver.method( vm.arg0, request.arg1 );
    </invoke>
	<target url="/myVelocityTest.vm" />
</action>

You will be able to use "myResult" object in your "myVelocityTest.vm" template.

application-executor-key (Optional)

Set the WebExecutor object key in your application (ServletContext). It helps you getting all the information of this framework at runtime.

And noting will be saved in your application (ServletContext) if you did not set it.