Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用于包装请求正文的吊索过滤器_Java_Servlets_Aem_Sling - Fatal编程技术网

Java 用于包装请求正文的吊索过滤器

Java 用于包装请求正文的吊索过滤器,java,servlets,aem,sling,Java,Servlets,Aem,Sling,用例: 我们正在开发一个AEM封闭用户组网站,用户需要提交触发工作流的表单。由于用户经过身份验证,部分工作流负载需要包括发起表单的用户 我正在考虑为此使用AEM表单,它保存到/content/usergenerated/content/Forms/af/my site下的节点,但有效负载中没有提到用户(仅服务用户)。在这种情况下,有两个服务用户:运行工作流的工作流服务和处理表单处理和初始保存的fd服务。例如,从工作流步骤调用的以下代码报告“fd服务” workItem.getWorkflowDa

用例: 我们正在开发一个AEM封闭用户组网站,用户需要提交触发工作流的表单。由于用户经过身份验证,部分工作流负载需要包括发起表单的用户

我正在考虑为此使用AEM表单,它保存到
/content/usergenerated/content/Forms/af/my site
下的节点,但有效负载中没有提到用户(仅服务用户)。在这种情况下,有两个服务用户:运行工作流的工作流服务和处理表单处理和初始保存的fd服务。例如,从工作流步骤调用的以下代码报告“fd服务”

workItem.getWorkflowData().getMetaDataMap().get("userId", String.class);
为了克服这一限制

从发布AEM实例启动的工作流:当从AEM发布实例提交自适应表单、交互式通信或信函时,使用服务用户创建所有工作流实例。在这些情况下,工作流实例数据中不会捕获登录用户的用户名

在AEM表单servlet使用请求包装器修改请求主体并添加原始用户ID之前,我添加了一个过滤器servlet来截获初始表单提交

在表单、工作流和启动器方面。。这就是我的基本设置

我审查了以下资源:

这是我的包装器的代码

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletInputStream;
import java.io.*;

public class FormSubmitRequestWrapper extends SlingHttpServletRequestWrapper {
String requestPayload;
private static final Logger log = LoggerFactory.getLogger(FormSubmitRequestWrapper.class);

public FormSubmitRequestWrapper(SlingHttpServletRequest slingRequest) {
    super(slingRequest);

    // read the original payload into the requestPayload variable
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = null;
    try {
        // read the payload into the StringBuilder
        InputStream inputStream = slingRequest.getInputStream();
        if (inputStream != null) {
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                stringBuilder.append(charBuffer, 0, bytesRead);
            }
        } else {
            // make an empty string since there is no payload
            stringBuilder.append("");
        }
    } catch (IOException ex) {
        log.error("Error reading the request payload", ex);
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException iox) {
                log.error("Error closing bufferedReader", iox);
            }
        }
    }
    requestPayload = stringBuilder.toString();
}

/**
 * Override of the getInputStream() method which returns an InputStream that reads from the
 * stored requestPayload string instead of from the request's actual InputStream.
 */
@Override
public ServletInputStream getInputStream ()
        throws IOException {

    final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestPayload.getBytes());
    ServletInputStream inputStream = new ServletInputStream() {
        public int read ()
                throws IOException {
            return byteArrayInputStream.read();
        }
    };
    return inputStream;
}
}
这是我的过滤器

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.engine.EngineConstants;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import javax.jcr.Session;
import javax.servlet.*;
import java.io.IOException;


@Component(service = Filter.class,
        immediate = true,

        property = {
                Constants.SERVICE_DESCRIPTION + "=Add the CUG userID to any UGC posts",
                EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
                Constants.SERVICE_RANKING + ":Integer=3000",
                EngineConstants.SLING_FILTER_PATTERN + "=/content/forms/af/my-site.*"
        })


public class DecorateUserGeneratedFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(DecorateUserGeneratedFilter.class);

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

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse ) response;
        final SlingHttpServletRequest slingRequest= (SlingHttpServletRequest) request;

        FormSubmitRequestWrapper wrappedRequest = new FormSubmitRequestWrapper(slingRequest);

        log.info("starting ConfirmAlumniStatus workflow");
        log.info(getCurrentUserId(slingRequest));

        chain.doFilter(wrappedRequest, slingResponse);
    }

    @Override
    public void destroy() {

    }

    public String getCurrentUserId(SlingHttpServletRequest request) {
        ResourceResolver resolver = request.getResourceResolver();
        Session session = resolver.adaptTo(Session.class);
        String userId = session.getUserID();

        return userId;

    }

}
当提交的帖子被这个过滤器处理时,我会得到下面的错误,说明请求主体已经被读取。因此,似乎过滤器排名可能不够高

2018年6月25日13:11:13.200错误[0:0:0:0:0:0:0:0:1[1529946669719]POST/content/forms/af/my site/request access/jcr:content/guideContainer.af.internalsubmit.jsp HTTP/1.1]org.apache.sling.engine.impl.SlingRequestProcessorImpl 服务:未捕获的可丢弃java.lang.IllegalStateException:请求 数据已在上读取 org.apache.sling.engine.impl.request.RequestData.getInputStream(RequestData.java:669) 在 org.apache.sling.engine.impl.SlingHttpServletRequestImpl.getInputStream(SlingHttpServletRequestImpl.java:292) 在 servlet.ServletRequestWrapper.getInputStream(ServletRequestWrapper.java:136) 在 my.site.servlets.FormSubmitRequestWrapper.(FormSubmitRequestWrapper.java:26) 在 my.site.servlets.DecorateUserGeneratedFilter.doFilter(DecorateUserGeneratedFilter.java:75) 在 org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68) 在 org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:73) 在 org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:73) 在 com.cognifide.cq.includefilter.DynamicIncludeFilter.doFilter(DynamicIncludeFilter.java:82) 在 org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter(AbstractSlingFilterChain.java:68) 在 org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter.doFilter(RequestProgressTrackerLogFilter.java:10

我认为服务排名不起作用。当我查看 我的过滤器如图所示列出。从列出的其他过滤器来看,我认为最左边的数字是过滤器排名。出于某种原因,我的过滤器排名为0,即使我将其设置为服务。排名=700

0:类my.site.servlets.DecorateUserGeneratedFilter(id: 8402,属性:service.ranking=700);调用:0;时间:0ms;时间/调用: -1µs


更新:我能够修复筛选器列组,使其700仍然给出IllegalStateException。使其3000使该问题消失。但是当从我的包装器调用request.getInputStream()时,它返回null。

正确的想法,错误的位置

简单的回答是,当您实现SlingHttpServletRequestWrapper时,如果您正在动态添加参数,它将提供对原始SlingHttpServletRequest的方法调用的默认处理。您要做的是确保覆盖与参数交互的方法,以便您可以确保因此,在初始化时,调用原始参数映射,将这些项复制到包含您自己的值的新映射中

然后超越任何请求这些值的方法

getParameter(String)
getParameterMap()
getParameterNames()
getParameterValues(String)
不要触摸InputStream,它已被处理以获取传入的任何参数

此外,这是处理此类用例的两种方法之一,另一种方法是使用所记录的SlingPostProcessor


它允许您检测正在写入存储库的内容,并修改数据,使其像您的案例一样包含一个附加字段。

正确的想法,错误的位置

简单的回答是,当您实现SlingHttpServletRequestWrapper时,如果您正在动态添加参数,它将提供对原始SlingHttpServletRequest的方法调用的默认处理。您要做的是确保覆盖与参数交互的方法,以便您可以确保因此,在初始化时,调用原始参数映射,将这些项复制到包含您自己的值的新映射中

然后超越任何请求这些值的方法

getParameter(String)
getParameterMap()
getParameterNames()
getParameterValues(String)
不要触摸InputStream,它已被处理以获取传入的任何参数

此外,这是处理此类用例的两种方法之一,另一种方法是使用所记录的SlingPostProcessor


它允许您检测正在写入存储库的内容,并修改数据,使其像您的案例一样包含一个附加字段。

您尝试执行的操作可能很简单,但对于新的AEM版本来说可能不是未来的证明

您需要完全控制工作流的触发方式!:

  • 你的