当前位置: 首页 > 知识库问答 >
问题:

用于包装请求主体的吊带过滤器

东郭淇
2023-03-14
workItem.getWorkflowData().getMetaDataMap().get("userId", String.class);

为了解决这一限制,

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

我添加了一个过滤器servlet来拦截AEM Forms servlet之前的初始表单提交,使用请求包装器修改请求正文,添加原始用户ID。

我审查了以下资源:

  • 如何在java过滤器中更改servlet请求主体?
  • https://coderanch.com/t/364591/java/read-request-body-filter
  • https://gitter.im/adobe-consulting-services/acs-aem-commons?at=5b2d59885862c35f47bf3c71
  • https://helpx.adobe.com/experience-manager/6-4/forms/using/forms-workflow-osgi-handling-user-data.html

下面是包装器的代码

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;

    }

}

0:类my.site.servlets.decoateUserGeneratedFilter(ID:8402,属性:service.ranking=700);调用:0;时间:0ms;时间/呼叫:-1μs

更新:我能够修复过滤器的等级,使其700仍然给出了IllegalStateException。把它变成3000使这个问题消失了。但是当从我的包装器调用request.getInputStream()时。它返回null。

共有1个答案

李开宇
2023-03-14

您试图做的可能是简单的路线,但可能不是未来的AEM新版本。

您需要完全控制如何触发工作流!:

  1. 表单应该有一个字段,该字段包含工作流路径(可能还有该工作流所需的其他信息)
  2. 创建窗体将发布到的自定义servlet。
  3. 在servlet过程中,所有用户都发布了值(来自表单)。尤其是获取预期的工作流路径并使用工作流API触发它。
 类似资料:
  • 问题内容: 将请求正文与GET请求一起传递是否违反REST风格? 例如在Elasticsearch中过滤一些信息 甚至设计了一些工具来避免GET请求中的请求主体(例如邮递员) 问题答案: 从RFC: GET请求消息中的有效负载没有定义的语义。在GET请求上发送有效内容正文可能会导致某些现有实现拒绝该请求。 换句话说,这不是禁止的,但是它是未定义的行为,应避免使用。HTTP客户端,服务器和代理可以随

  • 在play framework Java中找不到传入请求的请求体。我需要在play framework API中记录所有传入请求。为此,我尝试使用滤镜和动作组合。但我能得到请求体。 我尝试使用滤镜和动作组合。 从这个请求中,我可以得到body是否存在的布尔值。但却无法得到真正的尸体。

  • 我的应用程序只需要支持一个URL。喜欢http://.../service/api.要执行的操作取决于“操作”请求参数 为了处理这个问题,我创建了以下控制器 缺少ACTION参数时将调用 /view。对于前两个请求,我配置了OAuth身份验证,后者即 /view将使用formlogin。 我已经创建了一个过滤器,在那里我检查ACTION参数,如果丢失,我将请求转发到 /view处理程序。 下面是过

  • 我的http请求发送到此: 我的超文本传输协议请求与正文: { 我想通过WireMock映射这个请求。 这里是WireMock的映射文件。 我这样开始wireMock: 但当请求启动时,WireMock不会映射此请求。什么都没发生。为什么?

  • 泽西应用编程接口中是否有任何注释可用于实现基于头值的请求过滤?同样的情况在Spring like中实现 @RequestMapping(value=“/test”,method=RequestMethod.POST,headers={“version=v1.1”})

  • 在下面的示例中,我得到异常 当检查< code>if( i == 2 )失败时,我希望得到结果< code>Future( Test2 )。我如何在一个处理组合未来的for理解中处理filter/if? 下面是一个在Scala REPL中工作的简化示例。 代码: