0

我想从 javascript 代码中进行 ajax 调用(以检查用户会话是否仍处于活动状态)。我希望我的代码独立于任何 portlet,因此希望在 javascript 中构建 url,而不必依赖 portlet id。

这可能在 MVCPortlet 框架内吗?如果没有,有替代品吗?

在此行下方编辑。

我知道liferay的会话管理机制,我实际上已经设置了会话的自动扩展。但是我的两个用户丢失了他们的长时间输入,因为尽管有这种机制,会话还是过期了(我相信他们打断了他们的工作,他们的计算机进入了睡眠状态......)。

我想通过在从某些表单提交输入之前检查会话是否仍处于活动状态来避免这种情况。我这样做的方式是在提交之前添加一个 ajax 调用,我将在下面详细介绍。

我真正的问题是:如何在该代码中消除对 portletId 的依赖,这样我就不需要更改要在其中实现此机制的每个 portlet。

我今天使用以下 javascript 函数执行此操作:

Liferay.provide(window, "bb_checkSession",
    function (sessionId, portletId, successCallback, failureCallback) {
        var A = AUI();
        var resourceUrl = Liferay.PortletURL.createResourceURL();
        resourceUrl.setResourceId("CHECK_SESSION");
        resourceUrl.setPortletId(portletId);
        A.io.request(resourceUrl.toString(), {
            method: 'GET',
            cache: false,
            on: {
                success: function () {
                    var responseData = A.JSON.parse(this.get('responseData'));
                    if (responseData == null || sessionId != responseData.sessionId) {
                        if (failureCallback) failureCallback();
                    } else {
                        if (successCallback) successCallback();
                    }
                },
                failure: function () {
                    if (failureCallback) failureCallback();
                }
            }
        });
    },
    ['aui-io', 'liferay-portlet-url']
);

在我的 portlet 中,我按如下方式处理调用

public void checkSession(ResourceRequest resourceRequest, ResourceResponse resourceResponse) throws IOException {

    PortletSession session = resourceRequest.getPortletSession();

    JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
    resourceResponse.setContentType("text/javascript");
    jsonObject.put("sessionId", session.getId());
    resourceResponse.getWriter().write(jsonObject.toString());
}
4

2 回答 2

0

这可以通过Jquery轻松实现。如果web.xml您已将 15 分钟定义session-timeout为 15 分钟,则在第 14 分钟会出现一个灯箱,询问用户是否希望继续会话或注销。

如果用户希望继续会话,则/c/portal/extend_session调用(Ajax),否则/c/portal/logout调用。

下面的代码独立于任何类型的 portlet 工作。您需要将此代码放在您的 JSP/Facelets 页面中。

<script src="/static-files/scripts/jquery-1.6.2.js" type="text/javascript" charset="utf-8"></script>
<script src="/static-files/scripts/jquery-ui.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/static-files/scripts/jquery.idletimer.js" type="text/javascript" charset="utf-8"></script>
<script src="/static-files/scripts/jquery.idletimeout.js" type="text/javascript" charset="utf-8"></script>
<link href="/static-files/css/jquery-ui-rev.css" type="text/css" rel="stylesheet"/>

<script type="text/javascript" charset="utf-8">
var $j=jQuery.noConflict();
$j(document).ready(function()
        {

    $j("#dialog").attr("style","visibility:visible");
    var titletext=$j(this).attr('title');
    $j("#dialog").bind("contextmenu",function(event)
            {   return false; })

// setup the dialog
$j("#dialog").dialog({
    autoOpen: false,
    modal: true,
    width: 400,
    height: 200,
    closeOnEscape: false,
    draggable: false,
    resizable: false,
    buttons: {
    'Yes, Continue': function()
    {

        $j.ajax({
              url: '/c/portal/extend_session',
              cache: false,
              success: function() {
                $j('div#dialog').dialog('close');
              }
            });

        $j(document).attr('title',titletext);
        },
        'No, Log out': function(){

            $j.idleTimeout.options.onTimeout.call($j.post('/c/portal/logout',function()
                {}))
        }
    }

});

// cache a reference to the countdown element so we don't have to query the DOM for it on each ping.
var $jcountdown = $j("#dialog-countdown");

// start the idle timer plugint
$j.idleTimeout('#dialog', 'div.ui-dialog-buttonpane button:first', {
    idleAfter: 840,   // 14 mins

    onTimeout: function(){
        window.location.replace("/c/portal/logout");
    },
    onIdle: function(){
        $j(document).attr('title', 'Warning! Due to inactivity, your session is about to expire.');
        $j(this).dialog("open");


    },
    onCountdown: function(counter){
        $jcountdown.html(counter); // update the counter
    }
});
        });
</script>

<!-- dialog window markup -->
<div id="dialog" title="Your session is about to expire!" style="visibility:hidden">
    <p>
        <span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 50px 0;"></span>
        You will be logged out in <span id="dialog-countdown" style="font-weight:bold;whitespace:nowrap"></span> seconds.
    </p>

    <p>Do you wish to continue your session?</p>
</div>
于 2013-05-31T04:31:09.217 回答
0

Vikas V 为您提供了一些您可以使用的代码 - 您的问题有两个方面与我的看法不符......

  1. Liferay 已经有这样的机制 - 例如登录到您的门户并让它静置 30 分钟(或将超时配置为更早),您会看到您收到一条警告消息,然后是“您已注销" 如果您不单击“延长会话”,则显示消息。在 6.1 中,这甚至可以通过多个打开的选项卡工作(我相信它使用 js-cookies 来包含时间戳,以便所有选项卡同时超时)
  2. 如果您向服务器发出请求以检查会话是否仍处于活动状态,则您可能会延长会话 - 例如,仅检查会话是否处于活动状态可能会永久扩展它

因此,我的建议是挂钩 Liferay 的机制(如果您需要提示在哪里找到它,请在此处编辑您的问题或评论,我必须查找它)或使用您自己的完全客户端实现。如果您选择自己的实现(例如 Vikas V 建议的),请记住您可能打开了多个选项卡,并且您不希望被您在后台忘记的陈旧选项卡注销。

于 2013-05-31T06:33:58.607 回答