Сценарий использования: мы разрабатываем сайт закрытой группы пользователей AEM, на котором пользователям необходимо будет отправлять формы, запускающие рабочие процессы.Поскольку пользователи проходят проверку подлинности, часть полезной нагрузки рабочего процесса должна включать пользователя, который инициировал форму.
Я рассматриваю для этого использование форм AEM, которые сохраняются на узлах под /content/usergenerated/content/forms/af/my-site
, но пользователь не упоминается в полезной нагрузке (только пользователь службы).В этом случае есть два пользователя сервиса: workflow-service, выполняющий рабочий процесс, и fd-service, который обрабатывал обработку формы и первоначальное сохранение.Например, следующий код, вызываемый из шага рабочего процесса, сообщает 'fd-service'
workItem.getWorkflowData().getMetaDataMap().get("userId", String.class);
Чтобы обойти это ограничение,
Рабочий процесс, инициированный из публикации экземпляра AEM: Все экземпляры рабочего процессасоздается с использованием пользователя службы, когда из экземпляра публикации AEM отправляются адаптивные формы, интерактивные сообщения или письма.В этих случаях имя пользователя, вошедшего в систему, не фиксируется в данных экземпляра рабочего процесса.
Я добавляю сервлет фильтра для перехвата первоначальной отправки формы перед сервлетом AEM Forms с использованиемОболочка запроса для изменения тела запроса с добавлением исходного идентификатора пользователя.
С точки зрения форм, рабочих процессов и средств запуска. Это в основном настройка, которую я имею https://helpx.adobe.com/aem-forms/6/aem-workflows-submit-process-form.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;
}
}
Когда POST-запросы обрабатываются этим фильтром, я получаю сообщение об ошибке ниже, в котором указано, что тело запроса имеетуже прочитано.Похоже, что рейтинг фильтра может быть недостаточно высоким.
25.06.2018 13: 11: 13.200 ОШИБКА [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 service: UncaughtБрошенный java.lang.IllegalStateException: данные запроса уже были прочитаны в org.apache.sling.engine.impl.request.RequestData.getInputStream (RequestData.java:669) в org.apache.sling.engine.impl.SlingHttpServletRequestInream.get(SlingHttpServletRequestImpl.java:292) в javax.servlet.ServletRequestWrapper.getInputStream (ServletRequestWrapper.java:136) в my.site.servlets.FormSubmitRequestWrapper. (FormSubmitRequest..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) в comc.doFilter (DynamicIncludeFilter.java:82) в org.apache.sling.engine.impl.filter.AbstractSlingFilterChain.doFilter (AbstractSlingFilterChain.java:68) в org.apache.sling.engine.impl.debug.RequestProilFFFЯва: 10
Я не думаю, что рейтинг сервиса работает.Когда я просматриваю http://localhost:4502/system/console/status-slingfilter, мой фильтр отображается как показано.Судя по другим перечисленным фильтрам, я думаю, что крайний левый номер - это рейтинг фильтра.По какой-то причине мой фильтр имеет рейтинг 0, хотя я установил как service.ranking = 700
0: class my.site.servlets.DecorateUserGeneratedFilter (id: 8402, property: service.ranking = 700);называется: 0;время: 0 мс;время / вызов: -1 мкс
Обновление: мне удалось исправить ранг фильтра, в результате чего значение 700 все еще дало исключение IllegalStateException.Если сделать 3000, то эта проблема исчезнет.Но когда request.getInputStream () вызывается из моей оболочки.Возвращает ноль.