Fastjson是阿里巴巴开源的高性能JSON处理库,广泛应用于Java项目中。下面我将详细讲解如何使用Fastjson将Map对象转换为JSON字符串,并结合实际项目案例进行演示。
一、Fastjson核心API详解
1. 基本转换方法
typescript
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class FastjsonDemo {
public static void main(String[] args) {
// 创建Map对象
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("name", "张三");
dataMap.put("age", 25);
dataMap.put("isStudent", true);
dataMap.put("score", null);
// 方法1:使用JSON.toJSONString()
String jsonStr1 = JSON.toJSONString(dataMap);
System.out.println("方法1结果: " + jsonStr1);
// 方法2:使用JSONObject.toJSONString()
String jsonStr2 = JSONObject.toJSONString(dataMap);
System.out.println("方法2结果: " + jsonStr2);
}
}
2. 高级特性配置
Fastjson提供了多种序列化特性(SerializerFeature)来控制JSON的输出格式:
javascript
import com.alibaba.fastjson.serializer.SerializerFeature;
// 常用序列化特性
String json = JSON.toJSONString(dataMap,
SerializerFeature.PrettyFormat, // 美化输出,带缩进
SerializerFeature.WriteMapNullValue, // 输出null值字段
SerializerFeature.WriteDateUseDateFormat, // 日期格式化
SerializerFeature.DisableCircularReferenceDetect // 禁用循环引用检测
);
3. 命名过滤器(NameFilter)
Fastjson提供了多种命名过滤器来转换key的命名风格:
javascript
import com.alibaba.fastjson.serializer.PascalNameFilter;
import com.alibaba.fastjson.serializer.SnakeCaseNameFilter;
import com.alibaba.fastjson.serializer.CamelCaseNameFilter;
// Pascal命名风格(首字母大写)
String pascalJson = JSON.toJSONString(dataMap, new PascalNameFilter());
// 蛇形命名风格(小写加下划线)
String snakeJson = JSON.toJSONString(dataMap, new SnakeCaseNameFilter());
// 驼峰命名风格(首字母小写,后续单词首字母大写)
String CamelJson = JSON.toJSONString(dataMap, new CamelCaseNameFilter());
4. 值过滤器(ValueFilter)
可以自定义值的转换逻辑:
typescript
import com.alibaba.fastjson.serializer.ValueFilter;
ValueFilter htmlEscapeFilter = (object, name, value) -> {
if (value instanceof String) {
return ((String) value).replace("<", "<")
.replace(">", ">");
}
return value;
};
String safeJson = JSON.toJSONString(dataMap, htmlEscapeFilter);
二、项目实战案例
案例1:REST API响应封装
typescript
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.util.HashMap;
import java.util.Map;
public class ApiResponse {
public static String success(Object data) {
Map<String, Object> result = new HashMap<>();
result.put("code", 200);
result.put("message", "success");
result.put("data", data);
result.put("timestamp", System.currentTimeMillis());
return JSON.toJSONString(result,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat);
}
public static String error(int code, String message) {
Map<String, Object> result = new HashMap<>();
result.put("code", code);
result.put("message", message);
result.put("data", null);
result.put("timestamp", System.currentTimeMillis());
return JSON.toJSONString(result,
SerializerFeature.WriteMapNullValue);
}
}
案例2:数据库查询结果转换
java
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.sql.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class DbToJsonConverter {
public static String resultSetToJson(ResultSet rs) throws SQLException {
List<Map<String, Object>> resultList = new ArrayList<>();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
while (rs.next()) {
Map<String, Object> row = new LinkedHashMap<>();
for (int i = 1; i <= columnCount; i++) {
String columnName = metaData.getColumnLabel(i);
Object value = rs.getObject(i);
row.put(columnName, value);
}
resultList.add(row);
}
return JSON.toJSONString(resultList,
SerializerFeature.PrettyFormat,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat);
}
}
案例3:日志记录系统
typescript
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.util.HashMap;
import java.util.Map;
public class LogSystem {
public static void logRequest(String method, String url, Map<String, String> params) {
Map<String, Object> logData = new HashMap<>();
logData.put("type", "request");
logData.put("method", method);
logData.put("url", url);
logData.put("params", params);
logData.put("time", System.currentTimeMillis());
String logJson = JSON.toJSONString(logData,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat);
System.out.println("[REQUEST] " + logJson);
}
public static void logError(String message, Exception e) {
Map<String, Object> logData = new HashMap<>();
logData.put("type", "error");
logData.put("message", message);
logData.put("exception", e.getClass().getName());
logData.put("stackTrace", e.getStackTrace());
logData.put("time", System.currentTimeMillis());
String logJson = JSON.toJSONString(logData,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteDateUseDateFormat);
System.out.println("[ERROR] " + logJson);
}
}
三、性能优化建议
-
重用JSON实例:对于高并发场景,考虑重用JSON实例,以优化性能
javaprivate static final JSON json = new JSON();
在实际开发中,我们主要通过重用全局的 FastJsonConfig、SerializeConfig、ParserConfig等配置对象 来实现这一目标,而不是直接实例化 JSON类。
-
避免频繁创建Map:对于频繁调用的方法,可以重用Map对象
-
选择合适的序列化特性:只启用必要的特性,减少性能开销
-
使用JSON.parseObject反向操作:
javascriptMap<String, Object> map = JSON.parseObject(jsonStr, new TypeReference<Map<String, Object>>(){});
四、常见问题解决方案
问题1:日期格式处理
ini
// 全局设置日期格式
JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
// 单个转换指定格式
String json = JSON.toJSONString(dataMap,
SerializerFeature.WriteDateUseDateFormat);
问题2:循环引用问题
ini
// 方法1:禁用循环引用检测
String json = JSON.toJSONString(dataMap,
SerializerFeature.DisableCircularReferenceDetect);
// 方法2:使用$ref引用
String json = JSON.toJSONString(dataMap,
SerializerFeature.DisableCheckSpecialChar);
问题3:特殊字符处理
typescript
// 方法1:使用ValueFilter处理特殊字符
ValueFilter filter = (object, name, value) -> {
if (value instanceof String) {
return ((String) value).replace("\n", "\n")
.replace("\r", "\r");
}
return value;
};
// 方法2:使用SerializerFeature
String json = JSON.toJSONString(dataMap,
SerializerFeature.UseSingleQuotes,
SerializerFeature.UseISO8601DateFormat);
五、总结
Fastjson提供了灵活强大的API来处理Map到JSON的转换,通过合理使用各种特性和过滤器,可以满足各种复杂场景的需求。在实际项目中,建议:
- 统一JSON序列化配置,保持风格一致
- 对于敏感数据,使用ValueFilter进行脱敏处理
- 对于大量数据的转换,注意性能优化
- 处理好日期格式和特殊字符等常见问题