- Простой HTTP-сервер на Java
- HTTPServer
- Очередь выполнения запросов
- Код сервера
- HTTPHandler
- «). append(«Hello «) .append(requestParamValue) .append(«
- One of the most frequency used protocol in the whole Internet *
- What a web browser sends to the web server?
- Wireshark, my old friend
- You are right — the specification
- Just run the server and test
- HTTP request
- The trap
- Response
Простой HTTP-сервер на Java
Вы хотите реализовать HTTP-сервер , но не хотите рисковать написанием полноценного HTTP-сервера? Разработка HTTP-сервера с полной функциональностью не является тривиальной задачей. Но у Java есть решение этой проблемы. Java поддерживает встроенный HTTP-сервер. Просто написав 100 строк кода, мы можем разработать несколько приличный HTTP-сервер, который может обрабатывать запросы. Мы также можем использовать его для обработки других HTTP-команд.
HTTPServer
Java SDK предоставляет встроенный сервер под названием HttpServer . Этот класс относится к пакету com.sun.net .
Мы можем создать экземпляр сервера следующим образом:
HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 8001), 0);
Приведенная выше строка создает экземпляр HTTPServer на локальном узле с номером порта 8001. Но есть еще один аргумент со значением 0. Это значение используется для обратной регистрации .
Очередь выполнения запросов
Когда сервер принимает запрос клиента, этот запрос сначала будет поставлен в очередь операционной системой. Позже он будет передан на сервер для обработки запроса. Все эти одновременные запросы будут поставлены в очередь операционной системой. Однако операционная система сама решит, сколько из этих запросов может быть поставлено в очередь в любой данный момент времени. Это значение представляет обратную регистрацию. В нашем примере это значение равно 0, что означает, что мы не ставим в очередь никаких запросов.
Код сервера
Мы собираемся разработать следующий HTTP-сервер:
server.createContext("/test", new MyHttpHandler()); server.setExecutor(threadPoolExecutor); server.start(); logger.info(" Server started on port 8001");
Мы создали контекст под названием test . Это не что иное, как корень контекста приложения. Второй параметр — это экземпляр обработчика, который будет обрабатывать HTTP-запросы. Мы рассмотрим этот класс в ближайшее время.
Мы можем использовать исполнителя пула потоков вместе с этим экземпляром сервера. В нашем случае мы создали пул из 10 потоков.
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor)Executors.newFixedThreadPool(10);
С помощью всего трех-четырех строк кода мы создали HTTP-сервер с корневым контекстом, который прослушивает порт!
HTTPHandler
Это интерфейс с вызванным методом handle(..) . Давайте посмотрим на нашу реализацию этого интерфейса.
«). append(«Hello «) .append(requestParamValue) .append(«
One of the most frequency used protocol in the whole Internet *
* In OSI model, layer 7 Every time you visit a website your web browser uses the HTTP protocol to communicate with web server and fetch the page’s content. Also, when you are implementing backend app and you have to communicate with other backend app — 80% (or more) of cases you will use the HTTP. Long story short — when you want to be a good software developer, you have to know how the HTTP protocol works. And wiring the HTTP server is pretty good way to understood, I think.
What a web browser sends to the web server?
Good question. Of course, you can use «developer tools», let’s do it. Hmm. but what now? What exactly it means? We can see some URL, some method, some status, version (huh?), headers, and other stuff. Useful? Yes, but only to analyze the web app, when something is wrong. We still don’t know how HTTP works.
Wireshark, my old friend
The source of truth. Wireshark is application to analyze network traffic. You can use it to see each packet that is sent by your (or to your) PC. But to be honest — if you know how to use Wireshark — you probably know how HTTP and TCP works. It’s pretty advanced program.
You are right — the specification
Every good (I mean — used by more that 5 peoples) protocols should have specification. In this case it’s called RFC. But don’t lie — you will never read this, it’s too long — https://tools.ietf.org/html/rfc2616 .
Just run the server and test
Joke? No. Probably you have installed on your PC very powerful tool called netcat, it’s pretty advanced tool.
One of the netcat features is TCP server. You can run the netcat to listen on specific port and print every thing what it gets. Netcat is a command line app.
Netcat (nc), please, listen (-l) on port 8080 (-p 8080) and print everything (-v). Now open web browser and enter http://localhost:8080/ . Your browser will send the HTTP request to the server runned by netcat. Of course nc will print the whole request and ignore it, browser will wait for the response (will timeout soon). To kill nc press ctrl+c . So, finally, we have an HTTP request!
GET / HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:74.0) Gecko/20100101 Firefox/74.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Cookie: JSESSIONID=D3AF43EBFC0C9D92AD9C37823C4BB299 Upgrade-Insecure-Requests: 1
HTTP request
It may be a little confusing. Maybe nc parses the request before printing? HTTP protocol should be complicated, where is the sequence of 0 and 1? There aren’t any. HTTP is really very simple text protocol. There is only one, little trap (I will explain it at the end of this section). We can split the request to the 4 main parts:
This is the main request. GET — this is the HTTP method. Probably you know there are a lot of methods.
GET means give me / — resource. / means default one.
When you will open localhost:8080/my_gf_nudes.html , the resource will be /my_gf_nudes.html HTTP/1.1 — HTTP version. There are few versions, 1.1 is commonly used.
Host. One server can host many domains, using this field, the browser says which domain it wants exactly
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:74.0) Gecko/20100101 Firefox/74.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Cookie: JSESSIONID=D3AF43EBFC0C9D92AD9C37823C4BB299 Upgrade-Insecure-Requests: 1
Surprise — empty line. It means: end of the request. In general — empty line in HTTP means end of section.
The trap
Response
Ok. We have a request. How does response look like? Send a request to any server and see, there is nothing simpler.
On your laptop you can find another very useful tool — telnet . Using telenet you can open TCP connection, write something to server and print the response.
Try to do it yourself. Run telnet google.com 80 (80 is the default HTTP port) and type request manually (you know how it should look like). To close connection press ctrl+] than type quit . OK. We have a response.
HTTP/1.1 301 Moved Permanently
HTTP/1.1 — version
301 — status code. I believe you are familiar with that
Moved Permanently — human-readable status code
Location: http://www.google.com/ Content-Type: text/html; charset=UTF-8 Date: Wed, 25 Mar 2020 18:53:12 GMT Expires: Fri, 24 Apr 2020 18:53:12 GMT Cache-Control: public, max-age=2592000 Server: gws Content-Length: 219 X-XSS-Protection: 0 X-Frame-Options: SAMEORIGIN