简短的回答是 Sling-Servlets 不支持 异步。你的异常在这个类中被抛出:
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();
}
但是您正在将 OSGi Http-Whiteboard 模式与 Sling-Servlet 混合使用。我不确定,你想做什么。
Sling/AEM 是一个技术堆栈,其中层建立在层之上。不幸的是,这些层中有多个允许注册 servlet。
-
Sling Servlets = Apache Sling(推荐,默认)
-
OSGi HTTP 白板模式 = Apache Felix(仅适用于特殊情况)
-
JEE Servlet = Jetty Servlet 容器(不推荐)
Sling-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!");
}
}
}