首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

JSON 工具類封裝最佳實踐:基於 json-lib 的通用轉換組件

     編輯:Java 綜合教學

企業級 JSON 處理工具類設計與實現

在 Java 企業開發中,JSON 數據交換無處不在:REST API 回應、前後端數據傳輸、配置文件解析、日誌序列化。本文提供基於 json-lib 的通用工具類 JsonUtil,支援陣列、集合、Map、物件、XML 互轉,並解決循環引用、字段過濾、日期格式化等實戰痛點。

Maven 依賴配置

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <version>2.4</version>
    <classifier>jdk15</classifier>
</dependency>
<!-- 必須依賴 -->
<dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
</dependency>
<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>
<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.2</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>net.sf.ezmorph</groupId>
    <artifactId>ezmorph</artifactId>
    <version>1.0.6</version>
</dependency>

核心工具類實現

public class JsonUtil {
    
    /** 將物件陣列轉為 JSON 字串 */
    public static String array2json(Object[] objects) {
        JSONArray jsonArray = JSONArray.fromObject(objects);
        return jsonArray.toString();
    }
    
    /** 將 List 集合轉為 JSON 字串 */
    public static String list2json(List list) {
        JSONArray jsonArray = JSONArray.fromObject(list);
        return jsonArray.toString();
    }
    
    /** 將 Map 集合轉為 JSON 字串 */
    public static String map2json(Map map) {
        JSONObject jsonObject = JSONObject.fromObject(map);
        return jsonObject.toString();
    }
    
    /** 將任意 Java 物件轉為 JSON 字串 */
    public static String object2json(Object object) {
        JSONObject jsonObject = JSONObject.fromObject(object);
        return jsonObject.toString();
    }
    
    /** 將 XML 字串轉為 JSON 字串 */
    public static String xml2json(String xml) {
        JSONArray jsonArray = (JSONArray) new XMLSerializer().read(xml);
        return jsonArray.toString();
    }
    
    /** 
     * 進階配置:字段過濾、循環引用處理、日期格式化
     * @param excludes 要排除的字段名陣列(如關聯物件防止循環引用)
     */
    public static JsonConfig configJson(String[] excludes) {
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setExcludes(excludes);                              // 排除字段
        jsonConfig.setIgnoreDefaultExcludes(true);                     // 忽略默認排除
        jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT); // 寬容模式處理循環引用
        
        // 可選:註冊日期值處理器
        // jsonConfig.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
        
        return jsonConfig;
    }
    
    /** 帶配置的物件轉 JSON */
    public static String object2json(Object object, String[] excludes) {
        return JSONObject.fromObject(object, configJson(excludes)).toString();
    }
    
    /** 帶配置的 List 轉 JSON */
    public static String list2json(List list, String[] excludes) {
        return JSONArray.fromObject(list, configJson(excludes)).toString();
    }
}

實戰應用場景

1. REST Controller 統一回應

@RestController
public class UserController {
    
    @GetMapping("/users/{id}")
    public String getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        // 排除敏感字段與循環引用關聯
        return JsonUtil.object2json(user, new String[]{"password", "roles", "orders"});
    }
    
    @GetMapping("/users")
    public String listUsers(Pageable pageable) {
        Page page = userService.findAll(pageable);
        // 列表場景同樣需要過濾
        return JsonUtil.list2json(page.getContent(), new String[]{"password", "roles"});
    }
}

2. 解決雙向關聯循環引用

@Entity
public class Order {
    @Id Long id;
    @ManyToOne User user;           // 關聯用戶
    List items;          // 關聯明細
}

@Entity
public class User {
    @Id Long id;
    @OneToMany(mappedBy = "user") List orders;  // 反向關聯 → 循環引用
}

// 序列化時排除反向引用
String json = JsonUtil.object2json(user, new String[]{"orders"});
// 或在 Order 中排除 user
String json = JsonUtil.object2json(order, new String[]{"user.orders"});

3. 日期格式化統一處理

public class DateJsonValueProcessor implements JsonValueProcessor {
    private final String format;
    
    public DateJsonValueProcessor(String format) { this.format = format; }
    
    @Override
    public Object processArrayValue(Object value, JsonConfig jsonConfig) {
        return processObjectValue(null, value, jsonConfig);
    }
    
    @Override
    public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
        if (value == null) return "";
        if (value instanceof java.util.Date) {
            return new SimpleDateFormat(format).format((Date) value);
        }
        return value.toString();
    }
}

// 使用方式
JsonConfig config = JsonUtil.configJson(new String[]{"password"});
config.registerJsonValueProcessor(Date.class, new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));
String json = JSONObject.fromObject(user, config).toString();
// 輸出: {"createTime":"2024-01-15 14:30:00", ...}

4. XML 轉 JSON 互操作

String xml = "1張三";
String json = JsonUtil.xml2json(xml);
// 輸出: [{"user":{"id":"1","name":"張三"}}]
// 注意:XMLSerializer 將根元素轉為 JSONArray,單個元素也會包在陣列中

進階擴展建議

遷移到 Jackson(推薦)

json-lib 已停止維護,新專案強烈建議使用 Jackson 或 Gson。Jackson 遷移對照:

json-libJackson
JSONObject.fromObject(obj)objectMapper.writeValueAsString(obj)
JSONArray.fromObject(list)objectMapper.writeValueAsString(list)
JsonConfig.setExcludes()@JsonIgnore 或 objectMapper.setSerializationInclusion(Include.NON_NULL)
CycleDetectionStrategy.LENIENT@JsonManagedReference/@JsonBackReference 或 @JsonIdentityInfo
JsonValueProcessor@JsonFormat(pattern="yyyy-MM-dd") 或自定義 JsonSerializer

Jackson 等效配置範例

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapper.registerModule(new JavaTimeModule()); // Java 8 時間類型支援
        return mapper;
    }
}

效能優化提示

  1. ObjectMapper 重用:Jackson 的 ObjectMapper 線程安全,應作為單例重用
  2. 避免重複序列化:Controller 直接回傳物件,由 HttpMessageConverter 統一序列化
  3. 流式 API:大數據量場景使用 JsonGenerator 流式寫入,減少記憶體佔用
  4. Afterburner 模組:Jackson 可加入 jackson-module-afterburner 提升序列化速度 30%+

無論選用哪個 JSON 庫,核心設計原則一致:統一配置、字段可控、循環安全、日期標準。封裝好通用工具類,讓業務代碼專注於核心邏輯,而非格式轉換細節。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved