Настройка встроенного в JDK HTTP сервера для работы по HTTP

В интернете легко найти великое множество разрозненных исходников демонстрирующих в той или иной мере работу с HTTPS. Реальные проекты частенько однако выходят за рамки разрозненных примеров, поэтому, хорошо бы иметь под рукой тестовое средство, позволяющее тестировать разные варианты. Таким средством может оказаться http сервер, предоставляемый непосредственно в JDK. Документацию на него можно найти здесь: http://docs.oracle.com/javase/6/docs/jre/api/net/httpserver/spec/com/sun/net/httpserver/package-summary.html.

Для начала на основе примера из документации делаю обычный сервер.

src/test/java/SimpleServerTest.java

import com.sun.net.httpserver.*;
import org.junit.Test;

import java.io.*;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class SimpleServerTest {

    static class MyHandler implements HttpHandler {
        public void handle(HttpExchange t) throws IOException {

            String response = "This is the response";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());

        }
    }

    @Test
    public void testSimpleServer() throws IOException, InterruptedException {
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 5);
        server.createContext("/", new MyHandler());

        ExecutorService executor = Executors.newFixedThreadPool(5);
        server.setExecutor(executor);
        server.start();
        executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ssl-test</groupId>
    <artifactId>ssl-test</artifactId>
    <version>1.0</version>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
        </dependency>
    </dependencies>
</project>


mvn test

Класс RequestHandler выполняет всю работу. В качестве параметра в метод handle передается объект HttpExchange. Этот объект предоставляет методы для чтения входящего запроса и генерации ответа. В примере, его бизнес-логику составляют всего 4-ре строчки:

String response = "This is the response";
t.sendResponseHeaders(200, response.length());
os = t.getResponseBody();
os.write(response.getBytes());

Все остальное — просто обработка исключений. В целом, для тестирования она и не нужна. Поэтому в следующих тестах я ее выброшу.

Старт сервера осуществляется в тестовом методе. Тест сделан на основе примера, лишь добавлен собственный ExecutorService. Собственный еxecutor сервис применен лишь для того, чтобы запущенный сервер немедленно не завершился.

Строчка

executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);

ожидает завершения ExecutorService-a. Это позволяет протестировать сервер, например, с помощью Web-браузера. Что я и проделал.

Сервер стартован на порт 8080. Запросы нормально обрабатываются при обращении к http://localhost:8080/.

Тестируюсь, всё работает как положено. В браузере получаю строчку This is the response. Теперь можно переходить к экспериментам с HTTPS.

Немного комментариев к тестовому коду:

    HttpServer server = HttpServer.create(new InetSocketAddress(8080), 5);

Создается сервер, который будет слушать на 8080 порту. Второй параметр показывает количество отложенных в очереди соединений. Этот параметр эквивалентен параметру функции listen() в библиотеке сокетов операционной системы.

    server.createContext("/", new RequestHandler());

Указывается, что при обращениях к URI, начинающимся с “/”, выполняется обращение к RequestHandler. При настройке нескольких RequestHandler-ов рекомендую посмотреть в документацию. Соотвествие URI находится не просто по самому длинному соответствию.

    ExecutorService executor = Executors.newFixedThreadPool(5);
    server.setExecutor(executor);
    server.start();
    executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);

Создается ExecutorService на основе тредового пула, стартуется сервер и ожидается завершение тредового пула. Как я писал выше, это для того, чтобы протестироваться «вручную» из Web-браузера. Если применять сервер при интеграционном тестировании, тогда далее просто может идти отсылка тестового запроса.

Небольшие выводы. Встроенный в JDK сервер весьма просто настраивается, поэтому его легко применить для тестов, когда необходимо сделать эмулятор каких-либо веб-сервисов.

Взято:
https://dev64.wordpress.com/2013/06/17/using-jdk-built-in-http-server/