我可以连续两次调用portlet:actionURL吗? (liferay portlet)

时间:2013-12-03 14:40:12

标签: liferay portlet

我正在Liferay 6.1上开发一个portlet。

这是我的view.jsp:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>

<%@ page import="java.io.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.lang.*" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="org.apache.commons.lang3.*" %>
<%@ page import="org.jdom2.*, org.jdom2.input.*, org.jdom2.output.*" %>

<%
System.out.println("view.jsp"); // DEBUG
%>

<portlet:defineObjects/>

<!-- déclenche l'appel à ProvisionPortlet::processParams en sortie de la page -->
<portlet:actionURL name="processParams" var="processParamsURL">

    <!-- passage de workflowID du paramètre d'entrée au paramètre de sortie -->
    <%
    // lecture de workflowID (workflowID doit être présent dans renderRequest, 
    // soit en tant qu'attribut, soit en tant que paramètre, à ce stade de la
    // portlet, ou alors il y a une erreur de conception ou d'exécution)
    String workflowID = (String) renderRequest.getAttribute("workflowID");
    assert (workflowID != null) : "workflowID is not an attribute of renderRequest (it should be)";
    System.out.println("workflowID = " + workflowID); // DEBUG
    %>
    <portlet:param name="workflowID" value="<%= workflowID %>" />

    <!-- passage des paramètres du paramètre d'entrée au paramètre de sortie -->
    <%
    Map<String, String[]> mapParam = renderRequest.getParameterMap();
    for (Map.Entry<String, String[]> entry : mapParam.entrySet()) {
        String key = entry.getKey();
        String[] value = entry.getValue();
        if (value.length > 0) { 
    %>
            <portlet:param name="<%= key %>" value="<%= value[0] %>" />
    <%
        }
    }
    %>

</portlet:actionURL>

<!-- formulaire -->
<aui:form action="<%= processParamsURL.toString() %>" method="post">

    <%
    // lecture de parseMe (parseMe doit être présent dans renderRequest, 
    // soit en tant qu'attribut, soit en tant que paramètre, à ce stade de la
    // portlet, ou alors il y a une erreur de conception ou d'exécution)
    String parseMe = null;
    if (parseMe == null) {
        parseMe = (String) renderRequest.getAttribute("parseMe");
    }
    if (parseMe == null) {
        parseMe = renderRequest.getParameter("parseMe");
    }
    assert (parseMe != null) : "renderRequest is missing attribute or parameter parseMe";
    System.out.println("parseMe = " + parseMe); // DEBUG

    // parsing du document XML passé en paramètre d'entrée
    java.io.StringReader strReader = new java.io.StringReader(parseMe);
    java.io.Reader reader = (java.io.Reader) strReader;
    // on cree une instance de SAXBuilder
    SAXBuilder sxb = new SAXBuilder();
    org.jdom2.Document document = new org.jdom2.Document();
    try {
        // on cree un nouveau document JDOM avec en argument le fichier
        // le parsing est termine
        document = sxb.build(reader);
    } catch (java.io.IOException e) {
        e.printStackTrace();
        return;
    } catch (JDOMException e) {
        e.printStackTrace();
        return;
    }

    // on initialise un nouvel élément root avec l'élément root du document
    Element root = document.getRootElement();
    // lecture du namespace
    Namespace ns = root.getNamespace();

    // lecture des enfants de l'élément racine
    Element steps = root.getChild("steps", ns);
    List<Element> listStep = steps.getChildren("step", ns);

    for (Element step : listStep) {
        Element group = step.getChild("group", ns);
        Element fields = group.getChild("fields", ns);
        List<Element> listField = fields.getChildren("field", ns);

        for (Element field : listField) {

            // identifiant du field
            String fieldID = field.getAttributeValue("id");
            System.out.println("fieldID = " + fieldID); // DEBUG
            // type du field
            String fieldType = field.getAttributeValue("type");
            System.out.println("fieldType = " + fieldType); // DEBUG

            // présence d'un message d'absence dans le field ?
            boolean isMissingMessage = false;
            Element messages = field.getChild("messages", ns);
            if (messages != null) {
                Element message = messages.getChild("message", ns);
                if (message != null) {
                    String code = message.getAttributeValue("code");
                    if (code.compareTo("mandatory") == 0) {
                        isMissingMessage = true;
                    }
                }
            }

            // y'a-t-il de quoi faire un menu déroulant ? 
            boolean isDropDownMenu = false;
            Element decorators = field.getChild("decorators", ns);
            if (decorators != null) {
                Element dropDown = decorators.getChild("drop-down", ns);
                if (dropDown != null) {
                    Element array = dropDown.getChild("array", ns);
                    if (array != null) {
                        isDropDownMenu = true;
                    }
                }
            }

            // présence d'une valeur dans le field ?
            Element fieldElement = null;
            boolean isValue = false;
            if ((fieldType.compareTo("string") == 0) || (fieldType.compareTo("number") == 0)) {
                fieldElement = field.getChild(fieldType, ns);
                if (fieldElement != null) {
                    isValue = true;
                }
            } else {
                fieldElement = field.getChild("sdk-object", ns);
                if (fieldElement != null) {
                    isValue = true;
                }
            }

            // traitement différent selon les types de field
            if ((fieldType.compareTo("string") == 0) || (fieldType.compareTo("number") == 0)) {

                // type de base (string ou number)

                if (isMissingMessage) {

                    // présence d'un message d'absence
                    System.out.println("présence d'un message d'absence"); // DEBUG

                    if (isDropDownMenu) {

                        // présence de quoi faire un menu déroulant
                        System.out.println("présence de quoi faire un menu déroulant"); // DEBUG

                        // menu déroulant
                        System.out.println("menu déroulant"); // DEBUG

                        // présentation des valeurs possibles en menu déroulant 
                        Element dropDown = decorators.getChild("drop-down", ns);
                        Element array = dropDown.getChild("array", ns);
                        List<Element> listValues = array.getChildren(fieldType, ns);
    %>
                        <!-- menu déroulant -->
                        <aui:select label="<%= fieldID %>" name="<%= fieldID %>">
    <%
                        for (Element eltValue : listValues) {
                            String strNotEscaped = eltValue.getText();
                            String strEscaped = StringEscapeUtils.escapeXml(strNotEscaped);
                            System.out.println("strNotEscaped = " + strNotEscaped); // DEBUG
    %>
                            <aui:option value="<%= strEscaped %>">
                                <liferay-ui:message key="<%= strNotEscaped %>" />
                            </aui:option>
    <%
                        }
    %>
                        </aui:select>
    <%
                    } else {

                        // pas de quoi faire un menu déroulant
                        System.out.println("pas de quoi faire un menu déroulant"); // DEBUG

                        // champ de saisie
                        System.out.println("champ de saisie"); // DEBUG

                        if (isValue) {

                            // présence d'une valeur par défaut
                            System.out.println("présence d'une valeur par défaut"); // DEBUG

                            String defaultValue = fieldElement.getText();
                            System.out.println("defaultValue = " + defaultValue); // DEBUG
    %>
                            <aui:input name="<%= fieldID %>" label="<%= fieldID %>" type="text" value="<%= defaultValue %>" />
    <%
                        } else {

                            // pas de valeur par défaut
                            System.out.println("pas de valeur par défaut"); // DEBUG
    %>
                            <aui:input name="<%= fieldID %>" label="<%= fieldID %>" type="text" />
    <%
                        }

                    }

                } else {

                    // pas de message d'absence
                    System.out.println("pas de message d'absence");

                    if (isValue) {

                        // présence d'une valeur
                        System.out.println("présence d'une valeur"); // DEBUG

                        // une valeur a déjà été choisie
                        System.out.println("une valeur a déjà été choisie"); // DEBUG

                        // présentation de la valeur choisie
                        String chosenValue = fieldElement.getText();
                        System.out.println("chosenValue = " + chosenValue); // DEBUG
        %>
                        <!-- présentation de la valeur choisie -->
                        <aui:input label="<%= fieldID %>" name="<%= fieldID %>" type="text" value="<%= chosenValue %>" disabled="true" />
        <%
                    } else {

                        // TODO cas non prévu
                        System.out.println("TODO cas non prévu");

                    }

                }

            } else {

                // type structuré (sdk-object)

                if (isMissingMessage) {

                    // présence d'un message d'absence
                    System.out.println("présence d'un message d'absence"); // DEBUG

                    if (isDropDownMenu) {

                        // présence de quoi faire un menu déroulant
                        System.out.println("présence de quoi faire un menu déroulant"); // DEBUG

                        // menu déroulant
                        System.out.println("menu déroulant"); // DEBUG

                        // présentation des valeurs possibles en menu déroulant 
                        Element dropDown = decorators.getChild("drop-down", ns);
                        Element array = dropDown.getChild("array", ns);
                        // présentation des valeurs possibles en menu déroulant 
                        List<Element> listSdkObject = array.getChildren("sdk-object", ns);
    %>
                        <!-- menu déroulant -->
                        <aui:select label="<%= fieldID %>" name="<%= fieldID %>">
    <%
                        for (Element sdkObject : listSdkObject) {
                            String displayValue = sdkObject.getAttributeValue("display-value");
                            XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
                            String strNotEscaped = xmlOutputter.outputString(sdkObject);
                            String strEscaped = StringEscapeUtils.escapeXml(strNotEscaped);
    %>
                            <aui:option value="<%= strEscaped %>">
                                <liferay-ui:message key="<%= displayValue %>" />
                            </aui:option>
    <%
                        }
    %>
                        </aui:select>
    <%
                    } else {

                        // pas de quoi faire un menu déroulant
                        System.out.println("pas de quoi faire un menu déroulant"); // DEBUG

                        // champ de saisie (désactivé, on ne saisit pas les types structurés)
                        System.out.println("champ de saisie (désactivé, on ne saisit pas les types structurés)"); // DEBUG
    %>
                        <aui:input name="<%= fieldID %>" label="<%= fieldID %>" type="text" value="<%= fieldType %>" disabled="true" />
    <%
                    }

                } else {

                    // pas de message d'absence
                    System.out.println("pas de message d'absence"); // DEBUG

                    if (isValue) {

                        // présence d'une valeur
                        System.out.println("présence d'une valeur"); // DEBUG

                        // une valeur a déjà été choisie
                        System.out.println("une valeur a déjà été choisie"); // DEBUG
    %>
                        <!-- présentation de la valeur choisie -->
                        <aui:input label="<%= fieldID %>" name="<%= fieldID %>" type="text" value="<%= fieldElement %>" disabled="true" />
    <% 
                    } else {

                        // pas de valeur
                        System.out.println("pas de valeur"); // DEBUG

                        // TODO cas non prévu
                        System.out.println("TODO cas non prévu"); // DEBUG

                    }

                }

            }

        }

    }
    %>

    <!-- bouton de soumission du formulaire -->
    <aui:button-row>
        <aui:button type="submit" value="Send"/>
    </aui:button-row>

</aui:form>

这是我的DynamicPortlet.java:

package com.vco.portlet;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.IOException;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.apache.commons.lang3.StringEscapeUtils;
import org.jdom2.JDOMException;

/**
 * Portlet implementation class DynamicPortlet
 */
public class DynamicPortlet extends MVCPortlet {

    /**
     * Méthode init de la portlet.
     * Lit les noms des fichiers .jsp utilisés par la portlet.
     */
    public void init() {

        System.out.println("DynamicPortlet::init()");

        editJSP = getInitParameter("edit-template");
        helpJSP = getInitParameter("help-template");
        viewJSP = getInitParameter("view-template");
    }

    /**
     * Méthode appelée par view.jsp quand l'utilisateur soumet ses choix du
     * formulaire avec le bouton Submit.
     * @param actionRequest paramètre émis par view.jsp après remplissage par 
     * l'utilisateur du formulaire de view.jsp
     * @param actionResponse est renseigné en sortie de la fonction et envoyé 
     * à doView
     * @throws IOException je ne sais pas quand
     * @throws PortletException je ne sais pas quand
     */
    public void processParams(
            ActionRequest actionRequest, ActionResponse actionResponse) 
        throws IOException, PortletException {

        System.out.println("DynamicPortlet::processParams()");

        // lecture des paramètres d'entrée
        // workflowID
        String workflowID = actionRequest.getParameter("workflowID");
        if (workflowID != null) {
            System.out.println("workflowID = " + workflowID); // DEBUG
        }
        // organization
        String escOrg = actionRequest.getParameter("org");
        String strOrg = null;
        if (escOrg != null) {
            strOrg = StringEscapeUtils.unescapeXml(escOrg);
            System.out.println("strOrg = " + strOrg); // DEBUG
        }
        // template
        String escTemplate = actionRequest.getParameter("template");
        String strTemplate = null;
        if (escTemplate != null) {
            strTemplate = StringEscapeUtils.unescapeXml(escTemplate);
            System.out.println("strTemplate = " + strTemplate); // DEBUG
        }
        // vapp
        String escVApp = actionRequest.getParameter("vapp");
        String strVApp = null;
        if (escVApp != null) {
            strVApp = StringEscapeUtils.unescapeXml(escVApp);
            System.out.println("strVApp = " + strVApp); // DEBUG
        }
        // vmName
        String strVMName = actionRequest.getParameter("vmName");
        if (strVMName != null) {
            System.out.println("strVMName = " + strVMName); // DEBUG
        }
        // ENVIRONNEMENT
        String strEnvironnement = actionRequest.getParameter("ENVIRONNEMENT");
        if (strEnvironnement != null) {
            System.out.println("strEnvironnement = " + strEnvironnement); // DEBUG
        }
        // vcpu
        String strVCPU = actionRequest.getParameter("vcpu");
        if (strVCPU != null) {
            System.out.println("strVCPU = " + strVCPU); // DEBUG
        }
        // memoryMB
        String strMemoryMB = actionRequest.getParameter("memoryMB");
        if (strMemoryMB != null) {
            System.out.println("strMemoryMB = " + strMemoryMB); // DEBUG
        }

        // obtention des autres paramètres possibles
        String parseMe;

        if ((workflowID != null) && (strOrg != null) && (strTemplate != null)
                && ((strVApp == null) || (strVMName == null) 
                || (strEnvironnement == null) || (strVCPU == null) 
                || (strMemoryMB == null))) {

            try {
                parseMe = ServerRequest.postPresentationInstances(workflowID, strOrg, strTemplate);
            } catch (JDOMException e) {
                e.printStackTrace();
                return;
            }
            System.out.println("parseMe = " + parseMe); // DEBUG

            // passage des autres paramètres au paramètre de sortie
            actionResponse.setRenderParameter("workflowID", workflowID);
            actionResponse.setRenderParameter("org", escOrg);
            actionResponse.setRenderParameter("template", escTemplate);
            actionResponse.setRenderParameter("parseMe", parseMe);

        } else if ((workflowID != null) && (strOrg != null) 
                && (strTemplate != null) && (strVApp != null) 
                && (strVMName != null) && (strEnvironnement != null) 
                && (strVCPU != null) && (strMemoryMB != null)) {

            // envoi des paramètres à l'exécution
            boolean resExec = false;
            try {
                resExec = ServerRequest.postExecutions(workflowID, strOrg, strTemplate, strVApp, strVMName, strEnvironnement, strVCPU, strMemoryMB);
            } catch (JDOMException e) {
                e.printStackTrace();
                return;
            }
            System.out.println("resExec = " + (resExec ? "true" : "false")); // DEBUG

            // passage des autres paramètres au paramètre de sortie
            actionResponse.setRenderParameter("workflowID", workflowID);
            actionResponse.setRenderParameter("resExec", (String) (resExec ? "true" : "false"));

        }

    }

    /**
     * Méthode doEdit de la portlet
     * @param renderRequest paramètre d'entrée de la méthode
     * @param renderResponse paramètre renseigné en sortie de la méthode
     * @throws IOException je ne sais pas quand
     * @throws PortletException je ne sais pas quand
     */
    public void doEdit(
            RenderRequest renderRequest, RenderResponse renderResponse)
        throws IOException, PortletException {

        System.out.println("DynamicPortlet::doEdit()");

        include(editJSP, renderRequest, renderResponse);
    }

    /**
     * Méthode doHelp de la portlet
     * @param renderRequest paramètre d'entrée de la méthode
     * @param renderResponse paramètre renseigné en sortie de la méthode
     * @throws IOException je ne sais pas quand
     * @throws PortletException je ne sais pas quand
     */
    public void doHelp(
            RenderRequest renderRequest, RenderResponse renderResponse)
        throws IOException, PortletException {

        System.out.println("DynamicPortlet::doHelp()");

        include(helpJSP, renderRequest, renderResponse);
    }

    /**
     * Méthode doView de la portlet
     * @param renderRequest paramètre d'entrée de la méthode
     * @param renderResponse paramètre renseigné en sortie de la méthode
     * @throws IOException je ne sais pas quand
     * @throws PortletException je ne sais pas quand
     */
    public void doView(
            RenderRequest renderRequest, RenderResponse renderResponse)
        throws IOException, PortletException {

        System.out.println("DynamicPortlet::doView()");

        // workflow name (hardcoded)
        String workflowName = "Provision VM in vCloud";
        // workflowID
        String workflowID = null;
        if (workflowID == null) {
            workflowID = (String) renderRequest.getAttribute("workflowID");
        }
        if (workflowID == null) {
            workflowID = renderRequest.getParameter("workflowID");
        }
        if (workflowID == null) {
            workflowID = ServerRequest.getWorkflowID(workflowName);
        }
        assert (workflowID != null) : "workflowID is undefined";
        System.out.println("workflowID = " + workflowID); // DEBUG
        renderRequest.setAttribute("workflowID", workflowID);

        // parseMe
        String parseMe = null;
        if (parseMe == null) {
            parseMe = (String) renderRequest.getAttribute("parseMe");
        }
        if (parseMe == null) {
            parseMe = renderRequest.getParameter("parseMe");
        }
        if (parseMe == null) {
            parseMe = ServerRequest.postPresentationInstances(workflowID);
        }
        assert (parseMe != null) : "parseMe is undefined";
        System.out.println("parseMe = " + parseMe); // DEBUG
        renderRequest.setAttribute("parseMe", parseMe);

        include(viewJSP, renderRequest, renderResponse);

    }

    /**
     * Méthode include de la portlet
     * @param path nom du fichier .jsp à appeler
     * @param renderRequest paramètre d'entrée de la méthode
     * @param renderResponse paramètre renseigné en sortie de la méthode
     * @throws IOException je ne sais pas quand
     * @throws PortletException je ne sais pas quand
     */
    protected void include(
            String path, RenderRequest renderRequest,
            RenderResponse renderResponse)
        throws IOException, PortletException {

        System.out.println("DynamicPortlet::include()");
        System.out.println("path = " + path); // DEBUG

        PortletRequestDispatcher portletRequestDispatcher =
            getPortletContext().getRequestDispatcher(path);
        if (portletRequestDispatcher == null) {
            _log.error(path + " is not a valid include");
        }
        else {
            portletRequestDispatcher.include(renderRequest, renderResponse);
        }
    }

    /**
     * Nom du fichier .jsp de la view Edit de la portlet
     */
    protected String editJSP;
    /**
     * Nom du fichier .jsp de la view Help de la portlet
     */
    protected String helpJSP;
    /**
     * Nom du fichier .jsp de la view View de la portlet
     */
    protected String viewJSP;

    /**
     * Outil de log de la classe
     */
    private static Log _log = LogFactoryUtil.getLog(DynamicPortlet.class);
}

我使用Liferay Developer Studio。

当我打开我的portlet所在的页面时,函数调用堆栈如下:

  1. DynamicPortlet ::的doView
  2. view.jsp的
  3. 提交
  4. DynamicPortlet :: processParams
  5. DynamicPortlet ::的doView
  6. view.jsp的
  7. 提交
  8. DynamicPortlet ::的doView
  9. view.jsp的
  10. 我不明白为什么,第二次点击提交时,不会调用processParams。谁能告诉我为什么?是否有可能连续第二次调用processParams?

    谢谢

    玛丽

2 个答案:

答案 0 :(得分:1)

感谢您的回答。我已经解决了我的问题。我从portlet中取出了一个参数:actionURL。此参数是XML文档。看起来Nick Roth是对的:出于某种原因,XML文档(不是XML转义)生成的URL是错误的,并且阻止了view.jsp调用processParams。

很快见到你,

Marie Piolot

答案 1 :(得分:0)

使用actionResponse.sendRediect(renderurl);在你的行动方法。它应该可以解决您的问题。