HttpServer-HTTP服务器

JavaSE(JDK6)内置了一个十分轻量级的HttpServer类,它提供了类似ServletAPI的接口但不需要Tomcat,能够实现读取HTTP请求、写入HTTP响应,一些简单不需要考虑性能的HTTP服务可以直接用它来实现。

使用HttpServer创建服务

下面是使用HttpServer编写一个服务的例子。

DemoHttpHandler.java

package com.gacfox.demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class DemoHttpHandler implements HttpHandler {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        OutputStream os = null;
        try {
            // 打印请求信息
            log.info("Request method: {}", httpExchange.getRequestMethod());
            log.info("Request uri: {}", httpExchange.getRequestURI().toString());
            log.info("Request headers:");
            Headers headers = httpExchange.getRequestHeaders();
            for (String key : headers.keySet()) {
                List<String> values = headers.get(key);
                for (String value : values) {
                    log.info("{}: {}", key, value);
                }
            }

            // 生成响应数据
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("code", 0);
            resultMap.put("msg", "成功");
            String resultJson = objectMapper.writeValueAsString(resultMap);
            byte[] resultBytes = resultJson.getBytes(StandardCharsets.UTF_8);

            // 返回响应
            Headers responseHeaders = httpExchange.getResponseHeaders();
            // 设置响应头
            responseHeaders.add("Content-Type", "application/json;charset=UTF-8");
            // 设置响应码和响应体大小
            httpExchange.sendResponseHeaders(200, resultBytes.length);
            // 写入响应体
            os = httpExchange.getResponseBody();
            os.write(resultBytes);
        } catch (IOException e) {
            log.error("请求处理出错:", e);
        } finally {
            if (os != null) {
                os.close();
            }
        }
    }
}

Main.java

package com.gacfox.demo;

import com.sun.net.httpserver.HttpServer;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.InetSocketAddress;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class Main {
    public static void main(String[] args) throws IOException {
        // 创建服务器对象
        HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 8080), 0);
        // 注册请求处理器
        server.createContext("/", new DemoHttpHandler());
        // 创建线程池
        server.setExecutor(new ThreadPoolExecutor(
                200,
                200,
                60L, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(100),
                Executors.defaultThreadFactory()
        ));
        // 启动服务
        server.start();
    }
}

代码十分简单,DemoHttpHandler类中我们编写了读取HTTP请求信息和返回HTTP响应的代码;Main类中,我们注册了DemoHttpHandler,此外还为其配置了一个线程池。启动服务后,我们可以使用浏览器访问http://localhost:8080观察响应输出。这里如果没有配置线程池,默认是单线程处理的,经过测试配置线程池后性能会稍好一些。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。