凌峰创科服务平台

java 服务器 http请求

Java 提供了多种方式来处理 HTTP 请求,主要可以分为以下几类:

java 服务器 http请求-图1
(图片来源网络,侵删)
  1. Java 内置 API (无需任何框架):适合学习原理或创建简单的、独立的服务。
  2. Servlet 容器 (如 Tomcat):这是构建 Web 应用的传统标准,非常稳定和强大。
  3. 现代 Web 框架 (如 Spring Boot):目前业界最主流的方式,极大地简化了开发。

下面我们逐一介绍。


使用 Java 内置的 com.sun.net.httpserver API

这是 Java SE 自带的一个轻量级 HTTP 服务器,非常适合快速启动一个简单的 HTTP 服务,无需任何外部依赖。

核心概念

  • HttpServer: 主服务器类,用于绑定端口和创建上下文。
  • HttpContext: 代表一个 URL 路径(如 , /api),它将一个路径映射到一个处理器。
  • HttpHandler: 一个接口,你需要实现它的 handle 方法来处理具体的 HTTP 请求。

示例代码

下面是一个完整的、可以运行的示例,它会监听 8080 端口,并响应一个简单的 "Hello, World!"。

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
public class SimpleHttpServer {
    public static void main(String[] args) throws IOException {
        // 1. 创建 HttpServer 实例,并绑定到端口 8080
        // new InetSocketAddress(0) 表示自动选择一个可用端口
        HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
        // 2. 创建一个上下文,路径为 "/",并关联一个处理器
        // createContext 会自动处理该路径下的所有请求
        server.createContext("/", new MyHandler());
        // 3. 创建一个线程池来处理请求
        // Executors.newFixedThreadPool(10) 创建一个固定大小为10的线程池
        server.setExecutor(java.util.concurrent.Executors.newFixedThreadPool(10));
        // 4. 启动服务器
        server.start();
        System.out.println("Server started on port 8080. Press Ctrl+C to stop.");
    }
    // 5. 实现自定义的 HttpHandler
    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            // 只处理 GET 请求
            if (!"GET".equals(exchange.getRequestMethod())) {
                exchange.sendResponseHeaders(405, -1); // 405 Method Not Allowed
                return;
            }
            // 获取请求的 URI
            String requestURI = exchange.getRequestURI().toString();
            System.out.println("Received request for: " + requestURI);
            // 准备响应内容
            String response = "Hello, World! This is a response from the Java HTTP Server.";
            // 设置响应头
            // 200 OK
            // text/plain 是响应内容的类型
            exchange.getResponseHeaders().set("Content-Type", "text/plain");
            exchange.sendResponseHeaders(200, response.getBytes().length);
            // 发送响应体
            try (OutputStream os = exchange.getResponseBody()) {
                os.write(response.getBytes());
            }
        }
    }
}

如何运行

  1. 将代码保存为 SimpleHttpServer.java
  2. 编译:javac SimpleHttpServer.java
  3. 运行:java SimpleHttpServer
  4. 打开浏览器或使用 curl 访问 http://localhost:8080,你将看到 "Hello, World!"。

优点

java 服务器 http请求-图2
(图片来源网络,侵删)
  • 无需任何外部库,开箱即用。
  • 轻量级,资源占用少。
  • 适合创建微服务、测试工具或简单的内部服务。

缺点

  • 功能相对简单,处理复杂的 HTTP 特性(如文件上传、会话管理、WebSocket)比较繁琐。
  • 线程模型需要自己管理。

使用 Servlet 容器 (如 Apache Tomcat)

这是构建 Java Web 应用的传统方式,Servlet 是 Java EE (Jakarta EE) 的一部分,它定义了一个标准化的接口,让开发者可以专注于业务逻辑,而服务器(如 Tomcat)负责处理底层的网络通信、线程管理、请求分发等。

核心概念

  • Servlet: 一个 Java 类,用于接收和响应来自客户端的请求,你需要继承 HttpServlet 并重写 doGet, doPost 等方法。
  • Servlet 容器: 如 Apache Tomcat, Jetty, WildFly,它负责加载和运行 Servlet,管理其生命周期。
  • Web 应用: 一个标准的目录结构,包含 WEB-INF/web.xml (部署描述符) 和你的 Servlet 类等。
  • 构建工具: Maven 或 Gradle,用于管理依赖和构建 WAR (Web Application Archive) 文件。

示例步骤 (使用 Maven 和 Tomcat)

  1. 创建 Maven 项目pom.xml 中添加 tomcat-embed-core 依赖(这允许你内嵌 Tomcat 运行,而不是必须部署到外部服务器)。

    <dependencies>
        <!-- 用于内嵌 Tomcat 的核心库 -->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>10.1.15</version> <!-- 使用一个较新的版本 -->
        </dependency>
    </dependencies>
  2. 编写 Servlet 创建一个简单的 Servlet。

    java 服务器 http请求-图3
    (图片来源网络,侵删)
    import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import java.io.IOException;
    // @WebServlet 注解替代了 web.xml 的配置
    // urlPatterns 指定了这个 Servlet 处理的 URL 路径
    @WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            // 设置响应内容类型
            resp.setContentType("text/html");
            // 获取输出流
            java.io.PrintWriter out = resp.getWriter();
            // 生成 HTML 响应
            out.println("<html>");
            out.println("<head><title>Hello Servlet</title></head>");
            out.println("<body>");
            out.println("<h1>Hello from a Servlet running on Tomcat!</h1>");
            out.println("<p>Request URI: " + req.getRequestURI() + "</p>");
            out.println("</body>");
            out.println("</html>");
        }
    }
  3. 编写主程序启动 Tomcat 创建一个主类来启动内嵌的 Tomcat 服务器。

    import org.apache.catalina.WebResourceRoot;
    import org.apache.catalina.core.StandardContext;
    import org.apache.catalina.startup.Tomcat;
    org.apache.catalina.webresources.DirResourceSet;
    import java.io.File;
    public class EmbeddedTomcatServer {
        public static void main(String[] args) throws Exception {
            // 创建 Tomcat 实例
            Tomcat tomcat = new Tomcat();
            // 设置端口
            tomcat.setPort(8080);
            // 设置基础目录 (存放 webapp 的地方)
            String webappDirLocation = "src/main/webapp";
            // 将当前目录下的 webappDirLocation 作为 webapp 的根目录
            StandardContext ctx = (StandardContext) tomcat.addWebapp("/", 
                new File(webappDirLocation).getAbsolutePath());
            // 声明编译后的 classes 目录
            File additionWebInfClasses = new File("target/classes");
            WebResourceRoot resources = new StandardRoot(ctx);
            resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes",
                additionWebInfClasses.getAbsolutePath(), "/"));
            ctx.setResources(resources);
            // 启动 Tomcat
            tomcat.start();
            System.out.println("Tomcat started on port 8080. Press Ctrl+C to stop.");
            // 阻塞主线程,让服务器一直运行
            tomcat.getServer().await();
        }
    }
  4. 运行

    • 确保你的项目结构是 src/main/javasrc/main/webapp
    • 使用 Maven 编译项目:mvn clean compile
    • 运行主程序 EmbeddedTomcatServer
    • 访问 http://localhost:8080/hello

优点

  • 标准化:遵循 Java EE/Jakarta EE 标准,生态系统成熟。
  • 功能强大:拥有海量的第三方库支持(如 JSP, JSTL, JPA)。
  • 稳定可靠:经过数十年的发展,非常稳定,被广泛用于大型企业级应用。

缺点

  • 配置相对复杂:需要配置 web.xml 或使用注解,理解 Servlet 生命周期。
  • 开发周期较长:相比现代框架,需要编写更多的样板代码。

使用现代 Web 框架 (如 Spring Boot)

Spring Boot 是目前 Java 后端开发的事实标准,它通过“约定优于配置”和“自动配置”的理念,极大地简化了创建、运行、监控和生产级 Web 应用的过程。

核心概念

  • Spring Boot Starter: 提供了开箱即用的依赖,spring-boot-starter-web 就包含了构建 Web 应用所需的一切。
  • @RestController: 一个组合注解,用于标记一个类为控制器,并且其所有方法都返回数据(通常是 JSON 或 XML)而不是视图。
  • @RequestMapping / @GetMapping / @PostMapping: 用于映射 HTTP 请求到控制器的方法。

示例代码 (使用 Spring Boot)

  1. 创建 Spring Boot 项目 最简单的方式是使用 Spring Initializr (Web 界面或命令行工具)。

    • Project: Maven Project
    • Language: Java
    • Spring Boot: 选择一个较新的稳定版本 (如 3.x.x)
    • Project Metadata: Group, Artifact, Name 等
    • Dependencies: 添加 Spring Web
  2. 编写 Controller Spring Initializr 会生成一个主应用类,你只需要创建一个 Controller。

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    // @RestController 告诉 Spring 这是一个 RESTful 风格的控制器
    @RestController
    @RequestMapping("/api") // 为这个控制器下的所有方法设置基础路径
    public class MyController {
        // @GetMapping 映射 GET 请求
        // 这个方法会处理 "/api/hello" 的 GET 请求
        @GetMapping("/hello")
        public String sayHello() {
            return "Hello, Spring Boot!";
        }
        // 可以处理带参数的请求
        @GetMapping("/greet")
        public String greet(String name) {
            if (name == null || name.isEmpty()) {
                name = "Guest";
            }
            return "Hello, " + name + "!";
        }
    }
  3. 运行主应用 Spring Initializr 会生成一个带有 @SpringBootApplication 注解的主类,直接运行这个类的 main 方法即可。

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    @SpringBootApplication
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
  4. 测试 Spring Boot 内嵌了一个 Tomcat 服务器,启动后默认监听 8080 端口。

    • 访问 http://localhost:8080/api/hello,得到 Hello, Spring Boot!
    • 访问 http://localhost:8080/api/greet?name=Alice,得到 Hello, Alice!

优点

  • 极速开发:自动配置,省去大量繁琐配置。
  • 生态系统丰富:拥有庞大的社区和第三方库,轻松集成数据库、消息队列、安全等。
  • 生产就绪:内置监控、健康检查、外部化配置等功能。
  • RESTful API 友好:注解清晰,非常适合构建微服务。

缺点

  • 学习曲线:虽然入门简单,但要精通 Spring 框架体系需要一定时间。
  • “黑盒”特性:自动配置有时会让新手感到困惑,不知道背后发生了什么。

总结与对比

特性 com.sun.net.httpserver Servlet (Tomcat) Spring Boot
依赖 无 (JDK 内置) Servlet 容器 (Tomcat) Spring Boot 框架
易用性 简单,适合快速原型 中等,需要理解 Servlet 规范 非常高,开箱即用
功能 基础 HTTP 功能 强大,生态系统成熟 极其强大,生态最完善
性能 轻量级,适合简单任务 高性能,稳定 高性能,优化良好
适用场景 简单工具、测试、微服务 传统 Web 应用、企业级应用 现代微服务、RESTful API、几乎所有 Java Web 应用
推荐度 ⭐⭐⭐ (学习/简单场景) ⭐⭐⭐⭐ (传统项目/标准需求) ⭐⭐⭐⭐⭐ (现代开发首选)

如何选择?

  • 如果你是初学者,想了解 HTTP 服务器的工作原理:从 方案一 开始。
  • 如果你正在学习传统的 Java Web 开发,或者你的项目有严格的 EE 标准要求:学习 方案二
  • 如果你要进行实际的商业项目开发,或者想快速构建一个现代化的、可扩展的应用直接选择方案三 (Spring Boot),这是目前最主流、最高效的选择。
分享:
扫描分享到社交APP
上一篇
下一篇