diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml
index 4bb1a4fba1..a438d423e2 100644
--- a/libraries-3/pom.xml
+++ b/libraries-3/pom.xml
@@ -83,7 +83,6 @@
moshi-adapters
${moshi.version}
-
com.jcabi
jcabi-aspects
@@ -95,6 +94,16 @@
${aspectjrt.version}
runtime
+
+ org.takes
+ takes
+ ${takes.version}
+
+
+ org.apache.velocity
+ velocity-engine-core
+ ${velocity-engine-core.version}
+
@@ -132,8 +141,55 @@
+
+
+ src/main/webapp
+ true
+
+
-
+
+
+
+ reload
+
+
+
+ src/main/resources
+ true
+
+
+ src/main/webapp
+ true
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ ${exec-maven-plugin.version}
+
+
+ start-server
+ pre-integration-test
+
+ java
+
+
+
+
+ com.baeldung.takes.TakesApp
+ false
+
+ --port=${port}
+
+
+
+
+
+
+
+
1.78
1.18.6
@@ -151,5 +207,9 @@
0.14.1
1.9.2
1.9.2
+
+ 1.19
+ 2.2
+ 1.6.0
diff --git a/libraries-3/src/main/java/com/baeldung/takes/TakesApp.java b/libraries-3/src/main/java/com/baeldung/takes/TakesApp.java
new file mode 100644
index 0000000000..3c1407c291
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/takes/TakesApp.java
@@ -0,0 +1,42 @@
+package com.baeldung.takes;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+import org.takes.Response;
+import org.takes.facets.fallback.Fallback;
+import org.takes.facets.fallback.FbChain;
+import org.takes.facets.fallback.FbStatus;
+import org.takes.facets.fallback.RqFallback;
+import org.takes.facets.fallback.TkFallback;
+import org.takes.facets.fork.FkRegex;
+import org.takes.facets.fork.TkFork;
+import org.takes.http.Exit;
+import org.takes.http.FtBasic;
+import org.takes.misc.Opt;
+import org.takes.rs.RsText;
+
+public final class TakesApp {
+
+ public static void main(final String... args) throws IOException, SQLException {
+ new FtBasic(
+ new TkFallback(
+ new TkFork(
+ new FkRegex("/", new TakesHelloWorld()),
+ new FkRegex("/index", new TakesIndex()),
+ new FkRegex("/contact", new TakesContact())
+ ),
+ new FbChain(
+ new FbStatus(404, new RsText("Page Not Found")),
+ new FbStatus(405, new RsText("Method Not Allowed")),
+ new Fallback() {
+ @Override
+ public Opt route(final RqFallback req) {
+ return new Opt.Single(new RsText(req.throwable().getMessage()));
+ }
+ })
+ ), 6060
+ ).start(Exit.NEVER);
+ }
+
+}
\ No newline at end of file
diff --git a/libraries-3/src/main/java/com/baeldung/takes/TakesContact.java b/libraries-3/src/main/java/com/baeldung/takes/TakesContact.java
new file mode 100644
index 0000000000..e083bc3dc6
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/takes/TakesContact.java
@@ -0,0 +1,22 @@
+package com.baeldung.takes;
+
+import java.io.IOException;
+
+import org.takes.Request;
+import org.takes.Response;
+import org.takes.Take;
+import org.takes.rs.RsWithBody;
+import org.takes.rs.RsWithStatus;
+import org.takes.rs.RsWithType;
+
+public final class TakesContact implements Take {
+
+ @Override
+ public Response act(Request req) throws IOException {
+ return new RsWithStatus(
+ new RsWithType(
+ new RsWithBody("Contact us at https://www.baeldung.com"),
+ "text/html"), 200);
+ }
+
+}
diff --git a/libraries-3/src/main/java/com/baeldung/takes/TakesHelloWorld.java b/libraries-3/src/main/java/com/baeldung/takes/TakesHelloWorld.java
new file mode 100644
index 0000000000..9d1346d3c1
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/takes/TakesHelloWorld.java
@@ -0,0 +1,15 @@
+package com.baeldung.takes;
+
+import org.takes.Request;
+import org.takes.Response;
+import org.takes.Take;
+import org.takes.rs.RsText;
+
+public class TakesHelloWorld implements Take {
+
+ @Override
+ public Response act(final Request request) {
+ return new RsText("Hello, world!");
+ }
+
+}
diff --git a/libraries-3/src/main/java/com/baeldung/takes/TakesIndex.java b/libraries-3/src/main/java/com/baeldung/takes/TakesIndex.java
new file mode 100644
index 0000000000..3f74ba9c67
--- /dev/null
+++ b/libraries-3/src/main/java/com/baeldung/takes/TakesIndex.java
@@ -0,0 +1,24 @@
+package com.baeldung.takes;
+
+import java.io.IOException;
+
+import org.takes.Request;
+import org.takes.Response;
+import org.takes.Take;
+import org.takes.rq.form.RqFormSmart;
+import org.takes.rs.RsHtml;
+import org.takes.rs.RsVelocity;
+
+public final class TakesIndex implements Take {
+
+ @Override
+ public Response act(final Request req) throws IOException {
+ RqFormSmart form = new RqFormSmart(req);
+ String username = form.single("username");
+ return new RsHtml(
+ new RsVelocity(this.getClass().getResource("/templates/index.vm"),
+ new RsVelocity.Pair("username", username))
+ );
+ }
+
+}
diff --git a/libraries-3/src/main/webapp/templates/index.vm b/libraries-3/src/main/webapp/templates/index.vm
new file mode 100644
index 0000000000..5a97f654ce
--- /dev/null
+++ b/libraries-3/src/main/webapp/templates/index.vm
@@ -0,0 +1,9 @@
+
+
+Index
+
+
+Takes Web Application
+Welcome, ${username}
+
+
diff --git a/libraries-3/src/test/java/com/baeldung/takes/TakesAppIntegrationTest.java b/libraries-3/src/test/java/com/baeldung/takes/TakesAppIntegrationTest.java
new file mode 100644
index 0000000000..8b869d0742
--- /dev/null
+++ b/libraries-3/src/test/java/com/baeldung/takes/TakesAppIntegrationTest.java
@@ -0,0 +1,36 @@
+package com.baeldung.takes;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.net.URI;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.junit.Test;
+import org.takes.http.FtRemote;
+
+public class TakesAppIntegrationTest {
+
+ @Test
+ public void givenTake_whenRunRemoteServer_thenRespond() throws Exception {
+ new FtRemote(new TakesContact()).exec(
+ new FtRemote.Script() {
+ @Override
+ public void exec(final URI home) throws IOException {
+ HttpClient client = HttpClientBuilder.create().build();
+ HttpResponse response = client.execute(new HttpGet(home));
+ int statusCode = response.getStatusLine().getStatusCode();
+ HttpEntity entity = response.getEntity();
+ String result = EntityUtils.toString(entity);
+
+ assertEquals(200, statusCode);
+ assertEquals("Contact us at https://www.baeldung.com", result);
+ }
+ });
+ }
+}
diff --git a/libraries-3/src/test/java/com/baeldung/takes/TakesContactUnitTest.java b/libraries-3/src/test/java/com/baeldung/takes/TakesContactUnitTest.java
new file mode 100644
index 0000000000..5f8b7c57fc
--- /dev/null
+++ b/libraries-3/src/test/java/com/baeldung/takes/TakesContactUnitTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.takes;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.takes.rq.RqFake;
+import org.takes.rs.RsPrint;
+
+public class TakesContactUnitTest {
+
+ @Test
+ public void givenTake_whenInvokeActMethod_thenRespond() throws Exception {
+ final String resp = new RsPrint(new TakesContact().act(new RqFake())).printBody();
+ assertEquals("Contact us at https://www.baeldung.com", resp);
+ }
+
+}