基于Spring Portlet MVC的CRUD

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跳转到删除对象的控制器。

页面效果如下:
基于Spring Portlet MVC的CRUD


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(页面有保存和取消按钮),则可以重写方法。效果图如下:
基于Spring Portlet MVC的CRUD


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;
 }
效果图如下:
基于Spring Portlet MVC的CRUD

修改后跳转显示页面:
基于Spring Portlet MVC的CRUD 


4)删除联系人DeleteController.java
删除只是简单的接收到要删除对象的id,调用服务取得对象,再作删除操作。这里过程的细节在上面已经有所述。其效果如下:

基于Spring Portlet MVC的CRUD

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的应用还有很多细节,读者在实际应用中获得更多的经验,这里只作下介绍,希望有利于各位应用到实际项目中去。

以下是本例子的项目及源码:

SpringInfrastructurePortlet.part1.rar(977 KB)
SpringInfrastructurePortlet.part2.rar(977 KB)
SpringInfrastructurePortlet.part3.rar(977 KB)
SpringInfrastructurePortlet.part4.rar(977 KB)
SpringInfrastructurePortlet.part5.rar(977 KB)
SpringInfrastructurePortlet.part6.rar(977 KB)
SpringInfrastructurePortlet.part7.rar(749 KB)

你可能感兴趣的:(spring,bean,mvc,Hibernate,应用服务器)