/** * Caso o response ja esteja fechado ou o metodo startAsync() ja tenha sido chamado, uma nova * invocacao resultara em uma IllegalStateException. */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.println("Antes de iniciar a tarefa assincrona"); /* * Para iniciar uma requisicao assincrona, basta chamar o metodo * startAsync de ServletRequest. O metodo startAsync é sobrecarregado * para receber um ServletRequest e um ServletResponse, desta forma é * possivel passar wrappers para ele. Caso o metodo startAsync seja * chamado, os objetos ServletRequest e Response originais serao * utilizados. */ AsyncContext asyncContext = req.startAsync(); MyAsyncTask asyncTask = new MyAsyncTask(asyncContext, writer); /* * O tempo padrao de time out depende do container, geralmente está * entre 5 e 10 segundos. Para desabilitar o time out basta informar um * valor negativo ou 0. Esse metodo pode ser chamado antes ou depois do * metodo start(). */ asyncContext.setTimeout(-1); /* * A Interface AsyncContext possui metodos para configurar a tarefa * assincrona e inicializar a mesma. O metodo estart recebe um runnable * que sera responsavel por realizar o processamento da tarefa * assincrona. Quando esse metodo é chamado, o processamento é realizado * por outra Thread do pool de Threads do servidor. */ asyncContext.start(asyncTask); /* * Depois do start() da tarefa assincrona, o fluxo continua normalmente, * e quando o metodo service() é encerrado, a resposta nao é commitada * enquanto o metodo complete() de AsyncContext não for chamado. Desta * forma, o container processa a tarefa assincrona um background em * outra Thread. */ writer.println("Depois de iniciar a tarefa assincrona"); /* * Retorna o AsyncContext inicializado para esse request. Caso o metodo * startAsync() ainda nao tenha sido chamado, uma IllegalStateException * ocorrera. */ req.getAsyncContext(); }
@Override public Object getAsyncResult(long timeout) { // MockHttpServletRequest type doesn't have async methods HttpServletRequest request = this.mockRequest; if ((timeout != 0) && request.isAsyncStarted()) { if (timeout == -1) { timeout = request.getAsyncContext().getTimeout(); } if (!awaitAsyncResult(timeout)) { throw new IllegalStateException( "Gave up waiting on async result from handler [" + this.handler + "] to complete"); } } return this.asyncResult; }
@Override protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException { result = new StringBuilder(); result.append('1'); result.append(req.isAsyncStarted()); req.startAsync(); result.append('2'); result.append(req.isAsyncStarted()); req.getAsyncContext() .start( new Runnable() { @Override public void run() { Thread t = new Thread( new Runnable() { @Override public void run() { try { result.append('3'); result.append(req.isAsyncStarted()); Thread.sleep(1000); result.append('4'); result.append(req.isAsyncStarted()); resp.setContentType("text/plain"); resp.getWriter().print("OK"); req.getAsyncContext().complete(); result.append('5'); result.append(req.isAsyncStarted()); done = true; } catch (InterruptedException e) { result.append(e); } catch (IOException e) { result.append(e); } } }); t.start(); } }); // Pointless method call so there is somewhere to put a break point // when debugging req.getMethod(); }
@Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { if (req.isAsyncStarted()) { req.getAsyncContext().complete(); } else if (req.isAsyncSupported()) { AsyncContext actx = req.startAsync(); actx.addListener(this); resp.setContentType("text/plain"); clients.add(actx); if (clientcount.incrementAndGet() == 1) { ticker.addTickListener(this); } } else { new Exception("Async Not Supported").printStackTrace(); resp.sendError(400, "Async is not supported."); } }
@Override public AsyncContext getAsyncContext() { return request.getAsyncContext(); }
/** Processes the HTTP request, */ protected void processRequest( HttpServletRequest request, HttpServletResponse response, String request_type) throws ServletException, IOException { try { // Is this a dispatch? Object consume_status_key = request.getAttribute(AsyncServletProcessUtil.CONSUME_STATUS_KEY); // Make a process client, PlatformContext ctx = PlatformContextFactory.getPlatformContext(); ProcessInputMessage result; ProcessResult result_ob; // Is this the continuation init? if (consume_status_key == null) { Cookie pid_cookie = null; // The process id cookie, Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie c : cookies) { String cname = c.getName(); if (cname.equals("pid")) { pid_cookie = c; } } } if (pid_cookie == null) { // Give a friendlier error message here? response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Session cookie not found"); return; } // Get the cookie's value, String process_id_str = pid_cookie.getValue(); AppServiceProcessClient process_client = ctx.getAppServiceProcessClient(); ProcessId process_id = ProcessId.fromString(process_id_str); String ip_addr = request.getRemoteAddr(); // Check if the process is valid, ProcessMessage msg_to_send = ByteArrayProcessMessage.encodeArgs("?", null, null, ip_addr); // Invoke the function on the process id, result_ob = process_client.invokeFunction(process_id, msg_to_send, true); request.setAttribute(getClass().getName(), result_ob); result = result_ob.getResult(AsyncServletProcessUtil.createNotifier(request)); if (result == null) { // Set timeout to 30 seconds, request.getAsyncContext().setTimeout(30 * 1000); return; } } // Not initial, else { result_ob = (ProcessResult) request.getAttribute(getClass().getName()); result = result_ob.getResult(); } // This would be a timeout, if (result == null) { response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Timed out waiting for response"); return; } if (result.getType() == ProcessInputMessage.Type.RETURN_EXCEPTION) { throw new ServletException(result.getError()); } // Ok, we now have our result from the process, Object[] args = ByteArrayProcessMessage.decodeArgsList(result.getMessage(), 0); String resp = (String) args[0]; if (!resp.equals("OK")) { throw new RuntimeException("Invalid response from process: " + resp); } // The user of the process, String username = (String) args[1]; // Ok, everything looks good to go, String location; String html_body; // Context info, String context_path = request.getContextPath(); if (context_path == null) context_path = ""; if (context_path.equals("/")) context_path = ""; String servlet_path = request.getServletPath(); String path_info = request.getPathInfo(); if (path_info == null) path_info = "/"; // Create the response, DDBResourceAccess mckoi_access = ctx.getDDBResourceAccess(); // Parse the link, StringBuilder request_link = new StringBuilder(); request_link.append(context_path); request_link.append(servlet_path); request_link.append(path_info); // Sub-part, int delim = path_info.lastIndexOf("/"); String path_p = path_info.substring(0, delim); if (path_p.startsWith("/")) { path_p = path_p.substring(1); } // 'path_p' now contains the path we are looking at, // If no path_p, if (path_p.equals("")) { String link_prepend = context_path + servlet_path + "/"; location = "Path List"; html_body = pathListSummary(mckoi_access, link_prepend); } else { ODBTransaction t = mckoi_access.createODBTransaction(path_p); // Extract the location, delim = request_link.lastIndexOf("/"); location = request_link.substring(delim + 1); String link_prepend = request_link.substring(0, delim + 1); // Get the 'pos' and 'size' vars if they exist, String pos = request.getParameter("pos"); String size = request.getParameter("size"); if (pos != null) { location = location + "?pos=" + pos + "&size=" + size; } if (location.equals("")) { location = "Path: " + path_p; html_body = ODBPathSummary(t, path_p, link_prepend); } else { // Get the formatter, ODBHTMLFormatter formatter = new ODBHTMLFormatter(t, link_prepend); // Format it, html_body = formatter.format(location); } } response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("<html>"); out.println("<head>"); out.println("<title>DBBrowser - " + HTMLWriter.toHTMLEntity(location) + "</title>"); out.println("<style type=\"text/css\">"); out.println(" table { border: 1px solid #000000; border-collapse: collapse; }"); out.println( " td { border-left: 1px solid #000000; border-right: 1px solid #000000; padding: 0px 6px 0px 6px; }"); out.println(" th { background: #000000; color: #FFFFFF; }"); out.println(" table.oblist { font-family:monospace; }"); out.println(" table.data { border: none; border-collapse: collapse; }"); out.println( " table.data td { border-left: none; border-right: none; padding: 2px 12px 2px 12px; }"); out.println("</style>"); out.println("</head>"); out.println("<body>"); out.println(html_body); out.println("</body>"); out.println("</html>"); } finally { out.close(); } } catch (Throwable e) { // Output the error message, response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("<html>"); out.println("<head>"); out.println("<title>DBBrowser - error when producing page.</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>" + HTMLWriter.toHTMLEntity(e.getMessage()) + "</h1>"); out.print("<pre>"); StringWriter str_out = new StringWriter(); PrintWriter pout = new PrintWriter(str_out); e.printStackTrace(pout); pout.flush(); out.print(HTMLWriter.toHTMLEntity(str_out.toString())); out.println("</pre>"); out.println("</body>"); out.println("</html>"); } finally { out.close(); } } }