如何启用对Sling Servlet-Felix的异步支持



我有这个代码

@Component(service = Servlet.class, scope = ServiceScope.PROTOTYPE, property={
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN+"=/content/*",
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED+"=true",
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED+"=true"}
)
@SlingServletResourceTypes(
resourceTypes="cq/Page",
methods=HttpConstants.METHOD_GET,
selectors = "asynctest",
extensions="json")
public class ReactiveServlet extends HttpServlet {
@Override
protected void doGet(
HttpServletRequest  request, HttpServletResponse response)
throws ServletException, IOException {
AsyncContext async = request.startAsync();
// Some logic
}
}          

当调用这个servlet/content/mypage.asynctest.json时,得到这个错误

java.lang.IllegalStateException: null
at org.apache.felix.http.base.internal.dispatch.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:338) [org.apache.felix.http.jetty:4.1.10]
at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:369) [org.apache.felix.http.servlet-api:1.1.2]
at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:369) [org.apache.felix.http.servlet-api:1.1.2]

简单的答案是Sling Servlet不支持异步。您的异常在这个类中抛出:

https://github.com/apache/felix-dev/blob/master/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletRequestWrapper.java

@Override
public AsyncContext startAsync() throws IllegalStateException
{
if ( !this.asyncSupported )
{
throw new IllegalStateException();
}
return super.startAsync();
}

但是您将OSGiHttpWhiteboard模式与SlingServlet混合在一起。我不确定,你想做什么。

Sling/AEM是一种技术堆栈,其中层构建在层上。不幸的是,这些层中有多个允许注册servlet。

  • Sling Servlet=Apache Sling(推荐,默认(
  • OSGi HTTP白板模式=Apache Felix(仅适用于特殊情况(
  • JEE Servlet=Jetty Servlet容器(不推荐(

吊索Servlet

您在@SlingServletResourceTypes注册的Sling Servlet不支持异步。以下servlet的输出为:Async is not supported by an Sling-Servlet!(http://localhost:4502/content/we-retail.asynctest.json(

import static org.apache.sling.api.servlets.ServletResolverConstants.*;
import javax.servlet.AsyncContext;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.service.component.annotations.Component;
@Component(service = Servlet.class, property = {
SLING_SERVLET_RESOURCE_TYPES + "=cq:Page",
SLING_SERVLET_SELECTORS + "=asynctest",
SLING_SERVLET_EXTENSIONS + "=json",
SLING_SERVLET_METHODS + "=GET"
})
public class AsyncSlingServlet extends SlingSafeMethodsServlet {
@Override
protected void doGet(
SlingHttpServletRequest request,
SlingHttpServletResponse response
) throws ServletException, IOException {
if (request.isAsyncSupported() /* false */) {
final AsyncContext async = request.startAsync();
async.start(() -> {
async.getResponse().setContentType("text/plain");
async.getResponse().setCharacterEncoding("utf-8");
try {
async.getResponse().getWriter().println(
"Hello from the Sling-Servlet!");
} catch (IOException e) {
// ignore
}
async.complete();
});
} else {
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().println(
"Async is not supported by an Sling-Servlet!");
}
}
}

OSGi HTTP白板模式

通过OSGi HTTP白板模式注册的几乎相同的servlet支持异步。返回Hello from the OSGi Http-Whiteboard Servlet!(http://localhost:4502/my-project/hello(。但这样的servlet被Sling放在一边,所以它们是";竞争对手";或";竞争对手";。你必须小心,不要对Sling产生负面影响。因此应避免使用/content路径。

import javax.servlet.AsyncContext;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ServiceScope;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
@Component(
service = Servlet.class,
scope = ServiceScope.PROTOTYPE,
property = {
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN
+ "=/my-project/*",
HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT
+ "=("
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME
+ "=org.apache.sling)",
HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_ASYNC_SUPPORTED
+ "=true",
HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED
+ "=true" }
)
public class AsyncOSGiServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (request.isAsyncSupported() /* true */) {
final AsyncContext async = request.startAsync();
async.start(() -> {
async.getResponse().setContentType("text/plain");
async.getResponse().setCharacterEncoding("utf-8");
try {
async.getResponse().getWriter().println(
"Hello from the OSGi Http-Whiteboard Servlet!");
} catch (IOException e) {
// ignore
}
async.complete();
});
} else {
response.setContentType("text/plain");
response.setCharacterEncoding("utf-8");
response.getWriter().println(
"Async is not supported by an OSGi Http-Whiteboard Servlet!");
}
}
}

最新更新