是否有一种方法可以使用Java SE API在Java中创建一个非常基本的HTTP服务器(只支持GET/POST),而不需要编写代码手动解析HTTP请求和手动格式化HTTP响应?Java SE API在HttpURLConnection中很好地封装了HTTP客户机功能,但是是否有类似的HTTP服务器功能呢?

需要明确的是,我在网上看到的许多ServerSocket示例的问题是,它们自己进行请求解析/响应格式化和错误处理,这很乏味,容易出错,而且不太全面,出于这些原因,我试图避免使用它。


当前回答

看看“Jetty”web服务器Jetty。一流的开源软件,似乎可以满足您的所有要求。

如果你坚持要创建自己的类,那么可以看看“httpMessage”类。

其他回答

httpserver解决方案不能跨jre移植。最好使用javax.xml.ws中的官方webservices API来引导一个最小的HTTP服务器…

import java.io._
import javax.xml.ws._
import javax.xml.ws.http._
import javax.xml.transform._
import javax.xml.transform.stream._

@WebServiceProvider
@ServiceMode(value=Service.Mode.PAYLOAD) 
class P extends Provider[Source] {
  def invoke(source: Source) = new StreamSource( new StringReader("<p>Hello There!</p>"));
}

val address = "http://127.0.0.1:8080/"
Endpoint.create(HTTPBinding.HTTP_BINDING, new P()).publish(address)

println("Service running at "+address)
println("Type [CTRL]+[C] to quit!")

Thread.sleep(Long.MaxValue)

编辑:这实际上是工作!上面的代码看起来像Groovy之类的。以下是我测试的Java翻译:

import java.io.*;
import javax.xml.ws.*;
import javax.xml.ws.http.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

@WebServiceProvider
@ServiceMode(value = Service.Mode.PAYLOAD)
public class Server implements Provider<Source> {

    public Source invoke(Source request) {
        return  new StreamSource(new StringReader("<p>Hello There!</p>"));
    }

    public static void main(String[] args) throws InterruptedException {

        String address = "http://127.0.0.1:8080/";
        Endpoint.create(HTTPBinding.HTTP_BINDING, new Server()).publish(address);

        System.out.println("Service running at " + address);
        System.out.println("Type [CTRL]+[C] to quit!");

        Thread.sleep(Long.MAX_VALUE);
    }
}

以上所有的回答关于单主线程请求处理器的细节。

设置:

 server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());

允许多个请求服务通过多个线程使用执行器服务。

因此,结束代码将如下所示:

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 App {
    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.createContext("/test", new MyHandler());
        //Thread control is given to executor service.
        server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
        server.start();
    }
    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            String response = "This is the response";
            long threadId = Thread.currentThread().getId();
            System.out.println("I am thread " + threadId );
            response = response + "Thread Id = "+threadId;
            t.sendResponseHeaders(200, response.length());
            OutputStream os = t.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }
}

您可以编写一个非常简单的嵌入式Jetty Java服务器。

嵌入式Jetty意味着服务器(Jetty)与应用程序一起发布,而不是将应用程序部署在外部Jetty服务器上。

因此,如果在非嵌入式方法中,你的webapp内置到WAR文件中,并部署到一些外部服务器(Tomcat / Jetty / etc),在嵌入式Jetty中,你在相同的代码库中编写webapp并实例化Jetty服务器。

一个嵌入式Jetty Java服务器的例子,你可以git克隆和使用:https://github.com/stas-slu/embedded-jetty-java-server-example

Apache Commons HttpCore项目怎么样?

来自网站:…… HttpCore目标

实现最基本的HTTP传输方面 良好的表现和清晰的表达之间的平衡 API 小(可预测的)内存占用 自包含库(没有JRE以外的外部依赖)

我强烈建议考虑Simple,特别是如果您不需要Servlet功能,而只是访问请求/响应对象。如果你需要REST,你可以把Jersey放在上面,如果你需要输出HTML或类似的东西,有Freemarker。我真的很喜欢使用这个组合可以做的事情,而且需要学习的API相对较少。