api vs jsp 绑定风格

api vs jsp 绑定风格

这是一个关于 Java Web Servlet 接口的示例,我将为您创建两个 Servlet

  1. 一个支持 cURL 或任何标准 HTTP 客户端调用的接口 (CurlCallableServlet)。
  2. 一个通常不直接 设计为 cURL 调用,而是与 JSP 页面集成(用于渲染视图)的接口 (JspBoundServlet)。

请注意:从技术上讲,任何暴露 HTTP 端点的 Servlet 都可以被 cURL 调用。这里的"不支持"主要是指它的设计意图和通常用法:它通常会将请求转发给一个 JSP 页面来生成完整的 HTML 响应,而不是像 API 接口那样直接返回数据。

1. 支持 cURL 调用的 Servlet (API 风格)

这个 Servlet 通常用于提供 API 服务,它直接返回数据(例如 JSON 或纯文本),可以轻松地被 cURL 或其他编程客户端调用。

文件: CurlCallableServlet.java

复制代码
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 使用 @WebServlet 注解,映射到 /api/data 路径
@WebServlet("/api/data")
public class CurlCallableServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
           throws ServletException, IOException {
        
        // 1. 设置响应的内容类型为 JSON,方便客户端(如 cURL)解析
        response.setContentType("application/json");
        // 2. 设置字符编码
        response.setCharacterEncoding("UTF-8");

        // 3. 构造要返回的数据
        String name = request.getParameter("name");
        String message = (name != null && !name.isEmpty()) ? 
                         "Hello, " + name + "! Data fetched successfully." : 
                         "Data fetched successfully for an anonymous user.";

        // 4. 简单 JSON 格式输出
        String jsonResponse = String.format(
            "{\"status\":\"success\", \"message\":\"%s\", \"timestamp\":%d}", 
            message, System.currentTimeMillis());

        // 5. 写入响应
        PrintWriter out = response.getWriter();
        out.print(jsonResponse);
        out.flush();
    }
}

cURL 调用示例 (假设您的应用运行在 http://localhost:8080):

复制代码
# 简单的 GET 请求
curl http://localhost:8080/yourapp/api/data

# 带有参数的 GET 请求
curl "http://localhost:8080/yourapp/api/data?name=UserA"

# 预期输出类似:
# {"status":"success", "message":"Hello, UserA! Data fetched successfully.", "timestamp":1701234567890} 

2. 不支持 cURL 调用的 Servlet (JSP 绑定风格)

这个 Servlet 通常用于 MVC (Model-View-Controller) 模式的 Controller 部分。它的主要工作是处理请求、准备数据,然后使用 RequestDispatcher 将控制权转发 给一个 JSP 视图来渲染完整的 HTML 页面。如果用 cURL 调用,它会返回一个完整的 HTML 页面,而不是简洁的数据,所以通常认为它"不支持"直接作为 API 调用。

文件: JspBoundServlet.java

复制代码
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

// 映射到 /app/page 路径
@WebServlet("/app/page")
public class JspBoundServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
           throws ServletException, IOException {
        
        // 1. **不设置 ContentType** (通常由 JSP 来处理最终的 HTML 响应)

        // 2. 准备数据 (Model)
        String user = "Guest";
        String time = new java.util.Date().toString();
        
        // 3. 将数据放入 request 作用域,供 JSP 访问
        request.setAttribute("username", user);
        request.setAttribute("serverTime", time);

        // 4. **转发**请求到 JSP 视图 (View)
        // 核心区别:它不自己写响应,而是把响应生成任务交给 JSP。
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/views/welcome.jsp");
        dispatcher.forward(request, response);
        
        // 注意:在这个 Servlet 方法中,response.getWriter().print(...) 不会被调用
        // 所有输出都由 JSP 负责。
    }
}

JSP 文件: /WEB-INF/views/welcome.jsp

复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Welcome Page</title>
</head>
<body>
    <h1>Hello, ${username}!</h1>
    <p>This is a view rendered by JSP.</p>
    <p>Current Server Time: <strong>${serverTime}</strong></p>
    
    <button onclick="alert('This is a button for a real user.')">Click Me</button>
</body>
</html>

cURL 调用示例 (假设您的应用运行在 http://localhost:8080):

复制代码
curl http://localhost:8080/yourapp/app/page

# 预期输出:返回的是整个 HTML 页面内容,包含 <head>, <body> 等标签,
# 客户端(cURL)通常只想要数据的场景下,这种输出是不合适的。
# <!DOCTYPE html><html><head>...</head><body>...</body></html>

总结比较

特性 CurlCallableServlet (API 风格) JspBoundServlet (JSP 绑定风格)
设计意图 提供结构化数据(JSON/XML)作为 API 作为控制器,处理请求后转发给视图(JSP)
响应内容 application/jsontext/plain text/html (由 JSP 生成)
主要方法 response.getWriter().print(...) 直接输出数据 request.getRequestDispatcher().forward(...) 转发到 JSP
cURL 适用性 非常适用 (返回简洁数据) 不适用 (返回完整的 HTML 页面)
相关推荐
维吉斯蔡5 小时前
【VS Code / Cursor】文件夹右键快捷打开与文件类型自动关联
开发语言·程序人生·学习方法
蓝斯4976 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加贝塞尔曲线,上、下、左、右连接点
java·c#·流程图
前端工作日常6 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
都叫我大帅哥7 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-7 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常7 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅7 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
luj_17687 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
always_TT7 小时前
【Python 日志记录:logging 模块入门】
开发语言·python·php
xcLeigh8 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang