对于Spring-Portlet(Spring转Portlet)

Portlet的简单认识


  1. Portlet不能够想Spring一样直接经由HttpServletRequest指向相对路径(如:action="/SpringDuty/sign.jsp")将页面表单信息传给
    指定页面或者Controller,而是用另一种写法经由指定的Action转向(如:action"<portlet:actionURL> <portlet:param     name='action' value='coming'/></portlet:actionURL>")。(关于这句语句下会面有说明)
  2. Portlet有自己定义的Request,我使用到了两种:ActionRequest*、*RenderRequest
  • ActionRequest:它的作用与HttpServletRequest相同,将当前表单对象传给转向对象。
  • RenderRequest:在门户系统中,Portlet之间的共享信息是放在RenderRequest中,这样可以在单点登陆后每个Portlet即可在相应权限下获取所需的信息(如用户信息)

Spring转Portlet


  1. Portlet和Spring一样,也有自己的转发器org.springframework.web.portlet.DispatcherPortlet,它负责将获得的Action转发给相应处理。
  2. portlet根据自己的转发器与当前Portlet的状态会跳转到相应页面,大致流程是:
  • portlet会根据配置信息,首先找到View或者经由Controller跳转到View
  • 当进行相应动作时,portlet根据当前的状态(View,edit,help)跳转到相应View或者Controller
  • 其它过程与Spring类似

    如何获得RenderRequest

  1. 为了获得RenderRequest,可以首先让Portlet经由一个自己做的DispatcherController通过
    protected ModelAndView handleRenderRequestInternal(RenderRequest arg0, RenderResponse arg1)方法来返回一个ModelAndView,
    其中ModelAndView返回一个Map对象,Map中放入RenderRequest对象arg0和RenderResponse对象arg1,View是需要呈现的首页,这样,首页就能获取RenderRequest了。

Spring转Portlet过程举例

首先,请先下载一个Spring和Spring-portlet的源码,比较一下
下载附件

Web.xml
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
xmlns="http://Java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet>
<servlet-name>ViewRendererServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>searchModule</servlet-name>
<display-name>search</display-name>
<description>please search</description>
<servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
<init-param>
<param-name>portlet-class</param-name>
<param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
</init-param>
<init-param>

<param-name>portlet-guid</param-name>

<param-value>DSEPortletDemo.searchModule</param-value>
//注意:DSEPortletDemo为项目名称,searchModule为portlet.xml中对应的portlet-name
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ViewRendererServlet</servlet-name>
<url-pattern>/WEB-INF/servlet/view</url-pattern>
</servlet-mapping>
</web-app>

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

²           为了使其解析EL语句,必须加入:

<%@ page contentType="text/html; charset=UTF-8" isELIgnored="false"%>

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >
<beans>

<bean id="parameterMappingInterceptor" class="org.springframework.web.portlet.handler.ParameterMappingInterceptor"/>

<bean id="dispatcher" class="cssduty.operation.DispatherController">
<property name="viewPage" value="enter" ></property>
</bean>*

一个简单的处理器映射,它是基于当前的portlet模式(比如:'view', 'edit', 'help').:
<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="order" value="20"/>
<property name="portletModeMap">
<map>
<entry key="view"><ref bean="dispatcher"/></entry>
<entry key="help"><ref bean=""/></entry>//可以不写
</map> </property>
</bean>
在不改变Portlet模式的情况下在多个控制器间切换,参数的缺省名是"action",但可以通过parameterName来修改。
<bean id="parameterMappingInterceptor" class="org.springframework.web.portlet.handler*.ParameterMappingInterceptor"/>

<bean id="portletModeParameterHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping">
<property name="order" value="1"/>
<property name="interceptors">
<list>
<ref bean="parameterMappingInterceptor"/>
</list>
</property>
<property name="portletModeParameterMap">
<map>
<entry key="view">
<map>
<entry key="coming"><ref bean="comingRecord"/></entry>
<entry key="leaving"><ref bean="leaveRecord"/></entry>
<entry key="change"><ref bean="changeTeam"/></entry>
<entry key="sending"><ref bean="sendInfo"/></entry>
<entry key="dispatcher"><ref bean="dispatcher"/></entry>
</map>
</entry>
</map>
</property>
</bean>
Portlet包也带一个名为ParameterMappingInterceptor 的具体拦截器,它可以和ParameterHandlerMapping 以及PortletModeParameterHandlerMapping一起使用。 这个拦截器可以把用来控制映射的参数从ActionRequest 带到随后的RenderRequest,这能够确保 RenderRequest映射到和 ActionRequest相同的处理器。这些都是在 preHandle方法里完成的,所以在你的处理器里仍然可以改变决定 RenderRequest映射的参数值。
注意这个拦截器会调用ActionResponse 的setRenderParameter方法,这意味着在使用它的时候, 不能在处理器里调用sendRedirect。如果确实需要重定向, 可以手工地把映射参数向前传,或者另写一个拦截器来处理。
<bean id="parameterMappingInterceptor" class="org.springframework.web.portlet.handler.ParameterMappingInterceptor"/>

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="cache" value="false"/>
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/JSP/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="comingRecord" class="cssduty.operation.ComingRecord">
<property name="viewPage">
<value>sign</value>
</property>
</bean>

<bean id="leaveRecord" class="cssduty.operation.LeaveRecord">
<property name="viewPage">
<value>sign</value>
</property>
</bean>

<bean id="changeTeam" class="cssduty.operation.ChangeTeam">
<property name="viewPage">
<value>team</value>
</property>
</bean>

<bean id="sendInfo" class="cssduty.operation.SendBrowseInfo">
<property name="viewPage">
<value>List</value>
</property>
</bean>
</beans>

Spring的DispacherController

package cssduty.operation;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class DispatherController implements Controller{

 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
  // TODO Auto-generated method stub

  String hid=request.getParameter("hid");
  System.out.println("hid is "+request.getParameter("hid"));
  System.out.println("user is "+request.getParameter("user"));

  if(hid.equals("onduty"))
    {
     response.sendRedirect("/SpringDuty/comingRecord.do?user="+request.getParameter("user"));
    }
  return null;
 }

}

Spring-portlet的Controller

package cssduty.operation;

import java.util.HashMap;
import java.util.Map;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletMode;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.springframework.web.portlet.ModelAndView;
import org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping;
import org.springframework.web.portlet.mvc.AbstractController;
import org.springframework.web.portlet.mvc.PortletModeNameViewController;

public class DispatherController extends AbstractController{

 private String viewPage="";
 Map map=null;

 protected ModelAndView handleRenderRequestInternal(RenderRequest arg0, RenderResponse arg1) throws Exception {

    map=new HashMap();
    map.put("disRequest",arg0);
   return new ModelAndView(this.getViewPage(),map);     }

 public void handleActionRequestInternal(ActionRequest request, ActionResponse response) throws Exception {
  // TODO Auto-generated method stub

    response.setRenderParameter("hid",hid);
 }

 public String getViewPage() {
  return viewPage;
 }

 public void setViewPage(String viewPage) {
  this.viewPage = viewPage;
 }

}

两个Controller的区别在于包引入的不同
前者实现Controller接口,后者继承AbstractController类,实现的方法也就不同
后者不能直接提交ModelAndView,需要经由handleActionRequestInternal(ActionRequest request, ActionResponse response)方法提交给
handleRenderRequestInternal(RenderRequest arg0, RenderResponse arg1) 才可以。

enter.jsp

<%@ page language="java" pageEncoding="gb2312"%>
<%@ taglib     prefix="portlet" uri="http://java.sun.com/portlet" %>
<%@page import="javax.portlet.*" %>
<%@ taglib uri="c.tld" prefix="c" %>
<%@ taglib uri="c-1_0-rt.tld" prefix="c-rt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
      <title>enter.jsp</title>
      <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
      <meta http-equiv="description" content="this is my page">
      <meta http-equiv="content-type" content="text/html; charset=gb2312">

      <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
    <script language="javascript" type="text/javascript">
     function getOn()
     {
      document.enter_form.elements[2].value=document.all.onduty.name;
      document.enter_form.action="<portlet:actionURL> <portlet:param    name='action' value='coming'/></portlet:actionURL>";
      enter_form.submit();
     }

     function getLeave()
     {
      document.enter_form.elements[2]=document.all.leave.name;
      document.enter_form.action="<portlet:actionURL> <portlet:param    name='action' value='leaving'/></portlet:actionURL>";
      enter_form.submit();
     }

     function getTeamChange()
     {
      document.enter_form.elements[2].value=document.all.changeTeam.name;
      document.enter_form.action="<portlet:actionURL> <portlet:param    name='action' value='change'/></portlet:actionURL>";
      enter_form.submit();
     }
    </script>
    </head>

    <body>
      <form name="enter_form" method="post" id="f1" action="" >
        <%
            RenderRequest renderRequest=((RenderRequest)(request.getAttribute("disRequest")));
    %>
     <%== renderRequest.getPreferences().getValue("userName", null) %>

        <table border="0" width="208" height="58">
          <tr>
     //获取DispatcherController传过来的RenderRequest
       <%=((RenderRequest)(request.getAttribute("disRequest"))).getUserPrincipal()%>

       <c-rt:forEach var="userAttr" items="<%= request.getAttribute(PortletRequest.USER_INFO)%>">
          <tr>
            <c:if test="${userAttr.key=='user.name'}">
      <td>用户:<c:out value="${userAttr.value}"/></td>
      <td><input type="hidden" name="user" value="${userAttr.value}"/></td>
     </c:if>
     <c:if test="${userAttr.key=='user.department'}">
      <td>部门:<c:out value="${userAttr.value}"/></td>
      <td><input type="hidden" name="department" value="${userAttr.value}"/></td>
     </c:if>
          </tr>
       </c-rt:forEach>
          </tr>

          <tr>
            <td colspan="8" align="center">
           <input type="hidden" name="hid">
             <input type="button" value="上班" name="onduty" οnclick="getOn()">
             <input type="button" value="下班" οnclick="getLeave()" name="leave">
             <input type="button" value="项目组变更" οnclick="getTeamChange()" name="changeTeam">
            </td>
          </tr>
        </table>
      </form>
    </body>
</html>
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值