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.
Tweet
HTTP-сервер так же можно реализовать с помощью рестлетов http://www.restlet.org/documentation/1.0/firstSteps, (как вариант), очень советую!
REST – не всегда является заменой HTTP, и есть всего лишь его подмножеством.
Да и тянуть в проект 10-мегабайтный фреймворк для такой мелочи не всегда оправдано.
Да и реализация конкретно этого фреймворка мне не очень нравится – IMHO через чур абстрактно.
Красота да и только. Легким взмахом руки добавить freemarker и можно наслаждаться простыми веб-мордочками для своего приложения.
Интересно, почему sun жадничает и не выкладывает такие полезные куски в public API?
Почему же жадничает?
Вполне себе не жадничает – вон и JavaDoc открыт, и в JRE6 встроили.
Исходя из того, что в пакете com.sun.net.httpserver находятся только интерфейсы и абстрактные классы, а реализация находится в non-public пакетах ветки sun.*, можно судить что это будет частью стандарта JRE.
:) а как сессию замутить?
если готовая реализация что бы не приходилось самому разбирать кукисы и писать классы реализации???
Спасибо за статью!
Но возникла проблема с парсингом кириллических параметров в строке на 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″)
Есть идеи где копать? =)
Кодировку страницы смотри
Ajax по умолчанию всегда UTF8
Я нашел причину. Сам браузер формирует такую строку:
/?test=%F2%E5%F1%F2
Accept-Charset=windows-1251,utf-8;q=0.7,*;q=0.7
Сам броузер никогда ничего ) не делает,
иногда не хочет даже если его очень просить.
ты сам выбираеш коридовку для страниц
или это делает твой сервер по умолчанию
Спасибо за ответы. Будем копаться дальше.)
Причина была в том, что я делал локальный запрос с браузера.
В этом случае на сервер приходило ури: /?test=%F2%E5%F1%F2
Запрос с удаленного браузера выдал корректное ури: /?test=%D1%82%D0%B5%D1%81%D1%82
блин :) а какая разница )))
поиграйся знаеш как
в броузере меняй кодировку страницы и отправляй запрос
если у страницы не выбрала кодировка
броузер выставялет ее в зависимости от локали пользователя
как то так )
>> блин :) а какая разница )))
а вот видимо есть разница. ибо написал результаты реального теста.
возможно тут есть зависимость от ОС еще. У меня была Win7
от ОС нет :) а вот от Рантйма да )
потому то Джава вроде одна но отличия есть