Servlet 如何向客户端传递 JSON 数据
在 Java Web 开发中,Servlet 作为核心组件,常用于处理后端业务逻辑并向前端返回数据,随着前后端分离架构的普及,JSON(JavaScript Object Notation)已成为前后端数据交互的主流格式,本文将详细介绍 Servlet 如何将数据封装为 JSON 并传递给客户端,涵盖核心步骤、代码实现及常见问题处理。
Servlet 传递 JSON 数据的核心步骤
Servlet 向客户端传递 JSON 数据的本质是:将 Java 对象/数据序列化为 JSON 格式的字符串,并通过 HTTP 响应将字符串返回给前端,具体步骤如下:
- 添加 JSON 处理依赖:选择合适的 JSON 库(如 Jackson、Gson、Fastjson)将 Java 对象转换为 JSON 字符串。
- 设置响应内容类型:通过
response.setContentType()告知客户端返回的是 JSON 数据(通常为application/json)。 - 禁用缓存(可选):通过
response.setHeader("Cache-Control", "no-cache")避免浏览器缓存响应数据。 - 序列化数据并写入响应:使用 JSON 库将 Java 对象转为 JSON 字符串,通过
PrintWriter或OutputStream写入 HTTP 响应体。
实现方式:以 Jackson 库为例
Jackson 是 Java 生态中最流行的 JSON 库之一,高效且功能全面,下面通过具体代码演示 Servlet 如何使用 Jackson 传递 JSON 数据。
项目环境准备
(1)添加 Jackson 依赖
若使用 Maven 项目,在 pom.xml 中添加 Jackson 核心依赖:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- 可根据版本号调整 -->
</dependency>
(2)配置 web.xml
注册 Servlet(以 UserServlet 为例):
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>UserServlet</servlet-name>
<servlet-class>com.example.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserServlet</servlet-name>
<url-pattern>/user</url-pattern>
</servlet-mapping>
</web-app>
定义数据模型(Java 对象)
假设需要传递用户信息,定义 User 类:
package com.example.model;
public class User {
private int id;
private String name;
private int age;
private String email;
// 无参构造器(序列化时可能需要)
public User() {}
// 全参构造器
public User(int id, String name, int age, String email) {
this.id = id;
this.name = name;
this.age = age;
this.email = email;
}
// Getter 和 Setter(Jackson 需要通过反射访问属性)
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", email='" + email + '\'' + '}';
}
}
编写 Servlet 处理逻辑
在 UserServlet 中,模拟从数据库获取数据,并通过 Jackson 序列化为 JSON 返回:
package com.example.servlet;
import com.example.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class UserServlet extends HttpServlet {
// Jackson ObjectMapper 实例(建议单例,避免重复创建)
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 模拟业务逻辑:获取用户数据
List<User> users = new ArrayList<>();
users.add(new User(1, "张三", 25, "zhangsan@example.com"));
users.add(new User(2, "李四", 30, "lisi@example.com"));
// 2. 设置响应内容类型为 JSON
response.setContentType("application/json;charset=UTF-8");
// 3. 可选:禁用缓存(避免浏览器缓存旧数据)
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
// 4. 将 Java 对象序列化为 JSON 字符串并写入响应
// objectMapper.writeValue() 直接将对象写入响应输出流
objectMapper.writeValue(response.getOutputStream(), users);
}
}
测试接口
启动 Tomcat 服务器,通过浏览器或 API 工具(如 Postman)访问 http://localhost:8080/your-project-name/user,将返回如下 JSON 数据:
[
{
"id": 1,
"name": "张三",
"age": 25,
"email": "zhangsan@example.com"
},
{
"id": 2,
"name": "李四",
"age": 30,
"email": "lisi@example.com"
}
]
其他 JSON 库的实现对比
除了 Jackson,Gson 和 Fastjson 也是常用的 JSON 库,下面简要对比其实现方式。
使用 Gson 库
(1)添加依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
(2)Servlet 修改(仅替换序列化逻辑)
import com.google.gson.Gson;
public class UserServlet extends HttpServlet {
private final Gson gson = new Gson();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<User> users = new ArrayList<>();
users.add(new User(1, "张三", 25, "zhangsan@example.com"));
users.add(new User(2, "李四", 30, "lisi@example.com"));
response.setContentType("application/json;charset=UTF-8");
// 使用 Gson 的 toJson 方法转为 JSON 字符串
String json = gson.toJson(users);
response.getWriter().write(json);
}
}
使用 Fastjson 库(阿里巴巴)
(1)添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.40</version>
</dependency>
(2)Servlet 修改(仅替换序列化逻辑)
import com.alibaba.fastjson.JSON;
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<User> users = new ArrayList<>();
users.add(new User(1, "张三", 25, "zhangsan@example.com"));
users.add(new User(2, "李四", 30, "lisi@example.com"));
response.setContentType("application/json;charset=UTF-8");
// 使用 Fastjson 的 toJSONString 方法
String json = JSON.toJSONString(users);
response.getWriter().write(json);
}
}
常见问题与注意事项
中文乱码问题
若 JSON 数据中包含中文,可能出现乱码,解决方案:
- 响应输出流:使用
response.getOutputStream()(字节流)并指定编码(如response.setCharacterEncoding("UTF-8")),或使用response.getWriter()(字符流)确保编码一致。 - JSON 库配置:Jackson 可通过
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)处理命名风格,但中文乱码主要靠响应编码解决。
循环引用问题
若 Java 对象存在双向引用(如 User 和 Order 互相持有),序列化时会抛出 JsonMappingException,解决方案:
- 使用
@JsonIgnore注解:在循环引用的属性上添加,避免序列化该字段。public class User { private List<Order> orders;



还没有评论,来说两句吧...