You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Liferay技术求助:Portal.getUser登录后失效及文档阅读事件记录需求

Let's tackle your two Liferay issues one by one with practical, actionable solutions:

Issue 1: Portal.getUser() Failing After User Login

If Portal.getUser() isn't returning the authenticated user post-login, here's how to diagnose and fix it:

  • Confirm request context validity: Portal.getUser() relies on being called within an active Liferay request context (e.g., inside a Portlet action, MVC command, or servlet filter). If you're calling it from a background thread or non-request-triggered code, it won't work—instead, pass the User object explicitly or fetch it via UserLocalServiceUtil using a known user ID.
  • Verify login status first: Always check if the user is signed in before calling Portal.getUser() with Portal.isUserSignedIn(request). This avoids null returns when the session is invalid or expired.
  • Handle multi-tenant environments: In a multi-portal setup, ensure you're targeting the correct company instance. Use Portal.getCompanyId(request) to scope your user lookup if needed.
  • Fallback to a reliable alternative: If Portal.getUser() continues to misbehave, use this more direct approach:
    String remoteUserId = request.getRemoteUser();
    if (remoteUserId != null) {
        User user = UserLocalServiceUtil.getUserById(Long.parseLong(remoteUserId));
        // Use the user object here
    }
    
Issue 2: Tracking Document Reads via Hook Filter for Direct Document Library URLs

Intercepting direct document access URLs (like your example http://localhost:8080/documents/20181/323505/dddd.pdf/d188618b-56c5-4be6-bf94-548fac22bc24) to log reader events requires a custom filter hooked into Liferay's document download servlet. Here's a step-by-step implementation:

Step 1: Create a Custom Filter

Implement javax.servlet.Filter to capture download requests and log reader events. This example parses the URL, fetches the authenticated user, and logs the event to your database:

package com.yourcompany.liferay.hooks.filter;

import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.util.PortalUtil;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;

public class DLDocumentReadTrackingFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String requestURI = httpRequest.getRequestURI();

        // Match direct document library access URLs
        if (requestURI.startsWith("/documents/")) {
            User currentUser = PortalUtil.getUser(httpRequest);
            
            if (currentUser != null) {
                // Parse URL components: groupId, folderId, fileName, document UUID
                String[] uriParts = requestURI.split("/");
                if (uriParts.length >= 6) {
                    try {
                        long groupId = Long.parseLong(uriParts[2]);
                        long folderId = Long.parseLong(uriParts[3]);
                        String fileName = uriParts[4];
                        String documentUuid = uriParts[5];

                        // Log the read event to your database
                        logDocumentReadEvent(
                            currentUser.getUserId(),
                            groupId,
                            folderId,
                            fileName,
                            documentUuid,
                            new Date()
                        );
                    } catch (NumberFormatException e) {
                        // Handle invalid URL format gracefully
                        e.printStackTrace();
                    }
                }
            }
            // Optional: Add logic for anonymous users (log IP address, etc.)
        }

        // Continue processing the download request
        chain.doFilter(request, response);
    }

    private void logDocumentReadEvent(long userId, long groupId, long folderId, String fileName, String documentUuid, Date readDate) {
        // Implement your database insert logic here
        // Example using Liferay's service builder (if you generated a DLReadEvent entity):
        /*
        DLReadEvent readEvent = DLReadEventLocalServiceUtil.createDLReadEvent(
            CounterLocalServiceUtil.increment(DLReadEvent.class.getName())
        );
        readEvent.setUserId(userId);
        readEvent.setGroupId(groupId);
        readEvent.setFolderId(folderId);
        readEvent.setFileName(fileName);
        readEvent.setDocumentUuid(documentUuid);
        readEvent.setReadDate(readDate);
        DLReadEventLocalServiceUtil.addDLReadEvent(readEvent);
        */
    }

    @Override
    public void destroy() {}
}

Step 2: Register the Filter via Hook

Update your liferay-hook.xml to attach the filter to Liferay's DLFileEntryDownloadServlet (the servlet that handles direct document downloads):

<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 7.4.0//EN" "http://www.liferay.com/dtd/liferay-hook_7_4_0.dtd">

<hook>
    <servlet-filter>
        <servlet-filter-name>DLDocumentReadTrackingFilter</servlet-filter-name>
        <servlet-filter-impl>com.yourcompany.liferay.hooks.filter.DLDocumentReadTrackingFilter</servlet-filter-impl>
    </servlet-filter>
    <servlet-filter-mapping>
        <servlet-filter-name>DLDocumentReadTrackingFilter</servlet-filter-name>
        <servlet-name>DLFileEntryDownloadServlet</servlet-name>
    </servlet-filter-mapping>
</hook>

Key Notes

  • Performance optimization: To avoid slowing down document downloads, run the database log asynchronously using Liferay's MessageBus or a scheduled task.
  • URL edge cases: Test for URLs with version numbers (e.g., /documents/.../version/1.0/...) and adjust your parsing logic to handle them.
  • Anonymous users: If consumers can access documents without logging in, add logic to log their IP address or session ID instead of a user ID.

内容的提问来源于stack exchange,提问作者Óscar Ibáñez Fernández

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:17:35