bizkhit
bizkhit

Reputation: 93

How can I include css file using com.sun.net.httpserver?

I'm trying to write a simple http server, using com.sun.net.httpserver class. I send html file (index.html) to browser on startup, but I don't know how to include an external css file. It works when css code is placed inside html file. I know, that browser should send a request, asking server for css file, but I'm not sure how to receive this request and send back this file to browser. I attach a fragment of my code below, if it could be helpful.

private void startServer()
{
    try
    {
        server = HttpServer.create(new InetSocketAddress(8000), 0);
    } 
    catch (IOException e) 
    {
        System.err.println("Exception in class : " + e.getMessage());
    }
    server.createContext("/", new indexHandler());
    server.setExecutor(null);
    server.start();
}

private static class indexHandler implements HttpHandler
{
    public void handle(HttpExchange httpExchange) throws IOException
    {   
        Headers header = httpExchange.getResponseHeaders();
        header.add("Content-Type", "text/html");
        sendIndexFile(httpExchange);            
    }
}

static private void sendIndexFile(HttpExchange httpExchange) throws IOException
{
    File indexFile = new File(getIndexFilePath());
    byte [] indexFileByteArray = new byte[(int)indexFile.length()];

    BufferedInputStream requestStream = new BufferedInputStream(new FileInputStream(indexFile));
    requestStream.read(indexFileByteArray, 0, indexFileByteArray.length);

    httpExchange.sendResponseHeaders(200, indexFile.length());
    OutputStream responseStream = httpExchange.getResponseBody();
    responseStream.write(indexFileByteArray, 0, indexFileByteArray.length);
    responseStream.close();
}

Upvotes: 2

Views: 3569

Answers (1)

There is no built-in method for handling static content. You have two options.

Either use a light-weight webserver for static content like nginx, but than distribution of your application will be more difficult.

Or create your own file serving classes. For that, you have to create a new context in your web server:

int port = 8080;
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
// ... more server contexts
server.createContext("/static", new StaticFileServer());

And than create the class that will serve your static files.

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

@SuppressWarnings("restriction")
public class StaticFileServer implements HttpHandler {

    @Override
    public void handle(HttpExchange exchange) throws IOException {
        String fileId = exchange.getRequestURI().getPath();
        File file = getFile(fileId);
        if (file == null) {
            String response = "Error 404 File not found.";
            exchange.sendResponseHeaders(404, response.length());
            OutputStream output = exchange.getResponseBody();
            output.write(response.getBytes());
            output.flush();
            output.close();
        } else {
            exchange.sendResponseHeaders(200, 0);
            OutputStream output = exchange.getResponseBody();
            FileInputStream fs = new FileInputStream(file);
            final byte[] buffer = new byte[0x10000];
            int count = 0;
            while ((count = fs.read(buffer)) >= 0) {
                output.write(buffer, 0, count);
            }
            output.flush();
            output.close();
            fs.close();
        }
    }

    private File getFile(String fileId) {
        // TODO retrieve the file associated with the id
        return null;
    }
}

For the method getFile(String fileId); you can implement any way of retrieving the file associated with the fileId. A good option is to create a file structure mirroring the URL hierarchy. If you don't have many files, than you can use a HashMap to store valid id-file pairs.

Upvotes: 3

Related Questions