Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Is there a way to create a very basic HTTP server (supporting only GET/POST) in Java using just the Java SE API, without writing code to manually parse HTTP requests and manually format HTTP responses? The Java SE API nicely encapsulates the HTTP client functionality in HttpURLConnection, but is there an analog for HTTP server functionality?

Just to be clear, the problem I have with a lot of ServerSocket examples I've seen online is that they do their own request parsing/response formatting and error handling, which is tedious, error-prone, and not likely to be comprehensive, and I'm trying to avoid it for those reasons.

As an example of the manual HTTP manipulation that I'm trying to avoid:

http://java.sun.com/developer/technicalArticles/Networking/Webserver/WebServercode.html

share|improve this question
Umm...the short answer is no. If you want something that handles post and get requests without manually writing the http headers then you could use servlets. But thats java ee. If you don't want to use something like that then sockets and manual parsing is the only other option I know of. – Matt Phillips Sep 17 '10 at 1:32
I know this isn't in the spirit of SO, but I would urge you to reconsider you distaste for Java EE API's. As some of the answers have mentioned, there are some very straight-forward implementations such as Jetty that allow you to embed a web server in your stand-alone application while still taking advantage of the servlet api. If you absolutely can't use the Java EE API for some reason than please disregard my comment :-) – Chris Thompson Sep 17 '10 at 3:05

8 Answers

Since Java 1.6, there's a builtin HTTP server in Sun Oracle JDK (note: JDK, not JRE). The com.sun.net.httpserver package summary outlines the involved classes and contains examples.

Here's a (basic) kickoff example based on the docs, you can just copy'n'paste'n'run it on Java 1.6

package com.example;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

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

public class Test {

    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.createContext("/test", new MyHandler());
        server.setExecutor(null); // creates a default executor
        server.start();
    }

    static class MyHandler implements HttpHandler {
        public void handle(HttpExchange t) throws IOException {
            String response = "This is the response";
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }

}

Execute it and go to http://localhost:8000/test and you'll see the following response:

This is the response

Note that this is, in contrary to what some naive developers think, absolutely not forbidden by the well known FAQ Why Developers Should Not Write Programs That Call 'sun' Packages. That FAQ concerns the sun.* package (such as sun.misc.BASE64Encoder) for internal usage by the Oracle JRE, not the com.sun.* package. Sun/Oracle also just develops software on top of the Java SE API themselves like as every other company such as Apache and so on.

share|improve this answer
2  
Absolutely a -1 vote - do not use non-public unpublished classes from Sun/Oracle. – Software Monkey Sep 17 '10 at 4:42
2  
@Software Monkey - why not? It seems to satisfy asker's requirements. – emory Sep 17 '10 at 8:08
7  
@Software: it's not. Even more, it's documented. – BalusC Sep 17 '10 at 11:07
It's from com.sun, so it's not part of Java but part of the Sun JVM. You can't count on them being available. Maybe they're renamed to com.oracle next week? – Waldheinz Jan 10 '11 at 8:46
5  
@Waldheinz: like as @Software you're confusing sun.* with com.sun.*. For instance, do you see any documentation of sun.* API? Look here: java.sun.com/products/jdk/faq/faq-sun-packages.html Does it tell anything about com.sun.*? The com.sun.* is just used for their own public software which is not part of Java API. They also develop software on top of Java API, like as every other company. – BalusC Jan 10 '11 at 10:37
show 5 more comments

Check out NanoHttpd

share|improve this answer
2  
One caution: It's likely that NanoHTTPD does not have protection against tree-walking attacks - you should check this if it will be serving on a public address. By this I mean attacks where a request like GET /../../blahblah http/1.1 is issued and the server walks above the website root and into system file land, serving files that can be used to compromise or remotely attack the system, like a password file. – Software Monkey Sep 17 '10 at 4:51
That seems to be fixed. The current version generates a 403 if ( uri.startsWith( ".." ) || uri.endsWith( ".." ) || uri.indexOf( "../" ) >= 0 ). – Lena Schimmel May 4 '12 at 9:23

Have a look at the "Jetty" web server Jetty. Superb piece of Open Source software that would seem to meet all your requirments.

If you insist on rolling your own then have a look at the "httpMessage" class.

share|improve this answer
I think jetty api depends on servlet. – irreputable Sep 17 '10 at 3:00
1  
@Irreputable: No, Jetty is a highly modular web server, which has a servlet container as one of it's optional modules. – Software Monkey Sep 17 '10 at 4:43
"is ther an analog for server functionality" -- yes its the "servlet" API. The servlet container calls your class after it has parsed the headers, cookies etc. – James Anderson Sep 17 '10 at 8:06
Software Monkey: you can't use it without servlet api. as long as we are using the silly notions of java se/ee, jetty is not se. – irreputable Sep 17 '10 at 14:51

You may also have a look at some NIO application framework such as:

  1. Netty: http://jboss.org/netty
  2. Apache Mina: http://mina.apache.org/ or its subproject AsyncWeb: http://mina.apache.org/asyncweb/
share|improve this answer

I can strongly recommend looking into Simple, especially if you don't need Servlet capabilities but simply access to the request/reponse objects. If you need REST you can put Jersey on top of it, if you need to output HTML or similar there's Freemarker. I really love what you can do with this combination, and there is relatively little API to learn.

share|improve this answer

This code is better than ours, you only need to add 2 libs: javax.servelet.jar and org.mortbay.jetty.jar.

Class Jetty:

package jetty;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.mortbay.http.SocketListener;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHttpContext;

public class Jetty {

    public static void main(String[] args) {
        try {
            Server server = new Server();
            SocketListener listener = new SocketListener();      

            System.out.println("Max Thread :" + listener.getMaxThreads() + " Min Thread :" + listener.getMinThreads());

            listener.setHost("localhost");
            listener.setPort(8070);
            listener.setMinThreads(5);
            listener.setMaxThreads(250);
            server.addListener(listener);            

            ServletHttpContext context = (ServletHttpContext) server.getContext("/");
            context.addServlet("/MO", "jetty.HelloWorldServlet");

            server.start();
            server.join();

        /*//We will create our server running at http://localhost:8070
        Server server = new Server();
        server.addListener(":8070");

        //We will deploy our servlet to the server at the path '/'
        //it will be available at http://localhost:8070
        ServletHttpContext context = (ServletHttpContext) server.getContext("/");
        context.addServlet("/MO", "jetty.HelloWorldServlet");

        server.start();
        */

        } catch (Exception ex) {
            Logger.getLogger(Jetty.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
} 

Servlet class:

package jetty;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloWorldServlet extends HttpServlet
{
    @Override
    protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException
    {
        String appid = httpServletRequest.getParameter("appid");
        String conta = httpServletRequest.getParameter("conta");

        System.out.println("Appid : "+appid);
        System.out.println("Conta : "+conta);

        httpServletResponse.setContentType("text/plain");
        PrintWriter out = httpServletResponse.getWriter();
        out.println("Hello World!");
        out.close();
    }
}
share|improve this answer
2  
The question asks for a purely Java SE solution. You'll find that jetty implements the Java EE API. – sridhara Sep 17 '12 at 15:58

How about Apache Commons HttpCore project?

From the web site:... HttpCore Goals

  • Implementation of the most fundamental HTTP transport aspects
  • Balance between good performance and the clarity & expressiveness of API
  • Small (predictable) memory footprint
  • Self contained library (no external dependencies beyond JRE)
share|improve this answer

it's possible, because there are so many http servers written in pure java.

question is, how come there is no well-known, simple http server in java. (jetty is not simple enough). that's a good question. I'm sure if you google "simple java http server" there's a ton of simple implementations. but there isn't a "famous" one. maybe java people mostly do web apps and they've already got a non-simple http server.

a simple yet powerful http server can be implemented under 1000 lines of java.

share|improve this answer
4  
This answer isn't helpful. – Michael Brewer-Davis Sep 17 '10 at 4:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.