Liferay portal 相关总结(五)
七、Portal 与Spring结合
了解完DB层与DAO层,再往上就应该是业务逻辑层,换一句话说就是到了Spring所管辖的层面。Spring这个框架一直为人们所称道,原因我想不言自明,其轻量级的架构,MVC架构分层清晰,DI和IoC的(其实我觉得它俩是一回事)运用,使得各个模块之间耦合尽可能的降低,AOP的思想更是严格的遵照设计模式中的思想,使得复用性更高,更加灵活。好了,就感叹到这里了。下面转述一下具体的步骤,为什么说转述呢,这不是我发现的,而是借鉴别人的成功经验,所以要谦虚一下。
要想portal与Spring进行结合。第一要做的是感叹Spring的优越性,好吧,这个工作已经在前面完成了。废话不多说…
portal与Spring之间也是要有jar包支持的,所以要下载相应的jar包,谨慎起见,我将jar包列表复制过来,如下图:
可能大家找起来会非常费劲。。。
开始编程,这里我们选用一个比较简单的例子,为什么?为了遵循程序开发学习过程的一般性规则——要从Hello World程序开始学一门语言或编程技术。
熟悉MVC架构的都知道,MVC中最为重要的是C,也就是控制端,那么我们就从这个程序的控制端来开始看起。
//file: HelloWorldController.java
import javax.portlet.*;
import org.springframework.web.portlet.ModelAndView;
import org.springframework.web.portlet.mvc.Controller;
public class HelloWorldController implements Controller {
public void handleActionRequest(ActionRequest request,
ActionResponse response) throws Exception {
}
public ModelAndView handleRenderRequest(RenderRequest request,
RenderResponse response) throws Exception {
Map<String, Object> model = new HashMap<String, Object>();
model.put("helloWorldMessage", "Hello World");
return new ModelAndView("helloWorld", model);
}
}
上面就是一个比较简单的Controller类的例子,从这个中我们能得到如下认识:
1. Spring里面的C这个角色的类要实现Controller这个接口,而这个接口中有两个需要实现的方法:handleActionRequest和handleRenderRequest方法,其实这样写都不对,应该将方法签名写全,这里为了满足我这个懒人的特定生理需求和我的懒,我就这样写了。
2. 第一个方法通过方法名可以看出来是来处理Action请求的方法,在其中有针对Action请求的处理代码逻辑,而后面那个方法是用来处理Render(渲染)请求的。有了前面portal和portlet部分的铺垫,我想这个应该很好理解。
3. 再有就应该是第二个方法的返回值了,这个返回值类型看着就大概知道是干什么用的了,ModelAndView不就是MVC中的前两位的元素,返回view层和Model层的信息。
有了上面的认识,我们再来看看整个的portal结合Spring的项目的工作流程,相信能够更好的理解与Spring结合的这种方式。首先鉴于Portal和Portlet中学到的知识,一个portlet程序最重要的配置文件莫过于portlet.xml文件。首先是portlet-class这个标签的配置,要注意的是,在前面我们已经讲过这是对请求进行处理的类,而且要全路径,还记得不?!所以这里要选用一下这个类:org.springframework.web.portlet.DispatcherPortlet,看到Dispatcher这个字眼是不是很熟悉,眼熟就行了,后面要讲到的。既然是Spring,那么传说中的applicationContext.xml文件就必不可少了,只可惜这里这个配置文件不叫这个名字了,而且这个文件的名字被限制死,必须依照以下规则命名:<portlet-name>-portlet.xml其中portlet-name必须和portlet.xml文件中配置的名字一致。在我们这个比较简单的例子中,需要配置的内容有以下几项:处理类的定义(Controller的定义)、portlet状态到handler的映射和view resolver(view层的解析器的配置)。
上简单代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="helloWorldController"
class="chapter07.code.listing.HelloWorldController"/>
<bean id="portletModeHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="portletModeMap">
<map>
<entry key="view">
<ref bean="helloWorldController" />
</entry>
</map>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
最后的最后怎么能够少得了web.xml文件的配置,直接上代码:
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.ViewRendererServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
这些是上面view这层渲染时使用的servlet和URL的模式。
下面正式开始讲解工作流程:
首先要提及的就是在前面已经埋好伏笔的DispatcherPortlet,这个类的作用就像Struts中的Dispatcher,可以将各种请求进行各种转发。首先来看一个Request到程序中是怎样的一个逻辑处理过程,鉴于图表的方式比较直观,我也使用这个图表的方式来展示这个处理过程。这里这个图是我的原创。鉴于要展现的是一个流程,所以我使用软件工程中比较常用的时序图的方式进行绘制。见下图:接下来就对这个图进行相应的讲解,首先是用户向DispatcherPorlet发出一个请求,DispatcherPorlet由容器生成,对用户的请求进行处理,其先将请求发送给HandlerMapping进行映射,也就是我们在前面提到的那个必须与portlet-name有关的那个文件,在传统的ssh程序中叫做applicationContext.xml的,映射返回映射的结果,也就是这个处理类的信息。然后分发器向ViewResolver发送信息解析视图名称信息,将返回的视图名称信息,发送到ViewRenderServlet这个servlet中进行渲染,最后调用最终的Controller类来进行业务逻辑的处理。以上就是整个的处理过程的大致描述,也不知道我讲清楚没有?!前面我们配置的那么多文件其实都在这个过程中担任这不可忽略的角色。
以上就是Portal结合Spring的基本过程,其实在中高级的文章中也有很多的知识点,比如:Portal与Spring也有annotation,使用过Spring的你们懂得,这样就不用在配置文件中配置方法名称了,在类中直接写就可以了。期待吧……这会在我的下一系列博文中出现。