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 页面)
相关推荐
侠客行03174 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪4 小时前
深入浅出LangChain4J
java·langchain·llm
灰子学技术5 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚5 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎6 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
二十雨辰6 小时前
[python]-AI大模型
开发语言·人工智能·python
Yvonne爱编码6 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚6 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂6 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
pas1366 小时前
41-parse的实现原理&有限状态机
开发语言·前端·javascript