<commit_before><img src="http://www.takes.org/logo.png" width="96px" height="96px"/>

[![Made By Teamed.io](http://img.teamed.io/btn.svg)](http://www.teamed.io)
[![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/takes)](http://www.rultor.com/p/yegor256/takes)
[![We recommend IntelliJ IDEA](http://img.teamed.io/intellij-idea-recommend.svg)](https://www.jetbrains.com/idea/)

[![Build Status](https://img.shields.io/travis/yegor256/takes/master.svg)](https://travis-ci.org/yegor256/takes)
[![Build status](https://img.shields.io/appveyor/ci/yegor256/takes/master.svg)](https://ci.appveyor.com/project/yegor256/takes/branch/master)
[![Javadoc](https://javadoc-emblem.rhcloud.com/doc/org.takes/takes/badge.svg?color=blue&prefix=v)](http://www.javadoc.io/doc/org.takes/takes)
[![Test Coverage](https://img.shields.io/codecov/c/github/yegor256/takes.svg)](https://codecov.io/github/yegor256/takes?branch=master)
[![codebeat badge](https://codebeat.co/badges/5721bba4-59cd-44ea-a60f-6043734187f7)](https://codebeat.co/projects/github-com-yegor256-takes)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/938e7683fcfa4db9bff362c2b4a9b78e)](https://www.codacy.com/app/github_90/takes?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=yegor256/takes&amp;utm_campaign=Badge_Grade)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/takes/blob/master/LICENSE.txt)

[![Maven Central](https://img.shields.io/maven-central/v/org.takes/takes.svg)](https://maven-badges.herokuapp.com/maven-central/org.takes/takes)
[![Dependencies](https://www.versioneye.com/user/projects/561a9c5ca193340f2f00110d/badge.svg?style=flat)](https://www.versioneye.com/user/projects/561a9c5ca193340f2f00110d)
[![PDD status](http://www.0pdd.com/svg?name=yegor256/takes)](http://www.0pdd.com/p?name=yegor256/takes)

**Takes** is a [true object-oriented](http://www.yegor256.com/2014/11/20/seven-virtues-of-good-object.html)
and [immutable](http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html)
Java7 web development framework. Its key benefits, comparing to all others, include these
four fundamental principles:

 1. not a single `null` ([why NULL is bad?](http://www.yegor256.com/2014/05/13/why-null-is-bad.html))
 2. not a single `public` `static` method ([why they are bad?](http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html))
 3. not a single mutable class ([why they are bad?](http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html))
 4. not a single `instanceof` keyword, type casting, or reflection ([why?](http://www.yegor256.com/2015/04/02/class-casting-is-anti-pattern.html))

Of course, there are no configuration files.
Besides that, these are more traditional features, out of the box:

 * hit-refresh debugging
 * [XML+XSLT](http://www.yegor256.com/2014/06/25/xml-and-xslt-in-browser.html)
 * [JSON](http://en.wikipedia.org/wiki/JSON)
 * [RESTful](http://en.wikipedia.org/wiki/Representational_state_transfer)
 * Templates, incl. [Apache Velocity](http://velocity.apache.org/)

This is what is not supported and won't be supported:

 * [WebSockets](http://en.wikipedia.org/wiki/WebSocket)

These [blog posts](http://www.yegor256.com/tag/takes.html) may help you too.

## Contents

- [Quick Start](#quick-start)
- [Build and Run With Maven](#build-a-run-with-maven)
- [Unit Testing](#unit-testing)
- [Integration Testing](#integration-testing)
- [A Bigger Example](#a-bigger-example)
- [Templates](#templates)
	- [Velocity Templates](#velocity-templates)
- [Static Resources](#static-resources)
- [Hit Refresh Debugging](#hit-refresh-debugging)
- [Request Methods (POST, PUT, HEAD, etc.)](#request-methods)
- [Request Parsing](#request-parsing)
- [Form Processing](#form-processing)
- [Exception Handling](#exception-handling)
- [Redirects](#redirects)
- [RsJSON](#rsjson)
- [RsXembly](#rsxembly)
- [GZIP Compression](#gzip-compression)
- [Authentication](#authentication)
- [Command Line Arguments](#command-line-arguments)
- [Logging](#logging)
- [Directory Layout](#directory-layout)
- [Optional dependencies](#optional-dependencies)
- [How to contribute](#how-to-contribute)
- [Got questions?](#got-questions)

## Quick Start

Create this `App.java` file:

```java
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.jar`](http://repo1.maven.org/maven2/org/takes/takes/) and compile your Java code:

```
$ javac -cp takes.jar App.java
```

Now, run it like this:

```bash
$ java -Dfile.encoding=UTF-8 -cp takes.jar:. App
```

Should work :)

This code starts a new HTTP server on port 8080 and renders a plain-text page on
all requests at the root URI.

**Important**: 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.encoding` Java 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 using `Charset.defaultCharset()` everywhere in the code.

## Build and Run With Maven

If you're using Maven, this is how your `pom.xml` should look like:

```xml
<project>
  <dependencies>
    <dependency>
      <groupId>org.takes</groupId>
      <artifactId>takes</artifactId>
    </dependency>
  </dependencies>
  <profiles>
    <profile>
      <id>hit-refresh</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.3</version>
            <executions>
              <execution>
                <id>start-server</id>
                <phase>pre-integration-test</phase>
                <goals>
                  <goal>java</goal>
                </goals>
                <configuration>
                  <mainClass>foo.App</mainClass> <!-- your main class -->
                  <cleanupDaemonThreads>false</cleanupDaemonThreads>
                  <arguments>
                    <argument>--port=${port}</argument>
                  </arguments>
                </configuration>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>
```

With this configutation you can run it from command line:

```
$ mvn clean integration-test -Phit-refresh -Dport=8080
```

Maven will start the server and you can see it at `http://localhost:8080`.

## Unit Testing

This is how you can unit test the app, using JUnit 4.x and
[Hamcrest](http://hamcrest.org):

```java
public final class AppTest {
  @Test
  public void returnsHttpResponse() throws Exception {
    MatcherAssert.assertThat(
      new RsPrint(
        new App().act(new RqFake("GET", "/"))
      ).printBody(),<commit_msg>fix the pom code in README.md<commit_after><img src="http://www.takes.org/logo.png" width="96px" height="96px"/>

[![Made By Teamed.io](http://img.teamed.io/btn.svg)](http://www.teamed.io)
[![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/takes)](http://www.rultor.com/p/yegor256/takes)
[![We recommend IntelliJ IDEA](http://img.teamed.io/intellij-idea-recommend.svg)](https://www.jetbrains.com/idea/)

[![Build Status](https://img.shields.io/travis/yegor256/takes/master.svg)](https://travis-ci.org/yegor256/takes)
[![Build status](https://img.shields.io/appveyor/ci/yegor256/takes/master.svg)](https://ci.appveyor.com/project/yegor256/takes/branch/master)
[![Javadoc](https://javadoc-emblem.rhcloud.com/doc/org.takes/takes/badge.svg?color=blue&prefix=v)](http://www.javadoc.io/doc/org.takes/takes)
[![Test Coverage](https://img.shields.io/codecov/c/github/yegor256/takes.svg)](https://codecov.io/github/yegor256/takes?branch=master)
[![codebeat badge](https://codebeat.co/badges/5721bba4-59cd-44ea-a60f-6043734187f7)](https://codebeat.co/projects/github-com-yegor256-takes)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/938e7683fcfa4db9bff362c2b4a9b78e)](https://www.codacy.com/app/github_90/takes?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=yegor256/takes&amp;utm_campaign=Badge_Grade)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/takes/blob/master/LICENSE.txt)

[![Maven Central](https://img.shields.io/maven-central/v/org.takes/takes.svg)](https://maven-badges.herokuapp.com/maven-central/org.takes/takes)
[![Dependencies](https://www.versioneye.com/user/projects/561a9c5ca193340f2f00110d/badge.svg?style=flat)](https://www.versioneye.com/user/projects/561a9c5ca193340f2f00110d)
[![PDD status](http://www.0pdd.com/svg?name=yegor256/takes)](http://www.0pdd.com/p?name=yegor256/takes)

**Takes** is a [true object-oriented](http://www.yegor256.com/2014/11/20/seven-virtues-of-good-object.html)
and [immutable](http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html)
Java7 web development framework. Its key benefits, comparing to all others, include these
four fundamental principles:

 1. not a single `null` ([why NULL is bad?](http://www.yegor256.com/2014/05/13/why-null-is-bad.html))
 2. not a single `public` `static` method ([why they are bad?](http://www.yegor256.com/2014/05/05/oop-alternative-to-utility-classes.html))
 3. not a single mutable class ([why they are bad?](http://www.yegor256.com/2014/06/09/objects-should-be-immutable.html))
 4. not a single `instanceof` keyword, type casting, or reflection ([why?](http://www.yegor256.com/2015/04/02/class-casting-is-anti-pattern.html))

Of course, there are no configuration files.
Besides that, these are more traditional features, out of the box:

 * hit-refresh debugging
 * [XML+XSLT](http://www.yegor256.com/2014/06/25/xml-and-xslt-in-browser.html)
 * [JSON](http://en.wikipedia.org/wiki/JSON)
 * [RESTful](http://en.wikipedia.org/wiki/Representational_state_transfer)
 * Templates, incl. [Apache Velocity](http://velocity.apache.org/)

This is what is not supported and won't be supported:

 * [WebSockets](http://en.wikipedia.org/wiki/WebSocket)

These [blog posts](http://www.yegor256.com/tag/takes.html) may help you too.

## Contents

- [Quick Start](#quick-start)
- [Build and Run With Maven](#build-a-run-with-maven)
- [Unit Testing](#unit-testing)
- [Integration Testing](#integration-testing)
- [A Bigger Example](#a-bigger-example)
- [Templates](#templates)
	- [Velocity Templates](#velocity-templates)
- [Static Resources](#static-resources)
- [Hit Refresh Debugging](#hit-refresh-debugging)
- [Request Methods (POST, PUT, HEAD, etc.)](#request-methods)
- [Request Parsing](#request-parsing)
- [Form Processing](#form-processing)
- [Exception Handling](#exception-handling)
- [Redirects](#redirects)
- [RsJSON](#rsjson)
- [RsXembly](#rsxembly)
- [GZIP Compression](#gzip-compression)
- [Authentication](#authentication)
- [Command Line Arguments](#command-line-arguments)
- [Logging](#logging)
- [Directory Layout](#directory-layout)
- [Optional dependencies](#optional-dependencies)
- [How to contribute](#how-to-contribute)
- [Got questions?](#got-questions)

## Quick Start

Create this `App.java` file:

```java
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.jar`](http://repo1.maven.org/maven2/org/takes/takes/) and compile your Java code:

```
$ javac -cp takes.jar App.java
```

Now, run it like this:

```bash
$ java -Dfile.encoding=UTF-8 -cp takes.jar:. App
```

Should work :)

This code starts a new HTTP server on port 8080 and renders a plain-text page on
all requests at the root URI.

**Important**: 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.encoding` Java 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 using `Charset.defaultCharset()` everywhere in the code.

## Build and Run With Maven

If you're using Maven, this is how your `pom.xml` should look like:

```xml
<project>
  <dependencies>
    <dependency>
      <groupId>org.takes</groupId>
      <artifactId>takes</artifactId>
    </dependency>
  </dependencies>
  <profiles>
    <profile>
      <id>hit-refresh</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.3</version>
            <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 configutation you can run it from command line:

```
$ mvn clean integration-test -Phit-refresh -Dport=8080
```

Maven will start the server and you can see it at `http://localhost:8080`.

## Unit Testing

This is how you can unit test the app, using JUnit 4.x and
[Hamcrest](http://hamcrest.org):

```java
public final class AppTest {
  @Test
  public void returnsHttpResponse() throws Exception {
    MatcherAssert.assertThat(
      new RsPrint(
        new App().act(new RqFake("GET", "/"))
      ).printBody(),
{'fraction_non_alphanumeric': 0.16157778391820946, 'fraction_numerical': 0.03177673390439348, 'mean_word_length': 3.8176372712146422, 'pattern_counts': {'":': 0, '<': 107, '<?xml version=': 0, '>': 107, 'https://': 36, 'lorem ipsum': 0, 'www.': 38, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1476146', 'n_tokens_mistral': 5453, 'n_tokens_neox': 4884, 'n_words': 968}