Grizzly 2.0: HttpServer API. Implementing simple HTTP server

HttpServer API is Grizzly 2.0 replacement of GrizzlyWebServer API described here by Jeanfrancois.

HttpServer inherits all the GrizlyWebServer features and additionally introduces new NIO Streams API, which lets you make all you reads and writes non-blocking.

But let's start from the basics.

HttpServer API is pretty similar to Servlet API, so everyone who worked with Servlets will easily map basic HttpServer API abstractions to correspondent Servlet API abstractions. Here they are:

 HttpServer This is the Grizzly HTTP server which can be used to create standalong HTTP programs or embed Grizzly within other application to provide HTTP services
 NetworkListener
This is an abstraction of the Grizzly NIOTransport and Filter implementations. It also allows the enabling/disabling of HTTP-related features such as keep-alive, chunked transfer-encoding, cusom addons etc. HttpServer can support multiple NetworkListeners. Also, keep in mind that all HttpHandlers added to the ServerConfiguration will be shared across all listeners
 HttpHandler HttpHandler is akin to javax.servlet.Servlet
 Request  Request is similar to javax.servlet.http.HttpServletRequest
 Response Request is similar to javax.servlet.http.HttpServletResponse
 Session Session is similar to javax.servlet.http.HttpSession
 ServerConfiguration This class allows developer to add custom HttpHandler implementations to the server as well as exposing JMX/monitoring features
 AddOn The general interface for HttpServer addons, which suppose to extend basic HttpServer functionality


1. Serving Static Resources.

Ok, now we're ready to implement and start simplest HTTP server, which will serve static resources in the current folder on all available network interfaces (0.0.0.0) and default TCP port 8080.


-----------------------------------------------
HttpServer server = HttpServer.createSimpleServer();
try {
    server.start();
    System.out.println("Press any key to stop the server...");
    System.in.read();
} catch (Exception e) {
    System.err.println(e);
}
-----------------------------------------------

After running the code above, the files in the current folder could be retrieved using URL: http://localhost:8080/<filename>.

If we want to customize our HTTP server to serve static resources in the folder "/home/myhome/downloads" on localhost interface only, port 18888 with context-root "/xyz" - the code has to be changed:


-----------------------------------------------
HttpServer httpServer = new HttpServer();
        
NetworkListener networkListener = new NetworkListener("sample-listener", "localhost", 18888);
httpServer.addListener(networkListener);
        
httpServer.getServerConfiguration().addHttpHandler(new StaticHttpHandler("/home/myhome/downloads"),
    "/xyz");
        
try {
    server.start();
    System.out.println("Press any key to stop the server...");
    System.in.read();
} catch (Exception e) {
    System.err.println(e);
}
-----------------------------------------------

A bit more work isn't it? ;) Now the files located in the "/home/myhome/downloads" folder could be retrieved using URL: http://localhost:18888/xyz/<filename>.


2. Serving Dynamic Resources.

Ok, what if we want to serve dynamic resources, in other words generate response at runtime?

That's easy, instead of using StaticHttpHandler (sample above), we're going to create a custom HttpHandler, which API and features are pretty similar to javax.servlet.Servlet.  Let's implement HttpHandler, which returns current server time in format HH:mm:ss.


-----------------------------------------------
HttpServer httpServer = new HttpServer();
        
NetworkListener networkListener = new NetworkListener("sample-listener", "localhost", 18888);
httpServer.addListener(networkListener);
        
httpServer.getServerConfiguration().addHttpHandler(new HttpHandler() {
    final SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
            
    @Override
    public void service(Request request, Response response) throws Exception {
        final Date now = new Date();
        final String formattedTime;
        synchronized (formatter) {
            formattedTime = formatter.format(now);
        }
                
        response.setContentType("text/plain");
        response.getWriter().write(formattedTime);
    }
}, "/time");

try {
    server.start();
    System.out.println("Press any key to stop the server...");
    System.in.read();
} catch (Exception e) {
    System.err.println(e);
}
-----------------------------------------------

Looks familiar? :) You can test the implementation using URL: http://localhost:18888/time .

Indeed, Grizzly HttpServer API is similar to Servlets, having similar API and features. In the next blog I'll describe how to process HTTP requests asynchronously, which is particularly useful if you deal with a long lasting tasks, to not block the execution of other HTTP request coming at the same time.

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

oleksiys

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today