I'm prototyping an e-commerce web application using Servlets and JSPs, so in order to make regular queries to get the status of a transaction (paid/not paid) from another server without stopping the web application, I'm trying to learn how to use asynchronous Servlets. After some reading and failed attempts of making examples of AsyncServlets found on the web, I've found maybe the simplest one on this video. Even so, it's giving me a headache. It throws an IllegalStateException, even if all the things seem to be in order, since it's a very simple application with no external libraries. I'm using NetBeans IDE 8.2, Java EE 7 Web and Tomcat 8.0.27. This is the code:
package com.za.tutorial.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(urlPatterns = {"/ProgressAsyncServlet"}, asyncSupported=true)
public class ProgressAsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter printWriter = response.getWriter();
printWriter.println("<html><head><title>Progress Async Servlet</title></head><body>");
printWriter.println("entering doGet() ==> thread name: " + Thread.currentThread().getName() + "<br>");
printWriter.println("<progress id='progress' max='100'></progress>");
AsyncContext asyncContext = request.startAsync();
asyncContext.start(() -> {
printWriter.println("thread name within asyncContext.start((): " + Thread.currentThread().getName() + "<br>");
int i = 0;
while (i <= 100) {
printWriter.println("<script>document.getElementById('progress').value=\"" + i++ + "\";</script>");
printWriter.flush();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
printWriter.println("<script>document.getElementById('progress').style.display='none';</script>");
printWriter.println("[time consuming generated and returned result]<br>");
printWriter.println("exiting doGet() ==> thread name: " + Thread.currentThread().getName() + "<br>");
printWriter.println("</body></html>");
asyncContext.complete();
});
}
}
Running the file containing the example of the synchronous ProgressServlet is ok, as expected. Though, after running the ProgressAsyncServlet file, which contains almost the same code (but with asynchronous methods), I get the following log:
04-Mar-2021 08:50:03.188 SEVERE [http-nio-8084-exec-23] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [com.za.tutorial.servlet.ProgressAsyncServlet] in context with path [/AsyncServletPrj01] threw exception java.lang.IllegalStateException: A filter or servlet of the current chain does not support asynchronous operations. at org.apache.catalina.connector.Request.startAsync(Request.java:1612) at org.apache.catalina.connector.Request.startAsync(Request.java:1605) at org.apache.catalina.connector.RequestFacade.startAsync(RequestFacade.java:1030) at javax.servlet.ServletRequestWrapper.startAsync(ServletRequestWrapper.java:373) at com.za.tutorial.servlet.ProgressAsyncServlet.doGet(ProgressAsyncServlet.java:32) at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
It's driving me crazy. How can such a simple code work this wrong?
Aucun commentaire:
Enregistrer un commentaire