收听文档和媒体视图/下载事件

时间:2017-10-27 09:28:32

标签: audit liferay-7

我希望每次有人观看次数下载时,我都会调用我的代码:

查看: enter image description here 下载: enter image description here

视图和下载的内容URL(HTTP响应是实际预览图像或PDF本身被转移)分别为:

http://localhost:8080/documents/20143/0/invoice_ABC_2017.10.27.pdf/c44fd479-331b-f393-7879-973c5cecf086?version=1.0&previewFileIndex=1
http://localhost:8080/documents/20143/0/invoice_ABC_2017.10.27.pdf/c44fd479-331b-f393-7879-973c5cecf086?download=true

对这两个请求的响应似乎是由WebServerServlet.sendFile构建的,它是Liferay的一部分,遗憾的是它不是OSGi模块。

我的第一直觉是实现ModelListener,但它只有创建/更新/删除事件的方法,没有读取事件的任何内容。

如何在Liferay中拦截这些事件? (7 EE DXP)

3 个答案:

答案 0 :(得分:0)

模型侦听器连接到可能在实体上发生的CRUD操作。

您可以将自己附加到下载操作中。看看https://dev.liferay.com/develop/tutorials/-/knowledge_base/7-0/converting-strutsactionwrappers-to-mvccommands

答案 1 :(得分:0)

预览

可以通过部署取代MVCRenderCommand.class服务的组件来拦截预览(在任何用户显示的预览页面的意义上)。为此,请复制Liferay's ViewFileEntryMVCRenderCommand.java并使用render方法添加代码:

@Component(
        property = {
                "service.ranking:Integer=100",
                "javax.portlet.name=" + DLPortletKeys.DOCUMENT_LIBRARY,
                "javax.portlet.name=" + DLPortletKeys.DOCUMENT_LIBRARY_ADMIN,
                "javax.portlet.name=" + DLPortletKeys.MEDIA_GALLERY_DISPLAY,
                "mvc.command.name=/document_library/view_file_entry"
        },
        service = MVCRenderCommand.class
)
public class MyViewFileEntryMVCRenderCommand implements MVCRenderCommand {

    @Override
    public String render(
            RenderRequest renderRequest, RenderResponse renderResponse)
        throws PortletException {

        DoMyAuditThing();

        [...]
   }

   [...]
}

下载

通过使用此liferay-hook.xml配置创建一个Servlet过滤器(从Liferay plugin samples复制),可以拦截下载(在实际下载的文档和媒体的意义上):

(更新:在编写此代码之后,我意识到现在有better way to write Servlet Filters

<hook>
        <servlet-filter>
                <servlet-filter-name>Sample Filter</servlet-filter-name>
                <servlet-filter-impl>com.liferay.sampleservletfilter.hook.filter.SampleFilter</servlet-filter-impl>
                <init-param>
                        <param-name>hello</param-name>
                        <param-value>world</param-value>
                </init-param>
        </servlet-filter>
        <servlet-filter-mapping>
                <servlet-filter-name>Sample Filter</servlet-filter-name>
                <before-filter>SSO Open SSO Filter</before-filter>
                <url-pattern>/documents/*</url-pattern>
                <dispatcher>REQUEST</dispatcher>
                <dispatcher>FORWARD</dispatcher>
        </servlet-filter-mapping>
</hook>

请注意<url-pattern>/documents/*</url-pattern>部分。

Filter类:

public class SampleFilter implements Filter {

        @Override
        public void doFilter(
                        ServletRequest servletRequest, ServletResponse servletResponse,
                        FilterChain filterChain)
                throws IOException, ServletException {

                String uri = (String)servletRequest.getAttribute(
                        WebKeys.INVOKER_FILTER_URI);

                // Extract information
                String[] tokens = uri.split("/");
                if(tokens.length < 6) {
                        System.out.println("Failed to parse download URI (Too few slashes): " + uri);
                        filterChain.doFilter(servletRequest, servletResponse);
                        return;
                }
                long groupId;
                try {
                        groupId = Long.parseLong(tokens[2]);
                }
                catch(NumberFormatException e) {
                        System.out.println("Failed to parse download URI (Group not a number): " + uri);
                        filterChain.doFilter(servletRequest, servletResponse);
                        return;
                }
                String uuid = tokens[5];
                System.out.println("group:" + groupId + " uuid:" + uuid);
                DLFileEntry fileEntry = DLFileEntryLocalServiceUtil.fetchDLFileEntryByUuidAndGroupId(uuid, groupId);

                // Send it to your audit
                [...]

                filterChain.doFilter(servletRequest, servletResponse);
        }
}

问题是,在显示“文档和媒体”页面时,它似乎也捕获了不必要的事件......我正在调查。

答案 2 :(得分:0)

您可以实现Service Wrapper,尤其是getFile方法。当用户请求下载文件时调用此方法。