Portal学习手记之Portlet开发篇(一)

这个东西用来帮助自己以后review的。没有什么特殊价值。 

 

·使用JSR 168来开发Portlet

 

·开发环境:

1.       RAD

2.       测试环境是RAD中专门的门户测试环境(需要跟Portal Server配合)

3.       Portlet导出成war包,部署在stand-alonePortal中。

 

·Portlet应用程序特点:

1.  有组合模式,包括 view,edit,configure

2.  一个模式有多重页面views,来展示portlet页面导航

3.  Portlet要对某些数据有CRUD create read update delelte功能

4.  一些数据要在db中永久保存。

 

·理解:

1.  Portlet不应该依赖于不属于local的机器,不应该依赖于外网

2.  Portlet不关注商务功能的每个细节,也不提供所有的全面的操作。他只是一个展示的窗口。

 

一个需求完整的portlet就像一个联系人簿。主页面是联系人的列表,你选择一个人就会显示这个人的详细信息,电话,地址,单位等,然后你可以使用edit来对这些信息进行add, update, delete。你也可以使用configure来配置这些信息存放在数据库的什么地方。这些恰好满足一个porlet的全部需求。

 

我的开发环境:

RAD7.0

WebSphere Portal6

DB2 9.1

 

·发布生成的portletportal上。

包前缀 com.ibm.samples.standard

我们看到portlet类是 com.ibm.samples.standard.ContactsPortlet

资源束resource bundlecom.ibm.samples.standard.nl.ContactsPortletResource

资源束作用:存放我们的portlet应用程序中可能用到的可译字符串

这些可译字符串的语言翻译将会在“语言特定资源束文件”中存在。

如果是nl的话,可译字符串就存在缺省的自动生成的英语语言资源束中。

Porlet部署描述符中定义了portlet类、资源束、所支持的模式(view,edit,cofigure…)、portlet参数选项。Portlet参数选项是名称-值对,可以选择为只读。

建议只看source XML文件。这样就会清晰的看到定义了什么。其他的视图都比较多余。

 

· portlet类文件中doView()doEdit()doCustomConfigure()中指定这些操作view,edit,config所对应的动作,其中

PortletRequestDispather rd = getPortletContext().getRequestDispather(“/jsp/XXXView.jsp”);

来决定页面的转向。

 

·在RAD7中是没法直接给PortalServer配置数据源的。所以需要访问Portal server运行的WAS console。地址是:https://portalserver.ibm.com:10039/ibm/console/ 然后给我们的portlet配置数据源。

数据库选用的是DB2 v9 默认端口50000

1 首先在 环境-Websphere变量 中修改DB2UNIVERSAL_JDBC_DRIVER_PATH的值,这里是你的db2jdbc驱动包的位置。如果db2是远程的,就去DB2服务器下的sqllib/java/下把db2jcc_license_cu.jardb2jcc.jar拷过来,放在DB2UNIVERSAL_JDBC_DRIVER_PATH的文件夹值下。

2 然后到全局安全性-> J2EE连接器体系结构(J2C)认证数据条目 下新建一个属于自己应用程序所对应的数据库的JAAS条目。其中输入访问test数据库所需要的用户名和密码。

3.最后到 资源-JDBC提供程序下新建一个JDBC Universal DB2 Driver Provider(注意,如果你的DB2是在远程,就一定要选择这个Provider,这样就会在数据源创建的时候,让你输入db2所在服务器的地址和访问端口号了。)

4. 多余不赘述,其中在创建 数据源的时候,选择“组件管理认证别名”和“容器管理认证别名”Tab中,都选择在步骤2里创建的JAAS条目。

最后不要忘记测试连接。成功!

 

 

· 写个BeanBean就是一个java类,有固定的命名规则并实现java.io.Serializable接口。

这个bean的类成员变量都是protect的数据库数据表中的字段名String类型。使用RAD的源代码-〉添加getter&setter功能自动添加这些类成员变量的对应方法。

 

·写个访问DB的类。

http://publib.boulder.ibm.com/infocenter/wasinfo/v6r0/topic/com.ibm.websphere.base.doc/info/aes/ae/tdat_accdfac.html

上面的url有客户机访问数据的类模板和最佳实践。

        String sql = "select userid,oid,first_name,last_name,email,business_phone from contacts where userid= "+ uid +"order by first_name";

上述方式不好的是uid可能是个错误参数,这样就会有sql运行时错误了。所以,我们采用下面的方法:

String sql=

        "select userid,oid,first_name,last_name,email,business_phone from contacts where userid= ? order by first_name";

成功后发生的SQLException是:

[ibm][db2][jcc][10103][10941] Method executeQuery cannot be used for update.

我检查了sql语句,发现select和userid中间没有空格,修复即可。

这个DB类就是JDBC链接DB2数据库获得ResultSet并把值赋给List的作用。其中getContactList方法就是主要被调用的函数。

 

     在写Bean类,写DBAccess类的时候,最佳实践是把他们分别放在不同的包下。比如说package com.ibm.sample.standard.persistence; package com.ibm.sample.standard.beans;

因为在真正的工程中,bean和db的访问类会很多。还是分别放在不同的包下能够让整个工程的层次结构更清晰。

 

这三者准备好后,我们修改ContactsPortlet类的doView()方法:

     public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {

         // Set the MIME type for the render response

         response.setContentType(request.getResponseContentType());

        

         //get login userid

         String uid = "wpsadmin";

        

         //get the list of Contacts

         DbAccess da = new DbAccess();

         List contactlist = da.getContactList(uid);

         request.setAttribute("contactList", contactlist);

 

         // Invoke the JSP to render

         PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(VIEW_JSP);

         rd.include(request,response);

     }

其中的uid是可以用参数代替的,也就是说根据不同的用户就会获得不同的contactList。

注意:request.setAttribute()的第一个参数是在jsp中使用的属性。要和jsp中的声明保持一致。

·修改View.jsp文件,使用bean,并在form中显示出查询结果:

<%@page session="false" contentType="text/html"

import="com.ibm.sample.standard.beans.Contact" %>

 

<jsp:useBean id ="contactList" type="java.util.List" scope="request"/>

<%@taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<portlet:defineObjects/>

<form  method="POST" name="<portlet:namespace/>viewform">

<table>

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

    Contact contact = (Contact)contactList.get(i);%>

    <tr><td>

    <%=contact.getFirstName() %>   <%=contact.getLastName() %>

    </td></tr>

<%}  %>

</table></form>

???????  其中<portlet:namespace/>viewform ?????????有待理解。

 

 

·编写configure模式。

其中我们要定义一个read-only的portlet参数选项。这个只读的参数是可以被wps管理员在config模式下修改的。如果参数没有设置成只读,那么普通用户在edit(个性化编辑)中就可以修改该参数。

1.  修改portlet部署描述符。为数据源名称增加一个portlet参数选项。

注意:portlet被安装在portal上,那么这些参数选项会在portlet启动的时候从portlet部署描述符中读取,然后load到portal配置数据库中用于调用。但是在运行时的更新参数选项的时候(从edit或config模式下)更改数据是存放在portal配置数据库中的。那么如果portlet重启,就会又从portlet部署描述符中读取参数。

2.  修改doCustomConfigure方法。

     protected void doCustomConfigure(RenderRequest request, RenderResponse response) throws PortletException, IOException {

         // Set the MIME type for the render response

         response.setContentType(request.getResponseContentType());

         //Get the portlet preference for the datasource name

         String dsname="";

         PortletPreferences prefs = request.getPreferences();

         if(prefs!=null){

              dsname = (String)prefs.getValue("datasource", "");

         }

         //put list of Contacts on request for rendering

         request.setAttribute("dsName", dsname);

     // Invoke the JSP to render

         PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(CONFIG_JSP);

         rd.include(request,response);

     }

3.  修改Config.jsp

<%@page session="false" contentType="text/html" pageEncoding="GB18030" import="javax.portlet.*,com.ibm.sample.standard.*" %>

<%@taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

<<jsp:useBean id="dsName" type="java.lang.String" scope="request"></jsp:useBean>

<portlet:defineObjects/>

 

<form action="<portlet:actionURL/> method="post">

       <div style = "margin-top: 10px" class="wpsPortletHead">

       输入数据源名称:

       </div>

       <input name="datasource" value="<%=dsName %>" type="text"/>

       <input name="actionEvent" value="保存" type="submit"/>

</form>

 

说明:<%@page session.... 这行,确定jsp不会创建一个session,

<jsp:useBean…………..这行,声明了我们获得并在portlet代码中放入得request对象的数据源名称。

<%@taglib..........这行,加入了portlet的标记库,使JSP标记可用。

<portlet:actionURL/>………就是在portlet标记库中定义的。 defineObjects标记也是在这里面,它用来创建request,response和portlet Context对象。尽管这里没有被使用上。

<form action="<portlet:actionURL/>" method="post"> 。。。。指出了如果点击提交按钮,什么url会被激活。

 

Portlet运行过程中,有两个词汇代表了porlet的主要动作:renderaction。他们的区别在于:如果一个页面被rendered了,所有的在这个页面上的portlets都被要求render他们自己,这样才能建立HTML标记来构建整个页面。可是,当用户在与某一个特定的portlet在打交道的时候,比如在此一个用户点击提交按钮时,portlet能够在portletrendered前执行一个action事件。所以我们创建一个url链接指向我们的portlet来执行portlet类中的processAction方法。我们用actionURL来生成这个URL链接。

 

JSP<%=(script)%>表达式来显示我们从portlet参数选项中获得的数据源名称。

我们使用stylewpsPortletHead,这个类和其他很多类似的类在css提供用来配合Portal使用。使用这些专门为portal准备的style类是很好的,能够保持不同portlet间一致的风格。

 

4.   修改processAction方法

proccessAction方法就是对应actionURL的标记所生成的链接的,它会直接触发processAction内容。这里会对Submit按钮后要执行的操作进行描述。

<input name="actionEvent" value="保存" type="submit"/>

上条中actionEvent是参数名,这个名可以在request对象中查到,如果他的value是“保存”,我们就知道用户操作是什么。我们也可以在其他元素上使用相同的名字,根据value的不同在processAction方法中进行不同的操作。

         public void processAction(ActionRequest request, ActionResponse response) throws PortletException, java.io.IOException {

                   //get actionEvent's value.

                   String actionEventName = request.getParameter("actionEvent");

                   //Save the configuration update

                   if("保存".equalsIgnoreCase(actionEventName)){

                                     PortletPreferences prefs = request.getPreferences();//此处对portlet参数选项的修改//portal配置数据库中进行。

                            try{

                                     prefs.setValue("datasource", request.getParameter("datasource"));

                                     prefs.store();

                            }

                            catch(ReadOnlyException e){

                                     e.printStackTrace();

                            }

                            catch(ValidatorException ve){

                                     ve.printStackTrace();

                            }

                   }

         }

 

这个方法就是察看config模式叶面request中的actionEvent的值,如果是“保存”,就获取PortletPreferences对象,然后把其中的datasource设定成叶面输入的datasource的值,然后保存这个portlet参数项。

 

     public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {

         // Set the MIME type for the render response

         response.setContentType(request.getResponseContentType());

        

         //get login userid

         String uid = "wpsadmin";

         String ds = null;

         PortletPreferences prefs = request.getPreferences();

         if(prefs != null){

              ds = prefs.getValue("datasource", "");

         }

         //get the list of Contacts

         DbAccess da = new DbAccess(ds);

         List contactlist = da.getContactList(uid);

         request.setAttribute("contactList", contactlist);

 

         // Invoke the JSP to render

         PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(VIEW_JSP);

         rd.include(request,response);

     }

            

 

doView修改如上。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值