MDA模式开发Struts Portlet

来源:互联网 发布:fastadmin cms 编辑:程序博客网 时间:2024/05/16 18:43

MDA模式开发Struts Portlet

前言:

     上一篇笔记中,我们在Ext环境中开发了一个简单的Struts Portlet,在这一篇中我们将使用MDA模式开发一个较为复杂的Struts Portlet,这也是我们在实际项目中常用的开发方式。

一.     开发流程

1.   编写并执行service.users.xml,生成实体类和持久化类。(这一步和Hibernate Engine的功能很类似,感觉Hibernate Enine的更简易一些)

2.   增加业务代码接口和实现

3.   增加Portlet

4.   配置Portlet

基本流程就这四步,看似很简单,但中间的详细步骤是比较多而且复杂的。

二.     详细开发步骤(实例)

a)      在数据库新建一个表my_users,并插入模拟数据。

create table my_users(userid varchar(30),username varchar(30),password varchar(30))

insert into my_users values('001','zhangsan','1234');

insert into my_users values('002','lisi','1234');

insert into my_users values('003','ww','1234');

b)     ext-impl文件夹下新建一个services文件夹,我们将所有的service.xml都放入此文件夹。

c)      在新建的services.xml中创建service.users.xml,文件内容为:(可以拷贝一个例子中的service.xml进行修改)

<?xml version="1.0"?>

<!DOCTYPE service-builder PUBLIC"-//Liferay//DTD Service Builder 4.3.3//EN""http://www.liferay.com/dtd/liferay-service-builder_4_3_3.dtd">

<service-builder package-path="com.ext.portlet.users">

       <namespace>Users</namespace>

       <entity name="UsersEntry"local-service="false"

              remote-service="true"persistence-class="com.ext.portlet.users.service.persistence.UsersEntryPersistenceImpl">

              <!-- PK fields -->

              <column name="userid" type="String"primary="true" />

              <!-- Audit fields -->

              <column name="username" type="String"/>

              <column name="password" type="String"/>

              <!-- Order -->

              <order by="asc">

                     <order-column name="username" case-sensitive="false"/>

              </order>

       </entity>

       <exceptions>

              <exception>UsersEntry</exception>

       </exceptions>

</service-builder>

d)     修改ant文件,增加ant任务:

打开ext-impl目录下的build.xml,增加一个任务

<target name="build-service-portlet-users">

                     <antcall target="build-service">

                            <param name="service.file" value="services/service.users.xml" />

                     </antcall>

</target>

e)      执行build.xmlbuild-service-portlet-users任务

f)       打开ext-impl/src/META-INF/ext-hbm.xml,修改表名。(这是什么?噢,hibernate映射文件。^_^是不是很熟悉)

<classname="com.ext.portlet.users.model.impl.UsersEntryImpl"table="UsersEntry">改为

<classname="com.ext.portlet.users.model.impl.UsersEntryImpl" table="my_users">

g)      增加业务方法并实现

打开/ext-service/src/com/ext/portlet/users/serviceUsersEntryService文件,建立一个名为getAllUsers的抽象方法;

publicList getAllUsers() throws SystemException;

/ext-impl/src/com/ext/portlet/users/service/impl/UsersEntryServiceImpl.java中实现它.

public List getAllUsers() throws SystemException {

return UsersEntryUtil.findAll();

}

h)     重新执行build.xmlbuild-service-portlet-users任务

工具会帮你在UsersEntryServiceUtil也将业务方法实现,我们的Action层将会直接使用UsersEntryServiceUtil来访问持久层。

i)       /src/com/ext/portlet/users/action目录下建立一个ViewUserAction.java文件,完成响应客户端请求。

package com.ext.portlet.users.action;

 

import java.util.ArrayList;

import java.util.List;

import javax.portlet.PortletConfig;

import javax.portlet.RenderRequest;

import javax.portlet.RenderResponse;

import javax.portlet.WindowState;

importorg.apache.struts.action.ActionForm;

import org.apache.struts.action.ActionForward;

importorg.apache.struts.action.ActionMapping;

importcom.ext.portlet.users.model.UsersEntryModel;

importcom.ext.portlet.users.service.UsersEntryServiceUtil;

importcom.liferay.portal.struts.PortletAction;

 

public class ViewUsersAction extends PortletAction{

      

       publicActionForward render(ActionMapping mapping, ActionForm form,

                     PortletConfigconfig, RenderRequest req, RenderResponse res)

                     throwsException {

              if(req.getWindowState().equals(WindowState.NORMAL)) {

                     returnmapping.findForward("portlet.ext.users.view");

              }else {

                     Listusers = UsersEntryServiceUtil.getAllUsers();

                     Listusernames = new ArrayList();

                     for(int i = 0; i < users.size(); i++) {

                            usernames.add(((UsersEntryModel)users.get(i)).getUsername());

                     }

                     req.setAttribute("users",usernames);

                     req.setAttribute("count",""+users.size());

                     returnmapping.findForward("portlet.ext.users.view_users");

         }

     }

}

j)       建立Portlet

建立自己的portlet。在/ext-impl/src/com/ext/portlet/users下面新建文件UsersPortlet.java

package com.ext.portlet.users;

import java.io.IOException;

import javax.portlet.PortletException;

importjavax.portlet.PortletPreferences;

import javax.portlet.RenderRequest;

import javax.portlet.RenderResponse;

importcom.liferay.portlet.StrutsPortlet;

 

public class UsersPortlet extendsStrutsPortlet {

      

       publicvoid doView(RenderRequest req, RenderResponse res)

                     throwsIOException, PortletException {

              PortletPreferencesprefs = req.getPreferences();

              System.out.println(prefs.getValue("test",""));

              super.doView(req,res);

       }

}

portlet重载了doview方法。如果自己portletviewedit有自己特性,那么只要重载doviewdoedit就可以了。

现在portlet的内容是空的,我们用jsp页面来展示用户名称方式来填充portlet里面内容。

k)     编写ViewJSP文件:init.jsp,view.jsp,view_users.jsp

(你知道在哪建的^_^)

init.jsp

<%@ includefile="/html/common/init.jsp" %>

 

<portlet:defineObjects />

 

<%

PortletPreferences prefs = renderRequest.getPreferences();

%>

              view.jsp

              <%@ includefile="/html/portlet/ext/users/init.jsp"%>

<a href="<portlet:renderURLwindowState="<%=WindowState.MAXIMIZED.toString() %>"/>">My User<%= prefs.getValue("user", "") %></a>

            view_users.jsp

<%@ includefile="/html/portlet/ext/users/init.jsp"%>

<%List users = (List)request.getAttribute("users");%>

<%

for (int i = 0; i < users.size(); i++) {

    String userName = (String)users.get(i);

%>

 

    <%= userName %><br>

 

<%

}

%>

l)       配置porlet(胜利在望加油)

m)  打开portlet-ext.xml,增加一个portlet配置(这个配置文件你已经很熟悉了)

     <portlet>

              <portlet-name>EXT_Users</portlet-name>

              <display-name>Users</display-name>

              <portlet-class>

                     com.ext.portlet.users.UsersPortlet

              </portlet-class>

              <init-param>

                     <name>view-action</name>

                     <value>/ext/users/view_users</value>

              </init-param>

              <expiration-cache>0</expiration-cache>

              <supports>

                     <mime-type>text/html</mime-type>

              </supports>

              <resource-bundle>com.liferay.portlet.StrutsResourceBundle</resource-bundle>

              <portlet-preferences>

                     <preference>

                            <name>test</name>

                            <value>user portlet</value>

                     </preference>

              </portlet-preferences>

              <security-role-ref>

                     <role-name>power-user</role-name>

              </security-role-ref>

              <security-role-ref>

                     <role-name>user</role-name>

              </security-role-ref>

       </portlet>

n)     配置liferay-portlet-ext.xml

          <portlet>

                     <portlet-name>EXT_Users</portlet-name>

                     <struts-path>ext/users</struts-path>

                     <use-default-template>false</use-default-template>

</portlet>

o)      配置liferay-display.xml

example分类中加入:

<portletid="EXT_Users" />

p)     struts-config.xml中加入

<!-- Users -->

<action path="/ext/users/view_users"type="com.ext.portlet.users.action.ViewUsersAction">

                <forward name="portlet.ext.users.view"path="portlet.ext.users.view" />

                <forward name="portlet.ext.users.view_users"path="portlet.ext.users.view_users" />

</action>

q)      tiles-defs.xml中加入:

<!-- Users -->

       <definition name="portlet.ext.users.view"extends="portlet">

              <put name="portlet_content"value="/portlet/ext/users/view.jsp" />

       </definition>

       <definition name="portlet.ext.users.view_users"extends="portlet">

              <put name="portlet_content"

                     value="/portlet/ext/users/view_users.jsp"/>

</definition>

r)      修改国际化属性文件Language-ext.properties,加入

javax.portlet.title.EXT_Users=Users 
view-users=View Users

s)     完工! 重新部署后就可以测试了。目前功能只有查找所有用户姓名的业务方法和View。剩下的增删改自己完善吧。

开发过程中遇到的错误及解决方法:

     一.portlet not found 警告

       以前开发了一个portlet,并在一个页面中使用了它。后来由于重新生成了ext,该portlet丢失,服务器启动没问题,访问页面也没有问题。但是在访问某个页面的时候,总在tomcat的控制台上打印警告:Portlet Not Found for ....,虽然说没什么影响,但是看上去非常不爽。为了解决这个问题,查阅了一些资料。发现之所以出现这个警告,是因为以前不同页面的布局都是保存在数据库当中,每次访问页面时,都会调用数据库中记录的页面对应的portlet,添加了我开发的portlet的那个页面也一样,但是重新生成ext后,那个portlet不存在了,而数据库页面的布局中还保存有该portlet的记录,所以报出警告。解决方法也很简单,只要找到数据库中的layout表,在typeSetting字段中删除那个portlet即可。”

 

二.JSP空指针异常

18:15:03,578 ERROR[[jsp]:723] Servlet.service() for servlet jsp threw exceptio

 

java.lang.NullPointerException

atcom.liferay.portlet.PortletConfigImpl.getResourceBundle(Unknown Sour

e)

atcom.liferay.portal.util.PortalUtil.getPortletTitle(Unknown Source)

at com.liferay.portal.util.comparator.PortletTitleComparator.compare(Un

nown Source)

atjava.util.Arrays.mergeSort(Arrays.java:1284)

atjava.util.Arrays.sort(Arrays.java:1223)

atjava.util.Collections.sort(Collections.java:159)

atorg.apache.jsp.html.portlet.layout_005fconfiguration.view_005fcatego

y_jsp._jspService(view_005fcategory_jsp.java:781)

atorg.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)

atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)

atorg.apache.jasper.servlet.JspServletWrapper.service(JspServletWrappe

.java:328)

atorg.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:

15)

atorg.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)

atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App

icationFilterChain.java:269)

atorg.apache.catalina.core.ApplicationFilterChain.doFilter(Application

ilterChain.java:188)

atorg.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDis

atcher.java:691)

atorg.apache.catalina.core.ApplicationDispatcher.doInclude(Application

ispatcher.java:594)

atorg.apache.catalina.core.ApplicationDispatcher.include(ApplicationDi

patcher.java:505)

atcom.liferay.taglib.util.IncludeTag.doEndTag(Unknown Source)

atorg.apache.jsp.html.portlet.layout_005fconfiguration.view_jsp._jspx_

eth_liferay_002dutil_005finclude_005f0(view_jsp.java:875)

atorg.apache.jsp.html.portlet.layout_005fconfiguration.view_jsp._jspSe

vice(view_jsp.java:791)

at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)

atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)

atorg.apache.jasper.servlet.JspServletWrapper.service(JspServletWrappe

.java:328)

atorg.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:

15)

atorg.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)

atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)

atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(App

icationFilterChain.java:269)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(Application

ilterChain.java:188)

atorg.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDis

atcher.java:691)

atorg.apache.catalina.core.ApplicationDispatcher.doInclude(Application

ispatcher.java:594)

atorg.apache.catalina.core.ApplicationDispatcher.include(ApplicationDi

patcher.java:505)

atcom.liferay.taglib.util.IncludeTag.doEndTag(Unknown Source)

atorg.apache.jsp.html.common.themes.portlet_jsp._jspService(portlet_js

.java:925)

at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)

atjavax.servlet.http.HttpServlet.service(HttpServlet.java:803)

atorg.apache.jasper.servlet.JspServletWrapper.service(JspServletWrappe

.java:328)

atorg.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:

 

       在官方网站上搜索后,发现有人遇到过类似问题,并且有人给出了解决办法:

https://www.liferay.com/zh/community/forums/-/message_boards/message/155212

 

在此引用下回答,我觉得很有趣:

I had the same problem as I was also following the tutorials onwiki.liferay.com.

 

The issue comes up if you define the resource-bundle tag of your portletin portlet-ext.xml like this:

 

<resource-bundle>

com.liferay.portlet.StrutsResourceBundle

 

</resource-bundle>

 

If you want toavoid this problem define it in one line like this:

 

<resource-bundle>com.liferay.portlet.StrutsResourceBundle</resource-bundle>

 

 

I know this soundsstupid but this work. I resolved this problem by hit and trial. I hope liferayguys resolve this issue in the next release.

 

 

原创粉丝点击