Spring 2.0开始对JSR168 Portlet支持,其的MVC模式区别于WW/Struts2,重要的区别就是WW/Struts2对portlet的封装是统一于Servlet的封装,即把Portlet的RequestRender和RequestAction的生命周期封装为RequestAction,而Spring Portlet MVC保留了这特性。Spring Portlet MVC的模式与Spring MVC一样,但是是对Portlet重新开发,故应用Spring Portlet MVC与Spring MVC是一样的,具体注入的类不一样。
在这篇文章中,我会结合Spring和Hibernate开发实现一个基于联系人(Contact)数据对象的增、删、改功能;由于这篇文章重点讲述的是Portlet MVC,对于Spring+Hibernate的配置内容不作重点,请读者参考相关资料。这里只是个简单的例子,在实际应用中,还要读者根据实际情况自行修改适应实际的应用。由于在我上一篇文章中已经讲述过如何开发部署简单的Spring Portlet MVC的例子,在这里只讲述一些重要的细节,其余内容的请参考文章后面的例子原码。
数据模型
联系人Contact.,它包括名字,邮件地址等信息,如下所示: Contact.java public class Contact extends BaseEntity{ private String firstName; private String lastName; private String email; private String phoneNumber; …… 这个Contact对象是继承了BaseEntity,它是封装所有数据模型的唯一标识id的抽象类,把id抽象出来作为重用元素。 BaseEntity.java public abstract class BaseEntity implements IdEntity { private String contactId; ……. 如上所示,它实现一个通用的id存取接口。
DAO层操作
DAO层的接口,它负责数据对象的增删改的功能实现。
接口代码如下:
以下是引用片段: IStorage.java public interface IStorage { //增加 IdEntity doCreateEntity( IdEntity object ); //修改 IdEntity doUpdateEntity( IdEntity object ); //删除 void doDeleteEntity( IdEntity id ); //凭ID找数据对象 Object doFindEntityById( Class clazz, IdEntity object ); //找出某个数据对象的实体 Collection doFindAllEntities( Class clazz ); |
从上面可以看到这个接口是基于数据对象的增删改功能,其的实际类SpringStorage.java是应用Spring封装的Hiberante的操作接口来实现,详细内容请参考源码。
服务层接口
服务层接口是Spring层(业务接口)的实现。接口类IContactService代码如下,它是DAO操作的延伸,接口的实现详见例子。
以下是引用片段: public interface IContactService { Contact createContact( Contact contact ); Contact updateContact( Contact contact ); void deleteContact( Contact contact ); Contact findContactById( IdEntity object ); List findAllContacts(); } |
Portlet层
Portlet层的代码简单,但是理清增删改的逻辑非常重要。
1) 显示列表SelectController.java
显示列表,是通过服务接口取出所有数据,再跟跳转到页面上显示;跳转到显示页面是由返回ModelAndView对象控制到达哪个页面。
以下是引用片段: SelectController.java public class SelectController implements Controller{ private static Log log = LogFactory.getLog(SelectController.class); private IContactService contactService; public void setContactService(IContactService contactService) { this.contactService = contactService; } public IContactService getContactService() { return contactService; } |
显示列表Portlet Action实现org.springframework.web.portlet.mvc.Controller接口,在Servlet支持也有相应的接口。上面的代码只是设置IoC容器注入服务类。
以下是引用片段: public ModelAndView handleRenderRequest(RenderRequest renderRequest, RenderResponse response) throws Exception { ModelAndView modelAndView = new ModelAndView(“list”); modelAndView.addObject(“contactList”, contactService.findAllContacts()); return modelAndView; } |
上面代码是从服务接口取出所有数据,再跳转到list.jsp页面。 在list.jsp里取得相应的数据信息显示,这个和Sping MVC是完全一致,但是在显示页面了,有三个跳转:增加跳转,修改跳转,删除跳转。
增加跳转页面代码:
以下是引用片段: <a href='<portlet:renderURL> <portlet:param name=”action” value=”insert”/> </portlet:renderURL>’>Add Contact</a> |
上面代码说明这个链接是跳view里面的action为insert,这个action的跳转在配置里定义,这里跳转到增加数据的页面。
修改跳转页面代码:
以下是引用片段: <a href='<portlet:renderURL> <portlet:param name=”action” value=”update”/> <portlet:param name=”contactId”> <jsp:attribute name=”value”> <c:out value=”${contact.contactId}”/> </jsp:attribute> </portlet:param> </portlet:renderURL> ‘><c:out value=”${contact.contactId}”/></a> |
上面代码是说明根据对象的id作为参数跳转到修改的控制器,这里注意的是应用<jsp:attribute>标记来传递参数,而不是servlet的直接追加参数,portlet里的URL和参数是经过编码处理的。
删除跳转页面代码:
以下是引用片段: <a href='<portlet:actionURL> <portlet:param name=”action” value=”delete”/> <portlet:param name=”contactId”> <jsp:attribute name=”value”> <c:out value=”${contact.contactId}”/> </jsp:attribute> </portlet:param> </portlet:actionURL> ‘>Remove</a> |
是通过传入数据对象的id跳转到删除对象的控制器。
2)增加联系人InsertController.java
增加数据是过程:当控制器接到renderrequest时,控制器会跳转到form页面,这个页面会在配置文件里作配置;当控制器接到renderaction时,则会调用服务接口作保存操作。
跳转到form的配置:
以下是引用片段: <bean id=”insertController” class=”com.yds.portal.portlet.InsertController”> <property name=”contactService” ref=”contactService”></property> <property name=”commandName” value=”contact”/> <property name=”commandClass” value=”com.gdcn.portal.contact.model.Contact” /> <property name=”formView” value=”insert”></property> <property name=”successView” value=”list”></property> </bean> |
这是增加控制器的配置,其中formView属性就是说明跳转到form页面insert.jsp,而successView是requestaction成功处理后的跳转。
增加保存的代码:
以下是引用片段: protected void onSubmitAction(ActionRequest request, ActionResponse response, Object command, BindException errors) throws Exception { Contact contact =(Contact)command; contactService.createContact(contact); response.setRenderParameter(“action”, “list”); } |
当form页面提交后,通过command对象取得页面的对象,从而保存。上面的onSubmitAction方面是监听页面的form的submit操作,如果要作具体的那个submit(页面有保存和取消按钮),则可以重写方法。效果图如下:
3) 修改联系人UpdateController.java
修改与增加一样有两个操作,跳转到form页面和作更的保存操作。保存操作和增加的一样不作介绍,这里只说明下跳转到form页面。跳转到form页面前则要得到要修改的目标对象,通过取得页面传过来的参数,调用服务方法获取目标对象,再跳转到form页面。从列表跳转到修改页面作取得数据对象的代码如下:
以下是引用片段: protected Object formBackingObject(PortletRequest request) throws Exception { Contact updateContact =(Contact)super.formBackingObject(request); if(updateContact.getContactId() == null){ String contactId = request.getParameter(“contactId”); updateContact.setContactId(contactId); updateContact = contactService.findContactById(updateContact); } return updateContact; } |
4)删除联系人DeleteController.java
删除只是简单的接收到要删除对象的id,调用服务取得对象,再作删除操作。这里过程的细节在上面已经有所述。其效果如下:
Spring Portlet项目的配置
在项目中spring的配置在两个地方读入,一是servlet容器时,即web.xml;另一个是配置portlet.xml里。在Servlet容器里读取时,设置把spring对portlet的全部配置,服务器设置,Hibernate层设置等等信息读入到servlet容器。
Web.xml中
以下是引用片段: context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springconfig/applicationContext*.xml</param-value> </context-param> |
设置读取/WEB-INF/springconfig/目录下,以applicationContext开头的xml配置文件,在这个项目里有:
以下是引用片段: applicationContext.xml 全局的配置信息 applicationContext-Services.xml 服务层的配置信息 applicationContext-hibernate.xml Hibernate的配置信息 |
在applicationContext.xml里设置jsp页面的目录和view的一些信息;applicationContext-Services.xml是配置服务类的信息;applicationContext-hibernate.xml是配置事务,DAO,数据库配置等等信息。
在portlet.xml中,是配置portlet项目的控制器信息:
以下是引用片段: <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class> <init-param> <name>contextConfigLocation</name> <value>/WEB-INF/springconfig/contact-portlet.xml</value> </init-param> |
在当前的portlet中读取contact-portlet.xml配置,这是一个portlet的配置,项目中配置多个portlet时,可以配置多个。
Contact-portlet.xml中配置各个控制器和模式:
以下是引用片段: <bean id=”selectController” … 列表控制器 <bean id=”insertController”… 插入控制器 <bean id=”updateController” … 修改控制器 <bean id=”deleteController”…. 删除控制器 |
以下是引用片段: <bean id=”portletModeParameterHandlerMapping”… |
在view模式中配置各个控制器,前面的key为视图标识。
以下是引用片段: <bean id=”portletModeHandlerMapping”… |
porttlet的模式映射可以配置view、edit、help等各种模式的控制器。
综上所述,说明了基于spring portlet mvc的crud例子构建,上面对外WEB三层的概要,代码作了说明,也对portlet项目的配置作了介绍。关于spring在portlet的应用还有很多细节,读者在实际应用中获得更多的经验,这里只作下介绍,希望有利于各位应用到实际项目中去。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
作者
相关推荐
-
Spring针对Java 8升级
Java 8刚刚在几周前发布。后来Spring Framework项目负责人发表了题为《企业项目中的Java 8》的文章。文中,指出那些著名的Java EE应用服务器如何不允许轻松升级。
-
软件项目成功:项目的处理
在软件项目成功的因素中有我们谈及了问题域和社区,然这两者并不是软件项目本身。你可以把分类当作问题领域连续讨论几个星期,但分类的问题跟实际执行分类的库并不一样。
-
软件项目成功的问题域、社区及细节
在本系列的第一部分中,我们提到了项目成功相关的一些术语,并大致罗列了一组跟项目成功相关的东西……尽管从某种程度来说“提到”意味着“彻底无视”。
-
Rails 4.1改进启动时间和响应布局
在经历了两个候选版本后,Rails团队刚刚发布了Rails 4.1.0。以“单点版本(point release)”发布意在说明更改向后兼容,可以无痛升级。