I was in need of a tiny web server for one of my projects, and I found out that Java 1.6 actually comes with one!
While I have no idea how well this server performs, it’s perfect for what I was looking for, as my intention is to use it just for one user. First I decided to implement a simple file server, and over it I want to define some custom URLs with special handling. So, now that this part is finished, I think it does make a good base for future projects… so in case you need it, here you’ve it:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.File;
import java.net.InetSocketAddress;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class FileHandler implements HttpHandler {
FileNameMap fileNameMap = URLConnection.getFileNameMap();
public static void main(String[] args) throws IOException {
int serverPort = 8080;
InetSocketAddress addr = new InetSocketAddress(serverPort);
HttpServer server = HttpServer.create(addr, 0);
server.createContext("/", new FileHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
System.out.println("Server is listening on port " + serverPort);
}
public void handle(HttpExchange exchange) throws IOException {
String requestMethod = exchange.getRequestMethod();
String targetPath = exchange.getRequestURI().getPath();
if (requestMethod.equalsIgnoreCase("GET")) {
// Here it's a good place to include custom path handling,
// like calls to Java functions
// Handle paths trying to open index.html
// Instead of this, we could show a list of the files in the folder
if (targetPath.endsWith("/")) {
targetPath += "index.html";
}
// Check if file exists
File fileFolder = new File(".", "htdocs");
File targetFile = new File(fileFolder, targetPath.replace('/', File.separatorChar));
if (targetFile.exists() && targetFile.isFile()) {
// If it exists and it's a file, serve it
int bufLen = 10000*1024;
byte[] buf = new byte[bufLen];
int len = 0;
Headers responseHeaders = exchange.getResponseHeaders();
// Get mime type from the ones defined in [jre_home]/lib/content-types.properties
String mimeType = fileNameMap.getContentTypeFor(targetFile.toURI().toURL().toString());
if (mimeType == null) {
mimeType = "application/octet-stream";
}
responseHeaders.set("Content-Type", mimeType);
exchange.sendResponseHeaders(200, targetFile.length());
FileInputStream fileIn = new FileInputStream(targetFile);
OutputStream out = exchange.getResponseBody();
while ((len = fileIn.read(buf,0,bufLen)) != -1) {
out.write(buf, 0, len);
}
out.close();
fileIn.close();
} else {
// If it doesn't exist, send error
String message = "404 Not Found " + exchange.getRequestURI();
exchange.sendResponseHeaders(404, 0);
OutputStream out = exchange.getResponseBody();
out.write(message.getBytes());
out.close();
}
}
}
}
It’s very basic, but it has default index, 404 errors and MIME type autodetection.