Java: Run HTTP server on demand from my app?
Question
I want to write a simple P2P test app which uses HTTP as
underlying protocol.
The app has to decide on demand, if it should
act as a HTTP server, or as a HTTP client.
The classic way which I am aware of, would be to deploy the app on some existing HTTP server. But this is the wrong way for my intention. It has to be the other way: the server is started by the app (and only if it decides to).
Is there a way to execute the HTTP server part on demand (without deploying the app itself on a server)?
Can I do it by linking Glassfish or Tomcat libraries and call some "main" method?
Edit: IT WORKS!!!
I now tried Jetty along with JAX-RS (Jersey) successfully!
Thank you all.
(the REST class is trivial and left out)
package my.p2p;
import com.sun.jersey.spi.container.servlet.*;
import org.mortbay.jetty.*;
import org.mortbay.jetty.servlet.*;
public class Main {
public static void main(String[] args)
throws Exception {
ServletHolder holder = new ServletHolder(ServletContainer.class);
holder.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
"com.sun.jersey.api.core.PackagesResourceConfig");
holder.setInitParameter("com.sun.jersey.config.property.packages", "my.p2p.rest");
Server server = new Server(8000);
Context context = new Context(server, "/", Context.SESSIONS);
context.addServlet(holder, "/*");
server.start();
}
}
Solution
You may use Jetty or some other embeddable HTTP server. From Jetty's web site:
Jetty is an open-source project providing a HTTP server, HTTP client and javax.servlet container. These 100% java components are full-featured, standards based, small foot print, embeddable, asynchronous and enterprise scalable. Jetty is dual licensed under the Apache License 2.0 and/or Eclipse Public License 1.0. Jetty is free for commercial use and distribution under the terms of either of those licenses.
OTHER TIPS
Beside the other answers there also is NanoHTTPD. Its very tiny, in just one class and maybe the right thing if yout don't need more or just want to keep things minimal.
take a look at the restlet project. They provides an embeddable, standalone server, and a client, both using the same Java API (the famous Uniform Interface).
Glassfish, Tomcat or servlet API seems to be a little overkill to me. My 0.02$ :)
EDIT
Client
Client client = new Client(Protocol.HTTP);
client.get("http://127.0.0.1").getEntity().write(System.out);
Server
Restlet sayHello = new Restlet() {
@Override
public void handle(Request request, Response response) {
response.setEntity("Hello World!", MediaType.TEXT_PLAIN);
}
};
new Server(Protocol.HTTP, 80, sayHello).start();
Java 6 includes a built in web server. You can use it like so:
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/", new HttpHandler() {
@Override
public void handle(HttpExchange xchange) throws IOException {
String response = "This is the response";
xchange.sendResponseHeaders(200, response.length());
OutputStream os = xchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
});
server.setExecutor(null);
server.start();
And then access http://localhost:8000 to see your response.
There are more examples in the JavaDoc for the HttpServer package
If you can't guarantee Java 6, take a look at embedding Jetty 6 which is easy and fairly lightwight, i.e. you don't need a whole webapp.