Java 原生实现简单 http server

619 阅读2分钟

Java原生内置库用于 http server 编程主要是基于 HttpServer 类、Handler接口实现类及HttpExchange类实现,用 HttpServer 调用 Handler 的实现类,通过 HttpExchange 接收请求信息,并处理返回信息。

以下是主要用到的相关类的信息:

  • 1.HttpServer:表示一个服务器实例,需要绑定一个IP地址和端口号。(HttpsServer是其子类,处理https请求)
  • 2.HttpContext:服务器监听器的上下文,需要配置用于匹配URI的公共路径和用来处理请求的HttpHandler (可以创建多个 HttpContext,一个 HttpContext 对应一个 HttpHandler,不同的 URI 请求,根据添加的 HttpContext 监听器,分配到对应的 HttpHandler 处理请求)
  • 3.HttpHandler:上下文对应的http请求处理器
  • 4.HttpExchange:监听器回调时传入的参数,封装了http请求和响应的所有数据操作

以下是 http server 的相关实现:

server主程序

package org.example;

import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SimpleHttpServer {
    private static final int port = 8080;

    private static final String HttpContext = "/demo";

    private static final int nThreads = 8;

    public static void main(String[] args) {
        HttpServer httpserver;

        try {
            httpserver = HttpServer.create(new InetSocketAddress(port), 0);
            httpserver.createContext(HttpContext, new SimpleHttpHandlerDemo());
            // set concurrent num
            ExecutorService exec = Executors.newFixedThreadPool(nThreads);
            httpserver.setExecutor(exec);
            httpserver.start();
            System.out.println("启动端口:"+port);
            System.out.println("根节点:"+HttpContext);
            System.out.println("并发数:"+nThreads);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

handler

package org.example;

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

import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URI;

public class SimpleHttpHandlerDemo implements HttpHandler {
    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        // request address
        InetSocketAddress inetSocketAddress = httpExchange.getRemoteAddress();
        System.out.println("请求ip地址:"+inetSocketAddress);
        System.out.println("请求host:"+inetSocketAddress.getHostName());
        System.out.println("请求port:"+inetSocketAddress.getPort());
        // request method
        String requestMethod = httpExchange.getRequestMethod();
        System.out.println("请求方式:"+httpExchange.getRequestMethod());
        // url
        URI url = httpExchange.getRequestURI();
        System.out.println("url:"+url);

        // handle get request
        if (requestMethod.equalsIgnoreCase("GET")) {
            // set server end's code format
            Headers respHeaders = httpExchange.getResponseHeaders();
            respHeaders.set("Content-Type", "text/html;charset=utf-8");
            // get req body from httpExchange
            InputStream reqBody = httpExchange.getRequestBody();

            String resp = "This is Server.";

            httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, resp.getBytes("UTF-8").length);
            // send resp
            OutputStream respBody = httpExchange.getResponseBody();
            OutputStreamWriter wr = new OutputStreamWriter(respBody, "UTF-8");
            wr.write(resp);
            wr.close();
            respBody.close();
        } else {
            InputStream inputStream = httpExchange.getRequestBody();
            ByteArrayOutputStream bas = new ByteArrayOutputStream();

            int i;
            while ((i = inputStream.read()) != -1) {
                bas.write(i);
            }

            String reqMsg = bas.toString();
            System.out.println("请求报文:" + reqMsg);

            // return response
            String respMsg = "恭喜你成功了";
            httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, respMsg.getBytes("UTF-8").length);
            OutputStream outputStream = httpExchange.getResponseBody();
            outputStream.write(respMsg.getBytes("UTF-8"));
            outputStream.close();
            System.out.println("通信结束");
        }
    }
}

参考: