Struts2 中如何打印 JSON 数据详解
在 Java Web 开发中,Struts2 作为经典的 MVC 框架,常用于处理请求响应,而 JSON 作为轻量级的数据交换格式,前后端交互中被广泛使用,本文将详细介绍在 Struts2 中如何通过多种方式打印 JSON 数据,包括传统配置方式、注解方式以及常见问题解决方案。
Struts2 打印 JSON 数据的核心原理
Struts2 本身不直接处理 JSON 数据,而是通过集成 JSON 插件(json-plugin) 或 Struts2 Convention 插件 实现 JSON 数据的序列化与输出,其核心流程是:
- Action 处理请求,返回数据(如对象、集合、Map 等);
- Struts2 通过 JSON 处理器(如
json-default包的json结果类型)将数据序列化为 JSON 字符串; - 设置响应头为
application/json,最终将 JSON 数据输出到客户端。
准备工作:依赖与配置
添加必要依赖
确保项目中引入 Struts2 核心依赖及 JSON 插件依赖(以 Maven 为例):
<!-- Struts2 核心依赖 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.30</version>
</dependency>
<!-- Struts2 JSON 插件依赖 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.30</version>
</dependency>
<!-- JSON 序列化依赖(如 Jackson,JSON 插件默认使用) -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
配置 Struts2
在 struts.xml 中加载 json-default 包(该包包含 JSON 结果类型的定义):
<struts>
<!-- 继承 json-default 包,以使用 json 结果类型 -->
<package name="default" extends="json-default">
<!-- Action 配置见后续示例 -->
</package>
</struts>
传统方式:通过 XML 配置打印 JSON
定义 Action
创建一个 Action 类,包含需要返回的数据属性,并提供 getter/setter 方法:
package com.example.action;
import java.util.HashMap;
import java.util.Map;
public class UserAction {
// 请求参数(可通过 setter 注入)
private String username;
private int age;
// 返回的 JSON 数据(可直接作为属性)
private Map<String, Object> resultData = new HashMap<>();
// Action 方法
public String execute() {
// 模拟业务逻辑
resultData.put("status", "success");
resultData.put("message", "User info retrieved");
resultData.put("user", new HashMap<String, Object>() {{
put("name", username);
put("age", age);
}});
return "success"; // 返回逻辑视图名
}
// Getter & Setter
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map<String, Object> getResultData() {
return resultData;
}
public void setResultData(Map<String, Object> resultData) {
this.resultData = resultData;
}
}
配置 Action 与结果类型
在 struts.xml 中配置 Action,并指定 json 结果类型:
<package name="default" extends="json-default">
<action name="userAction" class="com.example.action.UserAction">
<!-- 配置请求参数拦截器(可选,用于自动注入 username/age) -->
<interceptor-ref name="params"/>
<!-- 配置 json 结果类型 -->
<result name="success" type="json">
<!-- 指定需要序列化为 JSON 的属性(默认会序列化所有 getter 返回的属性) -->
<param name="root">resultData</param>
<!-- 可选:排除不需要的属性 -->
<param name="excludeProperties">password</param>
<!-- 可选:是否忽略空值(默认 false) -->
<param name="ignoreHierarchy">true</param>
</result>
</action>
</package>
测试访问
启动项目后,通过浏览器或 API 工具(如 Postman)访问:
http://localhost:8080/your-project/userAction.action?username=Tom&age=25
响应结果为:
{
"status": "success",
"message": "User info retrieved",
"user": {
"name": "Tom",
"age": 25
}
}
注解方式:使用 @ParentPackage 与 @Action
对于习惯注解开发的开发者,可通过 Struts2 的注解简化配置,无需在 struts.xml 中逐个配置 Action。
添加注解支持依赖
确保 struts2-convention-plugin 依赖已添加(Maven):
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.5.30</version>
</dependency>
使用注解配置 Action
修改 Action 类,添加注解:
package com.example.action;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.ResultPath;
import java.util.HashMap;
import java.util.Map;
@ParentPackage("json-default") // 指定父包为 json-default,以使用 json 结果类型
@Namespace("/api") // 指定命名空间
@ResultPath(value = "/") // 指定结果页面路径(默认为 WEB-INF/content,可自定义)
public class UserActionAnnotation {
private String username;
private int age;
private Map<String, Object> resultData = new HashMap<>();
@Action(value = "getUser", results = {
@Result(name = "success", type = "json", params = {
"root", "resultData" // 指定 JSON 根节点
})
})
public String execute() {
resultData.put("status", "success");
resultData.put("user", new HashMap<String, Object>() {{
put("name", username);
put("age", age);
}});
return "success";
}
// Getter & Setter(省略)
}
测试访问
访问路径由注解自动生成:
http://localhost:8080/your-project/api/getUser.action?username=Jerry&age=30
响应结果与 XML 配置方式一致。
常见问题与解决方案
JSON 数据出现双引号转义(如 \"username\")
原因:Struts2 默认使用 org.apache.struts2.json.JSONWriter 进行序列化,会对特殊字符进行转义。
解决:改用 Jackson 作为 JSON 序列化引擎(推荐)。
在 struts.xml 中添加全局配置:
<constant name="struts.jsonUtilBean" value="com.fasterxml.jackson.databind.ObjectMapper"/>
返回 JSON 时提示“406 Not Acceptable”
原因:未正确设置响应头 Content-Type 为 application/json。
解决:确保结果类型配置正确,或在 Action 中手动设置响应头:
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.interceptor.ServletResponseAware;
public class UserAction implements ServletResponseAware {
private HttpServletResponse response;
@Override
public void setServletResponse(HttpServletResponse response) {
this.response = response;
}
public String execute() {
response.setContentType("application/json;charset=UTF-8");
// 业务逻辑
return "success";
}
}
循环引用导致 JSON 序列化失败
原因:对象间存在双向引用(如 User 和 Order 互相持有),序列化时无限递归。
解决:
- 使用
@JsonIgnore注解(需 Jackson 支持)标记不需要序列化的属性; - 或在
struts.xml中配置排除属性:<result name="success" type="json"> <param name="excludeProperties">orders.user</param> <!-- 排除 orders.user 属性 --> </result>
中文乱码问题
原因:未正确设置字符编码。
解决:
- 在 `str



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