天道酬勤,学无止境

为什么 Liferay Faces 不处理 JSF portlet 动作事件?(Why isn't Liferay Faces processing JSF portlet action events?)

问题

我在尝试使用 Liferay Faces 和任何 JSF 组件来触发动作事件时遇到问题。

我已经浏览了 Liferay 的开发 JSF Portlets 说明页面的第一部分,直到(但不包括)国际化 JSF Portlets 部分成功为止。 我继续添加了一些其他 JSF 组件,也取得了一些成功,但是,事件不起作用。

此示例的目标是拥有一个文本框,用户可以在其中更改“World”的默认文本,并且文本区域将在每次击键时通过 AJAX 更新为“Hello, XXX”(其中 XXX 是框中的文本) )。 是的,在一个单独的 JSF 项目中,我尝试了 view.xhtml 和 TestBean.java 并且它有效。

在 Liferay 门户中,portlet 出现,当我输入时,我收到了到服务器的回发。 DebugPhaseListener 仅导致 BEFORE/AFTER RESTORE_VIEW 1 和 BEFORE/AFTER RENDER_RESPONSE 6。两者之间没有阶段,我认为这表明了问题所在。 (注意:Liferay Faces portlet 桥接 portlet 生命周期事件并模拟 JSF 生命周期。)

我正在使用 Liferay 6.2,在 Eclipse Luna 中运行,带有 Liferay 最新的 Tomcat 包和来自 Liferay 更新站点的最新 eclipse 插件。 Java 1.7.0_71。

以下是我认为与弄清楚发生了什么相关的所有资产和代码。 您能提供的任何帮助将不胜感激。

视图.xhtml:

<?xml version="1.0"?>

<f:view
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
>
    <h:head />
    <h:body>
        <h:form id="someForm">
            <p:calendar id="myCal" mode="inline" value="#{testBean.myDate}" actionListener="#{testBean.updateDate}">
                <p:ajax actionListener="#{testBean.updateDate}" update="myMsgs"/>
            </p:calendar>
            <br/>
            <p:commandButton value="Hi there" actionListener="#{testBean.updateDate}" update="myMsgs"/>
            <br/>
            <p:messages id="myMsgs"/>
            <br/>
            Test String=#{testBean.testString}
            <br/>
            Output Text test string = <h:outputText value="#{testBean.testString}"/>


            <h:outputLabel value="Name" for="nameInput" />
            <h:inputText id="nameInput" value="#{testBean.name}">
                <f:ajax render="output" event="keyup" />
            </h:inputText>
            <br/>

            <p>
                <h:panelGroup id="output">
                    <strong> <h:outputText value="Hello, #{testBean.name}" />
                    </strong>
                </h:panelGroup>
            </p>

            <h:commandButton id="reset" value="Reset"
                actionListener="#{testBean.reset}">
                <f:ajax render="@form" />
            </h:commandButton> - Reset The Form to "World"
            <br/>

            <h:messages />

        </h:form>
    </h:body>
</f:view>

测试Bean.java

import java.io.Serializable;
import java.util.Date;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;


@ManagedBean(name="testBean")
@SessionScoped
public class TestBean
    implements Serializable
{
    private static final long serialVersionUID = 1L;

    public String getTestString()
    {
        return "Test String";
    }

    private Date myDate = new Date();
    public Date getMyDate() { return myDate; }
    public void setMyDate(Date value) { System.out.println("setMyDate value="+value); myDate = value; }

    public void updateDate()
    {
        System.out.println("updateDate - myDate="+myDate);
    }

    /**
     * Stores the name which will be used to greet the application user.
     */
    private String name;

    /**
     * Initializes {@link #name} with the value {@code "World"}.
     */
    @PostConstruct
    public void postContruct()
    {
        this.name = "World";
    }

    /**
     * Returns {@link #name}.
     *
     * @return {@link #name}
     */
    public String getName()
    {
        return name;
    }

    /**
     * Set {@link #name}.
     *
     * @param value
     */
    public void setName(String value)
    {
        System.out.println("Setting name to " + value);
        name = value;
    }

    /**
     * Resets {@link #name} to the default value {@code "World"}.
     *
     * @param ae
     * ignored
     */
    public void reset(ActionEvent ae)
    {
        setName("World");
    }
}

portlet.xml

<?xml version="1.0"?>

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0">

    <portlet>
        <portlet-name>my-calendar-portlet</portlet-name>
        <display-name>My Calendar Portlet</display-name>
        <portlet-class>
            javax.portlet.faces.GenericFacesPortlet
        </portlet-class>
        <init-param>
            <name>javax.portlet.faces.defaultViewId.view</name>
            <value>/views/my-calendar-portlet/view.xhtml</value>
        </init-param>
        <init-param>
            <name>javax.portlet.faces.defaultViewId.edit</name>
            <value>/views/my-calendar-portlet/edit.xhtml</value>
        </init-param>
        <expiration-cache>0</expiration-cache>
        <supports>
            <mime-type>text/html</mime-type>
            <portlet-mode>view</portlet-mode>
            <portlet-mode>edit</portlet-mode>
        </supports>
        <portlet-info>
            <title>My Calendar Portlet</title>
            <short-title>My Calendar Portlet</short-title>
            <keywords></keywords>
        </portlet-info>
        <security-role-ref>
            <role-name>administrator</role-name>
        </security-role-ref>
        <security-role-ref>
            <role-name>guest</role-name>
        </security-role-ref>
        <security-role-ref>
            <role-name>power-user</role-name>
        </security-role-ref>
        <security-role-ref>
            <role-name>user</role-name>
        </security-role-ref>
    </portlet>
</portlet-app>

liferay-portlet.xml

<?xml version="1.0"?>
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 6.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_6_2_0.dtd">

<liferay-portlet-app>

    <portlet>
        <portlet-name>my-calendar-portlet</portlet-name>
        <icon>/icon.png</icon>
        <header-portlet-css>/css/main.css</header-portlet-css>
        <footer-portlet-javascript>
            /js/main.js
        </footer-portlet-javascript>
        <css-class-wrapper>
            my-calendar-portlet-portlet
        </css-class-wrapper>
    </portlet>
    <role-mapper>
        <role-name>administrator</role-name>
        <role-link>Administrator</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>guest</role-name>
        <role-link>Guest</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>power-user</role-name>
        <role-link>Power User</role-link>
    </role-mapper>
    <role-mapper>
        <role-name>user</role-name>
        <role-link>User</role-link>
    </role-mapper>
</liferay-portlet-app>

每个按键的调试输出:

22:18:22,328 DEBUG [DebugPhaseListener:64] BEFORE phaseId=[RESTORE_VIEW 1] viewId=[null]
22:18:22,328 DEBUG [DebugPhaseListener:48] AFTER phaseId=[RESTORE_VIEW 1] viewId=[/views/my-calendar-portlet/view.xhtml]
22:18:22,328 DEBUG [DebugPhaseListener:64] BEFORE phaseId=[RENDER_RESPONSE 6] viewId=[/views/my-calendar-portlet/view.xhtml]
22:18:22,338 DEBUG [DebugPhaseListener:48] AFTER phaseId=[RENDER_RESPONSE 6] viewId=[/views/my-calendar-portlet/view.xhtml]
回答1

请将以下内容添加到WEB-INF/liferay-portlet.xml<portlet>部分:

<requires-namespaced-parameters>false</requires-namespaced-parameters>

确保遵循 DTD 并以正确的顺序包含元素:https://docs.liferay.com/ce/portal/7.0-latest/definitions/liferay-portlet-app_7_0_0.dtd.html。

例如,您的liferay-portlet.xml <portlet>部分应如下所示:

<portlet>
    <portlet-name>my-calendar-portlet</portlet-name>
    <icon>/icon.png</icon>
    <requires-namespaced-parameters>false</requires-namespaced-parameters>
    <ajaxable>false</ajaxable>
    <header-portlet-css>/css/main.css</header-portlet-css>
    <footer-portlet-javascript>
        /js/main.js
    </footer-portlet-javascript>
    <css-class-wrapper>
        my-calendar-portlet-portlet
    </css-class-wrapper>
</portlet>

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Why isn't Liferay Faces processing JSF portlet action events?
    I am having issues with trying to use Liferay Faces along with any JSF components to fire action events. I've gone through the first part of Liferay's Developing JSF Portlets instruction page up until (but not including) the Internationalize JSF Portlets section with success. I went ahead and added some other JSF components with some success as well, however, events are not working. The goal of this example is to have a text box where the user can change the default text of "World", and a text area will update by AJAX on every keystroke with "Hello, XXX" (where XXX is the text from the box)
  • 如何打开 JSF portlet 编辑模式的弹出窗口?(How can I open a pop up of my JSF portlet's edit mode?)
    问题 当打开 Liferay portlet 的配置模式时,它会在一个弹出对话框中打开: 我怎样才能让我的 JSF portlet 打开一个类似的弹出窗口,但对于我的 JSF portlet 的编辑模式? 我正在使用 Liferay 6.2。 回答1 在 Liferay 6.2+ 中: 在大多数情况下,您可以为 JSF 和 JSP portlet 以相同的方式打开 JSF portlet 的编辑模式:通过客户端 JS Liferay.Util.Window.getWindow() 方法。 要创建对话框,您需要在编辑模式下获取 portlet 的渲染 URL,并通过 portlet:renderURL 弹出状态: <portlet:renderURL var="popUpEditModeURL" escapeXml="false" portletMode="edit" windowState="pop_up" /> 然后使用Liferay.Util.Window.getWindow()方法中的 URL: <h:outputScript> AUI().use('liferay-util-window', function(A) { var popUp = Liferay.Util.Window.getWindow({ dialog: { centered: true
  • Liferay Portlet and JSF : Redirect during Render Phase
    I have a problem to implement a simple HTTP redirection. I use Liferay 6.0.6, our portlets are build with JSF2.0 / PortletFaces. I want to call a redirection when a view is loaded (and not when an action is triggered). Currently, my function is called by the PreRenderView listener. <f:metadata> <f:event listener="#{myControler.dispatch}" type="preRenderView" /> </f:metadata> In this function, i can check the permissions, do other stuff, and in some cases I want to redirect the user to a new page (not another view). I tried several methods, unsuccessfully. Specifically, I thought that this
  • Missing artifact org.primefaces.themes:cupertino:jar:1.0.9 [duplicate]
    This question already has answers here: jars are missing on `artifactory` server after installing primefaces all-themes (8 answers) Closed 1 year ago. I'm working on a project using liferay 6.1.1 and maven! I have this error message in pom.xml: Missing artifact org.primefaces.themes:cupertino:jar:1.0.9 even if the jar file is already there! When I tried to deploy the project, everything goes well ... but the warning persists even if the project works good. Any idea? pom.xml <?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema
  • 缺少工件 org.primefaces.themes:cupertino:jar:1.0.9 [重复](Missing artifact org.primefaces.themes:cupertino:jar:1.0.9 [duplicate])
    问题 这个问题在这里已经有了答案: 安装primefaces all-themes后,`artifactory`服务器上缺少jars (8个答案) 1 年前关闭。 我正在使用 liferay 6.1.1 和 maven 开发一个项目! 我在 pom.xml 中有此错误消息: 缺少工件 org.primefaces.themes:cupertino:jar:1.0.9 即使 jar 文件已经存在! 当我尝试部署项目时,一切顺利……但即使项目运行良好,警告仍然存在。 任何想法? pom.xml <?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <parent> <groupId>com.octave.portlet</groupId> <artifactId>octave-portlet</artifactId> <version>2.0.0</version> <relativePath>
  • 在 jsf 中使用 d3 图表有技巧吗?(Is there a trick to using d3 charts in jsf?)
    问题 我在 Liferay 中使用 Prime Faces,让 D3 示例显示在 jsf 中的技巧是什么,特别是 Liferay 上的 Prime Faces。 我试图在 JSF 中使用的示例是这样的:d3.js 差异图表示例如何处理 json 数据? 回答1 我想到了。 诀窍是引用一个 div 元素而不是 body。 我见过的所有示例都使用“body”。在门户容器中,您不想使用 body,因为这会将您置于端口之外。 一个 div 是必需的,并且必须像在 javascript 中一样被引用。 我在下面包含了新代码 <%@ page import="javax.portlet.WindowState" %> <%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %> <%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui" %> <portlet:defineObjects /> <form action="<portlet:actionURL />" method="post" name="<portlet:namespace />fm"> <div id="svgContainer" ></div> <script type="text
  • Liferay Portlet 基本 MVC 流程和视图选择(Liferay Portlet Basic MVC Flow and View Selection)
    问题 我正在尝试使用 LifeRay 6.1 开发一个基本的 portlet。 我精通各种 MVC 实现,但我发现 Liferay/java portlet 有点令人困惑——尤其是执行管道。 对于我使用过的大多数 MVC 框架,前提是简单的请求 > 路由器 > 控制器 > 视图。 视图选择通常基于控制器/动作命名约定、随请求传入或手动加载到控制器动作中的参数。 使用 LifeRay MVCPortlet 时,它不会像这样工作; 至少可以生成两种类型的 URL - 渲染 url 和操作 url。 渲染 URL 似乎完全绕过了我认为的控制器——MVCPortlet 的一个子类。 似乎这些 url 相对容易生成并且请求加载预期的视图,如果您可以调用它,考虑到所有意图和目的,它完全绕过控制器并且与模型无关。 <portlet:renderURL var="badminURL"><portlet:param name="mvcPath" value="/views/edit.jsp" /></portlet:renderURL> 动作 URL 通过控制器,动作被调用,然后默认视图用于呈现 portlet,而不管我提供什么作为 mvc 路径。 <portlet:actionURL var="adminURL" name="editSlide"><portlet:param name=
  • 当我的插件部署到 Liferay 时,我如何运行一些操作?(How can I run some action when my plugin was deployed to Liferay?)
    问题 我想在我的插件( portlet 、 hook或theme )在 Liferay 中可用后立即运行一些代码。 我在liferay-plugin-package.xml 、 liferay-portlet.xml 、 liferay-hook.xml或liferay-look-and-feel.xml找不到任何类似启动侦听器的东西。 回答1 还有另一种方法。 您可以利用 StartupAction。 它只是一个事件,每次启动插件时都会触发它。 此方法只会在服务器启动或部署时触发一次。 请注意,doRun 方法将一个由 companyIds 组成的 String 数组作为参数。 companyId 代表一个门户实例(Liferay 内部实例。不是另一个应用程序服务器。) 例如,我有一个依赖于一些自定义字段的 portlet。 所以我有这个整洁的小班: package de.osc.kaleositeaddon.startup; import com.liferay.portal.kernel.events.ActionException; import com.liferay.portal.kernel.events.SimpleAction; public class StartupAction extends SimpleAction { @Override public
  • 理解动作阶段和渲染阶段的执行(Understanding the execution of Action Phase and Render Phase)
    问题 我正在使用 Liferay 6 进行门户开发。 通过阅读 Liferay 开发人员指南,作者解释说 Portlet 执行有两个阶段 行动阶段渲染阶段 public class DateTimePortlet extends GenericPortlet { public void doView(RenderRequest req, RenderResponse res) throws IOException, PortletException { Object actionAttribute = req.getAttribute("datetime"); res.getWriter().println("Date Time:" + (actionAttribute != null ? actionAttribute :"Unavailable")); res.getWriter().println("<BR/>"); PortletURL u = res.createActionURL(); res.getWriter().println("<A href=" + u + ">Trigger an action."); res.getWriter().close(); } public void processAction(ActionRequest req
  • Liferay:ActionRequest、RenderRequest 和 PortletRequest 的关系和区别是什么?(Liferay: what is the relationship and difference between ActionRequest, RenderRequest and PortletRequest?)
    问题 ActionRequest 、 RenderRequest和PortletRequest之间的关系和区别是什么? 我们可以从另一个获取一个实例吗? 回答1 PortletRequest是两者的父级。 ActionRequest和RenderRequest都是不同类型的PortletRequest对象。 ActionRequest在 portlet 的操作处理阶段是有效的。 在这个阶段,portlet 还没有完全决定如何呈现自己,是最小化、最大化、编辑模式还是查看模式等。 另一方面, RenderRequest在 portlet 的呈现阶段是有效的。 此时,portlet 知道它将如何呈现自身,并且不允许某些更改(例如窗口状态)。 如果要将参数从动作传递到呈现,则需要使用设置ActionResponse response.setRenderParameter(key,val); 然后这在相应的RenderRequest可用。 答案在这里找到
  • 动作类不将对象传递给jsp类,在liferay中使用struts2(action class do not passing objects to jsp class ,using struts2 in liferay)
    问题 我在liferay中使用struts2来创建一个portlet,我有一个提交按钮做一个动作,在动作方法中我想填充一个私有字段并将它传递给resualt add.jsp但是当我想在add中打印该字段时.jsp 值为空。 问题是什么???!!! 我应该怎么办????!! 在运行服务器、构建/部署和执行期间没有错误或异常... 这是我的代码: portlet.xml http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0"> <description xml:lang="EN">IIN Subject</description> <portlet-name>MySiteStruts</portlet-name> <display-name>MySiteStruts</display-name> <!-- struts portlet class --> <portlet-class>org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher</portlet-class> <!-- The namespace for the actions configured for view mode --> <init-param> <name
  • Portlet 和 Web 服务之间的区别(Difference between portlet and a webservice)
    问题 我不确定我是否将洋葱与卷心菜进行比较。 但我真的对 portlet 和 Web 服务感到困惑。 我知道 Web 服务使您的应用程序中的软件组件成为其他应用程序的服务,但对我而言,它类似于响应请求的 portlet。 我知道我的理解让您(Portlet 和 SAAS 开发人员)非常沮丧。 但我需要对此有所澄清。 为什么我不能将请求-响应用于类似于 Web 服务的 Portlet 工作? 如果是,使用 Web 服务比使用 portlet 有什么好处? 如果不是,那么作为 Web 服务的 portlet 缺少什么? 我是 Portlet 开发的新手。 请不要因为这个问题诅咒我。 请建议。 编辑:大多数答案都说 portlet 是一个 UI 组件。 我的客户要求我在 liferay 中创建一个网络服务。 那么是将portlet 做成Web 服务吗? 如果是,您能否提供一个指针或一些代码片段? 回答1 专门针对 Liferay 解决您的“编辑”问题... Liferay 插件项目无需太多工作即可公开 Web 服务。 Liferay Service Builder 实际上有一些工具,因此您可以创建由 Liferay 数据库中的表支持的 SOAP Web 服务或 JSON Web 服务(并在现有数据库表上进行查询)。 在 JSON Web 服务的情况下,生成的 URL 方案不是
  • 从 Portlet 删除自定义权限/操作(Removing Custom Permissions/Actions from a Portlet)
    问题 我已经能够基于 Liferay Plugins SDK 中的这个示例定义自定义 portlet 操作/权限 https://github.com/liferay/liferay-plugins/tree/master/portlets/sample-permissions-portlet 我想知道从 portlet 中删除自定义 portlet 操作/权限(不是模型权限)需要采取的必要步骤。 我记得观察到当我重新部署带有修改的自定义操作/权限的 portlet 时,旧的自定义操作/权限仍然存在。 我尝试从 Tomcat 的 webapps 中删除 portlet 文件夹并成功注销。 但是在我再次部署 portlet 并从相应的 XML 中删除自定义操作/权限后,我仍然可以在定义角色的权限中看到权限。 我尝试在 Liferay 控制面板的服务器管理中清除权限设置,但它没有改变任何东西(它不应该改变)。 使用删除/修改的权限重新部署 portlet 并重新启动服务器后,我仍然看到分配给 portlet 的自定义操作/权限,但是当我选择 portlet 时,我看不到删除的权限,这是我的需要。 取消部署 portlet 是否会从 Liferay 门户和门户的数据库中删除所有相关的自定义操作/权限? 或者我是否需要进行单独的 Liferay 服务调用才能做到这一点?
  • 在 Liferay 6.1 搜索中包含动态数据列表记录的最佳方法(Best way to include Dynamic Data List Records in search in Liferay 6.1)
    问题 在 Liferay 6.2 中,可以在动态数据列表定义的字段上设置可Indexable选项,从而使它们可搜索(如 Liferay 6.2 文档中所述) 我想在我的搜索中包含 DDL 记录并且必须使用 Liferay 6.1。 我想知道,解决这个问题的最佳方法是什么。 现在我已经考虑过自定义搜索,但动态数据列表没有被提及作为一个选项。 我还查看了创建索引器后处理器钩子,但如果我理解正确,它只能改变现有的索引过程。 似乎可以为自定义资产创建索引器,但我想知道这是否是最好的方法,因为该过程可能非常耗时,而且我不知道适用于自定义资产的相同过程是否也适用于 Dynamic数据列表一般。 有没有更简单的方法可以在 Liferay 6.1(如 6.2 中)中实现我没有看到的可搜索动态数据列表? 回答1 我在 liferay-portlet.xml 的任何动态数据 portlet 定义中都找不到<indexer-class>声明。 因此,您需要创建一个 EXT 插件,该插件具有 1) 用于 DDL 记录的索引器类和 2) 使用 Portlet 169 的<indexer-class>更新的 liferay-portlet.xml。成功实现此目标后,您将拥有如本页所述更新您的搜索 portlet 的显示设置,并在以下列表中添加com.liferay.portlet
  • 如何仅通过单独的图标而不通过引用的输入字段来激活YUI Datepicker?(How do I activate a YUI Datepicker only by a seperate Icon, not by the referenced input field?)
    问题 我想显示一个AUI / YUI DatePicker(教程),它只能通过单击相应的图标来激活,而不是像通常那样focus于focus或click事件。 var AUI = YUI; AUI().use('event', 'aui-datepicker', function(A) { function createCalendar(calendarInputBox) { var datumInputField = calendarInputBox.one('input.calendar'); var datumInputFieldSelector = '#' + datumInputField.get('id').replace(/:/g, '\\:'); var datepickerIcon = calendarInputBox.one('.calendarInputIcon'); var datepicker = new A.DatePicker({ container : datumInputFieldSelector, mask : '%d.%m.%Y', calendar : { firstDayOfWeek : 1, }, popover : { zIndex : 1, } }); function
  • liferay-ui:search-container 中的动态列?(Dynamic columns in liferay-ui:search-container?)
    问题 我已经尝试过liferay-ui:search-container以表格/网格格式在 UI 上获取和显示数据库表格记录。 通过使用liferay-ui:search-container我得到如下所示的输出, 我正在获取上面屏幕截图中的 USER_ 表记录。 问题: 我想让网格列像动态一样,我想为最终用户启用一个选项来删除不需要的列并在相应的网格/表中添加想要的列。 前任: 在上面的屏幕截图中,以下列显示在网格中。 First Name, Last Name, Screen Name, Job Title, Organization, User Groups 现在,如果用户想要删除Job Title并想要在 UI 上添加Greetings and Mail Address列,并带有点击事件而不需要触摸/修改代码。 如何实现此功能? 笔记: 我需要为自定义模型实现此功能。 查询: 1) 是否有任何 api/方法来实现/启用此功能? 2)如果不是,我该如何实施这些步骤? 有什么建议或步骤来完成这项任务吗? 回答1 这可以通过向您的 portlet 添加一个配置页面来实现。 您可以开发 portlet 配置页面,该页面可以配置所需的选项并将其保存为 portlet 首选项。 稍后在显示搜索容器时,您可以检索 portlet 首选项并仅显示在配置表单中选择的那些列。 这是关于如何使用
  • 为什么我在 liferay 中收到 NullPointerException?(Why am I getting NullPointerException in liferay?)
    问题 我在以下行中收到NullPointerException : originalStrutsPortletAction.processAction( originalStrutsPortletAction, portletConfig, actionRequest, actionResponse); 我正在打印所有值: System.out.println(originalStrutsPortletAction); System.out.println(portletConfig); System.out.println(actionRequest); System.out.println(actionResponse); 输出: com.liferay.portal.struts.StrutsPortletActionAdapter@2f20c4be com.liferay.portlet.PortletConfigImpl@5f4268dd com.liferay.portlet.ActionRequestImpl@1054ae1e com.liferay.portlet.ActionResponseImpl@27733bf2 那么为什么我会收到NullPointerException呢? 请帮忙。提前致谢。 完整的堆栈跟踪如下:- java.lang
  • 在 Portlet Liferay 6.1 中呈现 Liferay 页面 URL(rendering Liferay page URLs inside of portlets Liferay 6.1)
    问题 我是 liferay 的新手,我几乎肯定这是非常简单的:使用速度标记,我希望能够生成指向 Liferay 网站中页面的链接,并将它们嵌入到不同页面的 portlet 中。 我对如何完成它有一个模糊的想法,所以我四处搜索,认为它会张贴在某个地方,但我找不到任何东西。 顺便说一下,我想把我想出的任何代码放在 portlet 的 view.jsp 中。 我会在这里使用速度标记,但我不认为(不确定)是否允许在 jsp 内部使用。 如果您需要更多信息来回复,请告诉我。 回答1 我会在这里使用速度标记,但我不认为(不确定)是否允许在 jsp 内部使用。 为什么要在 JSP ( view.jsp ) 中使用 Velocity 标记? 除了你在速度方面真的很棒的论点之外,我认为这样做没有任何好处。 尽管这里有一个链接可以帮助您在 JSP 中嵌入速度。 注意:在我看来,在 portlet 中的 JSP 中嵌入速度不是一个好习惯 在 JSP 中: 您将需要一个Layout对象,您可以借助 LayoutLocalServiceUtil 中的静态方法获得该对象。 获得布局后,您可以使用 com.liferay.portal.util.PortalUtil 的静态方法(如getLayoutFriendlyURL或getLayoutFullURL等)来构建 URL。 在 VM 中(这些将是主题中的*
  • 下载文件,文件名在 portlet 中不起作用(Download file, filename doesn't work in portlet)
    问题 我在HttpServletResponse标头中设置了文件名,但是当我下载它时没有这个文件名 FileInputStream fis = new FileInputStream(fileDocumento); PortletResponse portletResponse=(PortletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); HttpServletResponse res = PortalUtil.getHttpServletResponse(portletResponse); res.setHeader("Content-Disposition", "attachment; filename=schedaObiettivoTAC_.docx"); res.setHeader("Content-Transfer-Encoding", "binary"); res.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); res.flushBuffer(); OutputStream out=res.getOutputStream()
  • 「数字体验」Liferay数字体验平台(DXP)的好处
    随着DXP版本的发布,Liferay在它的基础产品上做了一个范式转换。通过这个版本,Liferay现在已经定义了一个路线图,以应对未来的技术趋势,比如微服务、数字体验管理、更智能、更快速的构建管理。在这篇文章中,我们将挑选一些Liferay DXP的新功能,并对它们进行详细的探讨。模块化:这实际上意味着Liferay的每个模块(特性)现在都是联合的,可以从核心Liferay安装中分离出来。虽然Liferay以前是一个单一的大型单片应用程序,但现在它由多个jar组成。这意味着企业现在可以在安装中挑选他们想要的东西,而不必为不必要的性能开销买单。优点:更简洁的安装,更少的性能开销,更易于管理的安装,更快的部署,更容易维护谁受益最大:广泛使用Liferay的几个模块的部署语义版本控制:现在,在一个Liferay实例上同时运行同一个模块的多个版本。例如,您的安装上运行了Wiki(特性)的一个版本,您现在可以根据该特性中的新需求进行更改,使用不同的版本控制,并且应用程序可以使用经过修改的版本控制服务。甚至旧版本和新版本都可以在同一个实例中使用好处:你现在可以有更新的beta版本的功能供用户使用,而不会影响当前的功能。另一个好处是实例化-相同的可以在同一个实例的不同形式。这将帮助你在A/B测试你的网页谁受益最多