Takes
True Object-Oriented Java Web Framework without NULLs, Static Methods, Annotations, and Mutable Objects
Install / Use
/learn @yegor256/TakesREADME
Pure Object-Oriented Java Web Framework
Takes is a [true object-oriented][oop] and [immutable][immutable] Java 8 web development framework. Its key benefits, compared to all others, include these four fundamental principles:
- Not a single
null([why is NULL bad?][null]) - Not a single
publicstaticmethod ([why are they bad?][utility]) - Not a single mutable class ([why are they bad?][immutable])
- Not a single
instanceofkeyword, type casting, or reflection ([why?][casting])
Of course, there are no configuration files. Besides that, these are the more traditional features, out of the box:
- Hit-refresh debugging
- XML+XSLT
- JSON
- RESTful
- Templates, including Apache Velocity
This is what is not supported and will not be supported:
These two web systems use Takes, and they are open source: rultor.com (sources), jare.io (sources).
Watch these videos to learn more: [An Immutable Object-Oriented Web Framework][webcast] and Takes, Java Web Framework, Intro. This blog post may help you as well.
Contents
- Quick Start
- Build and Run With Maven
- Build and Run With Gradle
- Unit Testing
- Integration Testing
- A Bigger Example
- Templates
- Static Resources
- Hit Refresh Debugging
- Request Methods (POST, PUT, HEAD, etc.)
- Request Parsing
- Form Processing
- Exception Handling
- Redirects
- RsJSON
- RsXembly
- GZIP Compression
- SSL Configuration
- Authentication
- Command Line Arguments
- Logging
- Directory Layout
- Optional dependencies
- Backward compatibility
- Version pattern for RESTful API
- How to contribute
Quick Start
Create this App.java file:
import org.takes.http.Exit;
import org.takes.http.FtBasic;
import org.takes.facets.fork.FkRegex;
import org.takes.facets.fork.TkFork;
public final class App {
public static void main(final String... args) throws Exception {
new FtBasic(
new TkFork(new FkRegex("/", "hello, world!")), 8080
).start(Exit.NEVER);
}
}
Then, download [takes-1.25.0-jar-with-dependencies.jar][jar]
and compile your Java code:
javac -cp takes-1.25.0-jar-with-dependencies.jar App.java
Now, run it like this:
java -Dfile.encoding=UTF-8 -cp takes-1.25.0-jar-with-dependencies.jar:. App
It should work!
This code starts a new HTTP server on port 8080 and renders a plain-text page for all requests at the root URI.
[!CAUTION] Pay attention that UTF-8 encoding is set on the command line. The entire framework relies on your default Java encoding, which is not necessarily UTF-8 by default. To be sure, always set it on the command line with
file.encodingJava argument. We decided not to hard-code "UTF-8" in our code mostly because this would be against the entire idea of Java localization, according to which a user always should have a choice of encoding and language selection. We're usingCharset.defaultCharset()everywhere in the code.
Build and Run With Maven
If you're using Maven, this is how your pom.xml should look:
<project>
<dependencies>
<dependency>
<groupId>org.takes</groupId>
<artifactId>takes</artifactId>
<version>1.25.0</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>hit-refresh</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>start-server</id>
<phase>pre-integration-test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>foo.App</mainClass> <!-- your main class -->
<cleanupDaemonThreads>false</cleanupDaemonThreads>
<arguments>
<argument>--port=${port}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
With this configuration you can run it from the command line:
mvn clean integration-test -Phit-refresh -Dport=8080
Maven will start the server and you can see it at http://localhost:8080.
Using in a Servlet App
Create a Take with constructor accepting ServletContext:
package com.myapp;
public final class TkApp implements Take {
private final ServletContext ctx;
public TkApp(final ServletContext context) {
this.ctx = context;
}
@Override
public Response act(final Request req) throws Exception {
return new RsText("Hello servlet!");
}
}
Add org.takes.servlet.SrvTake to your web.xml, don't forget to specify
take class as servlet init-param:
<servlet>
<servlet-name>takes</servlet-name>
<servlet-class>org.takes.servlet.SrvTake</servlet-class>
<init-param>
<param-name>take</param-name>
<param-value>com.myapp.TkApp</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>takes</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Build and Run With Gradle
If you're using Gradle, this is how your build.gradle should look:
plugins {
id 'java'
id 'application'
}
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.takes', name: 'takes', version: '1.24.6'
}
mainClassName='foo.App' //your main class
With this configuration you can run it from the command line:
gradle run -Phit-refresh -Dport=8080
Unit Testing
This is how you can unit-test the app, using JUnit 4.x and Hamcrest:
public final class AppTest {
@Test
public void returnsHttpResponse() throws Exception {
MatcherAssert.assertThat(
new RsPrint(
new App().act(new RqFake("GET", "/"))
).printBody(),
Matchers.equalTo("hello, world!")
);
}
}
You can create a fake request with form parameters like this:
new RqForm.Fake(
new RqFake(),
"foo", "value-1",
"bar", "value-2"
)
Integration Testing
Here is how you can test the entire server via HTTP, using JUnit and jcabi-http for making HTTP requests:
public final class AppITCase {
@Test
public void returnsTextPageOnHttpRequest() throws Exception {
new FtRemote(new App()).exec(
new FtRemote.Script() {
@Override
public void exec(final URI home) throws IOException {
new JdkRequest(home)
.fetch()
.as(RestResponse.class)
.assertStatus(HttpURLConnection.HTTP_OK)
.assertBody(Matchers.equalTo("hello, world!"));
}
}
);
}
}
More complex integration testing examples can be found in one of the open source projects that use Takes, for example: [rultor.com][rultor-code].
A Bigger Example
Let's make it a bit more sophisticated:
public final class App {
public static void main(final String... args) {
new FtBasic(
new TkFork(
new FkRegex("/robots\\.txt", ""),
new FkRegex("/", new TkIndex())
),
8080
).start(Exit.NEVER);
}
}
The FtBasic accepts new incoming sockets on port 8080,
parses them according to HTTP 1.1 specification and creates instances
of class Request. Then, it gives requests to the instance of TkFork
(tk stands for "take") and expects it to return an instance of Take back.
As you pr
Related Skills
node-connect
339.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
339.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.8kCommit, push, and open a PR
