Simple & Reliable Java HTTP-server

Рубрика: Development, Java | 22 December 2008, 13:43 | Vadim Voituk

Думаю никто не будет спорить с тем, что на данный момент HTTP является самым популярным высокоуровневым сетевым протоколом.
Как следствие, все больше и больше приложений используют его для организации сетевых коммуникаций, и все больше и больше приложений содержат в себе функционал примитивного HTTP-сервера.

Вариантов, как встроить в свое приложение небольшой HTTP-сервер уйма –
начиная от аскетичного и сложно-развиваемого 10-ти строчного HTTP-сервера на Groovy, заканчивая интеграцией в приложение небольшого сервлет-контейнера Jetty.

Я же хочу предложить что-то среднее между этими двумя вариантами.
Начиная с 6й версии, в составе JRE поставляется пакет “com.sun.net.httpserver”, который содержит реализацию достаточно производительного и гибкого HTTP-сервера, построенного на асинхронной технологии NIO.

С его использованием код самого простого HTTP-сервера умещается в 30 строк Java-кода:


import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class HttpServerEx implements HttpHandler {

	public static void main(String[] args) throws IOException {
		HttpServer server = HttpServer.create(new InetSocketAddress(80), 10);
		server.createContext("/", new HttpServerEx());
		server.start();
		System.out.println("Server started\nPress any key to stop...");
		System.in.read();
		server.stop(0);
		System.out.println("Server stoped");
	}

	@Override
	public void handle(HttpExchange exc) throws IOException {
		exc.sendResponseHeaders(200, 0);
		PrintWriter out = new PrintWriter(exc.getResponseBody());
		out.println( "Hello moto!" );
		out.close();
		exc.close();
	}

}

Теперь, думаю, никому не составит труда расширить метод handle() под свои нужды.

Более подробную документацию можно найти тут: Javadoc пакета “Java™ HTTP Server”

К сожалению исходный код пакета доступен только как часть Standard Edition Development Kit Source Release под Java Research License, что вынуждает немного “попотеть” чтоб его добыть.

P.S. За наводку спасибо Dmitriy Kopylenko и его ссылке на реализацию подобного HTTP-сервера на Scala.

Комментариев: 15

15 Responses to “Simple & Reliable Java HTTP-server”

Комментарии:

  1. Evgenij Nerush

    HTTP-сервер так же можно реализовать с помощью рестлетов http://www.restlet.org/documentation/1.0/firstSteps, (как вариант), очень советую!

  2. Vadim Voituk

    REST – не всегда является заменой HTTP, и есть всего лишь его подмножеством.
    Да и тянуть в проект 10-мегабайтный фреймворк для такой мелочи не всегда оправдано.

    Да и реализация конкретно этого фреймворка мне не очень нравится – IMHO через чур абстрактно.

  3. juriy

    Красота да и только. Легким взмахом руки добавить freemarker и можно наслаждаться простыми веб-мордочками для своего приложения.

    Интересно, почему sun жадничает и не выкладывает такие полезные куски в public API?

  4. Vadim Voituk

    Почему же жадничает?
    Вполне себе не жадничает – вон и JavaDoc открыт, и в JRE6 встроили.
    Исходя из того, что в пакете com.sun.net.httpserver находятся только интерфейсы и абстрактные классы, а реализация находится в non-public пакетах ветки sun.*, можно судить что это будет частью стандарта JRE.

  5. Swed

    :) а как сессию замутить?
    если готовая реализация что бы не приходилось самому разбирать кукисы и писать классы реализации???

  6. edolganov

    Спасибо за статью!
    Но возникла проблема с парсингом кириллических параметров в строке на Windows платформе.

    допустим есть запрос: /?test?=тест
    тогда код: URI requestURI = exc.getRequestURI();
    выдает ури вида: /?test=%F2%E5%F1%F2
    где %F2%E5%F1%F2 – декодируется корректно при URLDecoder.decode(pair[0], “CP1251″), но не при “UTF8″

    К сожалению, я пока не нашел решения, чтобы ури приходил вида: /?test=%D1%82%D0%B5%D1%81%D1%82, что корректно для
    URLDecoder.decode(pair[0], “UTF8″)

    Есть идеи где копать? =)

  7. Swed

    Кодировку страницы смотри
    Ajax по умолчанию всегда UTF8

  8. edolganov

    Я нашел причину. Сам браузер формирует такую строку:
    /?test=%F2%E5%F1%F2
    Accept-Charset=windows-1251,utf-8;q=0.7,*;q=0.7

  9. Swed

    Сам броузер никогда ничего ) не делает,
    иногда не хочет даже если его очень просить.
    ты сам выбираеш коридовку для страниц
    или это делает твой сервер по умолчанию

  10. edolganov

    Спасибо за ответы. Будем копаться дальше.)

  11. edolganov

    Причина была в том, что я делал локальный запрос с браузера.
    В этом случае на сервер приходило ури: /?test=%F2%E5%F1%F2
    Запрос с удаленного браузера выдал корректное ури: /?test=%D1%82%D0%B5%D1%81%D1%82

  12. Swed

    блин :) а какая разница )))
    поиграйся знаеш как
    в броузере меняй кодировку страницы и отправляй запрос
    если у страницы не выбрала кодировка
    броузер выставялет ее в зависимости от локали пользователя
    как то так )

  13. edolganov

    >> блин :) а какая разница )))

    а вот видимо есть разница. ибо написал результаты реального теста.
    возможно тут есть зависимость от ОС еще. У меня была Win7

  14. Swed

    от ОС нет :) а вот от Рантйма да )
    потому то Джава вроде одна но отличия есть

  15. Vetal

    Здравствуйте! Статья хорошая, но вот только вопрос об поддержке асинхронности, в доках я этого не нашел, да и нагуглить не удалось. Действительно ли есть такая возможность?

Leave a Reply