| 方式 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 原生 HttpServletResponse 流 | 零依賴、完全可控、性能最高 | 手動拼接/序列化、易出錯、無類型安全 | 極簡接口、老項目無法加 jar |
| struts2-json-plugin | 自動序列化、OGNL 表達式過濾字段、注解控制 | 版本衝突多 (xwork/core)、配置繁瑣 | 傳統 Struts2 項目、需字段級控制 |
| 約定優於配置 + Maven | 零 XML、註解驅動、依賴管理自動化 | 需 Maven、學習成本 | 新模塊、現代化改造 |
public void writeJson() throws IOException {
HttpServletResponse response = ServletActionContext.getResponse();
// 必須在 getWriter() 前設置編碼,否則中文亂碼 (ISO-8859-1)
response.setContentType("application/json;charset=UTF-8");
// response.setCharacterEncoding("UTF-8"); // 等價
PrintWriter out = response.getWriter();
String json = "{\"user\":{\"id\":123,\"name\":\"張三\"},\"success\":true}";
out.print(json);
out.flush();
out.close();
}
<action name="writeJson" class="json.JsonAction" method="writeJson" />
<!-- 無 result,Action 直接結束響應 -->
<!-- 方案 A:Struts 2.3.x / 2.5.x 官方插件 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.30</version> <!-- 與 struts2-core 版本一致 -->
</dependency>
⚠️ 老版本 (2.1.x) 需配套 xwork-core-2.1.6.jar,易衝突,強烈建議升級到 2.5+。
public class JsonAction extends ActionSupport {
private Map<String, Object> dataMap = new HashMap<>();
private String internalKey = "不輸出"; // 內部字段
public String json() {
dataMap.put("user", new User("張三", "123"));
dataMap.put("success", true);
return SUCCESS;
}
public Map<String, Object> getDataMap() { return dataMap; }
@JSON(serialize = false) // 註解排除字段
public String getInternalKey() { return internalKey; }
}
<package name="json" extends="struts-default,json-default">
<action name="json" class="json.JsonAction" method="json">
<result type="json">
<param name="root">dataMap</param> <!-- 指定序列化根對象 -->
<param name="excludeNullProperties">true</param> <!-- 忽略 null -->
<param name="includeProperties">user.*</param> <!-- 白名單 -->
<param name="excludeProperties">internalKey</param> <!-- 黑名單 -->
</result>
</action>
</package>
root:指定序列化對象 (需有 getter)includeProperties:OGNL 表達式白名單,如 user.name,list[0].idexcludeProperties:黑名單excludeNullProperties:true 忽略 null 值wrapPrefix/wrapSuffix:JSONP 回調包裹enableGZIP:大響應壓縮<dependencies>
<dependency><groupId>org.apache.struts</groupId><artifactId>struts2-core</artifactId><version>2.5.30</version></dependency>
<dependency><groupId>org.apache.struts</groupId><artifactId>struts2-convention-plugin</artifactId><version>2.5.30</version></dependency>
<dependency><groupId>org.apache.struts</groupId><artifactId>struts2-json-plugin</artifactId><version>2.5.30</version></dependency>
</dependencies>
<struts>
<constant name="struts.action.extension" value="" /> <!-- 去掉 .action 後綴 -->
<constant name="struts.devMode" value="false" />
<package name="base" extends="json-default,struts-default" />
</struts>
@ParentPackage("base")
@Namespace("/watson")
@Results({
@Result(name = "json", type = "json", params = {"root", "msg"})
})
public class JsonAction {
@Action(value = "json")
public String json() {
msg = new HashMap<>();
msg.put("flag", "success");
msg.put("user", Map.of("name", "張三", "age", "34"));
return "json";
}
private Map<String, Object> msg;
public Map<String, Object> getMsg() { return msg; }
}
訪問 /watson/json 直接返回 JSON,無需任何 XML 映射。
Result<T> { code, msg, data },Action 返回 Result,JSON 插件序列化整個對象struts.json.date.format=yyyy-MM-dd HH:mm:ss 或字段註解 @JSON(format="yyyy-MM-dd")excludeNullProperties,避免序列化大量 null@JSON(serialize=false)Struts2 返回 JSON 三板斧:原生流最輕、json-plugin 最全、約定插件最爽。老項目維護用插件,新模塊直接上 struts2-convention-plugin + 註解,配合 Maven 統一版本,徹底告別 jar 衝突地獄。核心竅門:指定 root 對象、字段級白黑名單、統一響應包裝、日期格式全局化。