我正在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所在的页面时,函数调用堆栈如下:
我不明白为什么,第二次点击提交时,不会调用processParams。谁能告诉我为什么?是否有可能连续第二次调用processParams?
谢谢
玛丽
答案 0 :(得分:1)
感谢您的回答。我已经解决了我的问题。我从portlet中取出了一个参数:actionURL。此参数是XML文档。看起来Nick Roth是对的:出于某种原因,XML文档(不是XML转义)生成的URL是错误的,并且阻止了view.jsp调用processParams。
很快见到你,
Marie Piolot
答案 1 :(得分:0)
使用actionResponse.sendRediect(renderurl);在你的行动方法。它应该可以解决您的问题。