Skip to content

Commit b7492c4

Browse files
committed
Fixes issue #96 - Add Servlet asynchronous Servlet example
1 parent 2d06e68 commit b7492c4

File tree

6 files changed

+223
-7
lines changed

6 files changed

+223
-7
lines changed

servlet/README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Servlet Examples
22

3-
1. [A HTTP servlet mapping example](httpServletMapping/README.md)
4-
2. [A HTTP session listener example](httpSessionListener/README.md)
5-
3. [A PushBuilder example](pushBuilder/README.md)
6-
4. [A ServletContextListener example](servletContextListener/README.md)
7-
5. [A ServletRequestListener example](servletRequestListener/README.md)
8-
6. [A @WebServlet example](webServlet/README.md)
3+
1. [An asynchronous servlet example](asyncServlet/README.md)
4+
2. [A HTTP servlet mapping example](httpServletMapping/README.md)
5+
3. [A HTTP session listener example](httpSessionListener/README.md)
6+
4. [A PushBuilder example](pushBuilder/README.md)
7+
5. [A ServletContextListener example](servletContextListener/README.md)
8+
6. [A ServletRequestListener example](servletRequestListener/README.md)
9+
7. [A @WebServlet example](webServlet/README.md)

servlet/asyncServlet/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# An asynchronous servlet example
2+
3+
This example demonstrates how to create an asynchronous Servlet.

servlet/asyncServlet/pom.xml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<project xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6+
<modelVersion>4.0.0</modelVersion>
7+
<parent>
8+
<artifactId>project</artifactId>
9+
<groupId>jakartaee.examples.servlet</groupId>
10+
<version>8-SNAPSHOT</version>
11+
</parent>
12+
<artifactId>asyncServlet</artifactId>
13+
<packaging>war</packaging>
14+
<name>An asynchronous servlet example</name>
15+
<dependencies>
16+
<dependency>
17+
<groupId>javax</groupId>
18+
<artifactId>javaee-web-api</artifactId>
19+
<scope>provided</scope>
20+
</dependency>
21+
</dependencies>
22+
<properties>
23+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
24+
</properties>
25+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) 2002-2018, Manorrock.com. All Rights Reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are met:
6+
*
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
*
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24+
* POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
package jakartaee.examples.servlet.asyncservlet;
27+
28+
import java.io.IOException;
29+
import java.io.PrintWriter;
30+
import java.util.ArrayList;
31+
import java.util.concurrent.ArrayBlockingQueue;
32+
import java.util.concurrent.BlockingQueue;
33+
import java.util.concurrent.Executors;
34+
import java.util.concurrent.ScheduledExecutorService;
35+
import java.util.concurrent.TimeUnit;
36+
import javax.servlet.AsyncContext;
37+
import javax.servlet.ServletConfig;
38+
import javax.servlet.ServletException;
39+
import javax.servlet.annotation.WebServlet;
40+
import javax.servlet.http.HttpServlet;
41+
import javax.servlet.http.HttpServletRequest;
42+
import javax.servlet.http.HttpServletResponse;
43+
44+
/**
45+
* The Servlet for the asynchronous servlet example.
46+
*
47+
* @author Manfred Riem ([email protected])
48+
*/
49+
@WebServlet(asyncSupported = true, value = "/*")
50+
public class AsyncServlet extends HttpServlet {
51+
52+
/**
53+
* Stores the executor service (for async processing).
54+
*/
55+
private ScheduledExecutorService executorService;
56+
57+
/**
58+
* Stores the queue.
59+
*/
60+
private BlockingQueue queue;
61+
62+
/**
63+
* Start the request.
64+
*
65+
* @param request the request.
66+
* @param response the response.
67+
* @throws IOException when an I/O error occurs.
68+
* @throws ServletException when a Servlet error occurs.
69+
*/
70+
@Override
71+
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
72+
queue.add(request.startAsync());
73+
}
74+
75+
/**
76+
* Initialize the servlet.
77+
*
78+
* @param config the servlet configuration.
79+
*/
80+
@Override
81+
public void init(ServletConfig config) {
82+
executorService = Executors.newScheduledThreadPool(1);
83+
executorService.scheduleAtFixedRate(() -> {
84+
ArrayList<AsyncContext> clients = new ArrayList<>();
85+
queue.drainTo(clients);
86+
clients.parallelStream().forEach((AsyncContext context) -> {
87+
try {
88+
PrintWriter writer = context.getResponse().getWriter();
89+
writer.println("OK");
90+
writer.flush();
91+
context.complete();
92+
} catch (IOException ioe) {
93+
}
94+
});
95+
}, 0, 2, TimeUnit.SECONDS);
96+
queue = new ArrayBlockingQueue(1000);
97+
}
98+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Permission to use, copy, modify, and/or distribute this software for any
3+
* purpose with or without fee is hereby granted.
4+
*
5+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIMS ALL WARRANTIES
6+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
7+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR
8+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
9+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
10+
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
11+
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
12+
*/
13+
package jakartaee.examples.servlet.asyncservlet;
14+
15+
import com.gargoylesoftware.htmlunit.TextPage;
16+
import com.gargoylesoftware.htmlunit.WebClient;
17+
import jakartaee.examples.test.commons.JakartaEEServer;
18+
import java.net.URL;
19+
import org.arquillian.container.chameleon.runner.ArquillianChameleon;
20+
import org.jboss.arquillian.container.test.api.Deployment;
21+
import org.jboss.arquillian.container.test.api.RunAsClient;
22+
import org.jboss.arquillian.test.api.ArquillianResource;
23+
import static org.jboss.shrinkwrap.api.ShrinkWrap.create;
24+
import org.jboss.shrinkwrap.api.spec.WebArchive;
25+
import org.junit.After;
26+
import static org.junit.Assert.assertTrue;
27+
import org.junit.Before;
28+
import org.junit.Test;
29+
import org.junit.runner.RunWith;
30+
31+
/**
32+
* The JUnit tests for the @WebServlet example.
33+
*
34+
* @author Manfred Riem ([email protected])
35+
*/
36+
@RunWith(ArquillianChameleon.class)
37+
@JakartaEEServer
38+
public class AsyncServletTest {
39+
40+
/**
41+
* Stores the base URL.
42+
*/
43+
@ArquillianResource
44+
private URL baseUrl;
45+
46+
/**
47+
* Stores the web client.
48+
*/
49+
private WebClient webClient;
50+
51+
/**
52+
* Setup before testing.
53+
*/
54+
@Before
55+
public void before() {
56+
webClient = new WebClient();
57+
}
58+
59+
/**
60+
* Create the deployment web archive.
61+
*
62+
* @return the deployment web archive.
63+
*/
64+
@Deployment
65+
public static WebArchive createDeployment() {
66+
return create(WebArchive.class).addClass(AsyncServlet.class);
67+
}
68+
69+
/**
70+
* Tear down after testing.
71+
*/
72+
@After
73+
public void after() {
74+
webClient.close();
75+
}
76+
77+
/**
78+
* Test the @WebServlet annotation.
79+
*
80+
* @throws Exception when a serious error occurs.
81+
*/
82+
@RunAsClient
83+
@Test
84+
public void testWebServletAnnotation() throws Exception {
85+
TextPage page = webClient.getPage(baseUrl);
86+
String content = page.getContent();
87+
assertTrue(content.contains("OK"));
88+
}
89+
}

servlet/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
<packaging>pom</packaging>
1515
<name>Servlet Examples</name>
1616
<modules>
17+
<module>asyncServlet</module>
1718
<module>httpServletMapping</module>
1819
<module>pushBuilder</module>
1920
<module>servletContextListener</module>
2021
<module>servletRequestListener</module>
2122
<module>webServlet</module>
2223
</modules>
23-
2424
<dependencies>
2525
<dependency>
2626
<groupId>jakartaee.examples</groupId>

0 commit comments

Comments
 (0)