当前位置: 首页 > news >正文

Java对象与字符串相互转化的方式

今天在用AI辅助编码时,遇到一个AI写的小缺陷,但是这个小缺陷也可能会有小伙伴遇到,那便是将Bean通过toString()进行了转化,存到了数据库,在后续要再使用时,转不出来系统报错了。

这里我们就来看看这种场景下这个问题应该怎么解决。

要把对象保存到数据库并能还原,常用且安全/可维护的做法有两种:

  1. Java 原生序列化(Serializable — 存为 BLOB 或 Base64 字符串(可直接还原,但有安全与兼容性风险)。
  2. JSON 序列化(推荐) — 使用 Jackson / Gson 把对象转成 JSON 字符串存 VARCHAR/TEXT,恢复时从 JSON 反序列化回对象(更便于阅读、兼容、跨语言)。

下面给出完整示例代码(包含 JDBC 存取示例),并说明为什么不要使用 toString()


例子说明

  • 演示一个简单的 Person 类。

  • 演示三部分代码:

    1. 坏做法toString()(展示为何不可逆)。
    2. 原生序列化 -> Base64 存字符串 -> 反序列化恢复
    3. JSON(使用 Jackson)序列化/反序列化(推荐)
  • 给出 JDBC 插入/查询示例(示范性,不含连接池、事务管理等生产细节)。


1) 示例类(Person)

import java.io.Serializable;public class Person implements Serializable {private static final long serialVersionUID = 1L;private String name;private int age;// 默认构造器(JSON/反序列化需要)public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}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; }// 注意:toString() 仅用于调试,不用于序列化@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}

2) 为什么不要用 toString()

toString() 的输出格式并非标准化,通常为人阅读设计,不保证字段完整性或未来兼容性。除非你自己定义了严格、可逆的 toString()/fromString(),否则无法可靠恢复原对象。

如果你确实用 toString() 存储,只有在你完全控制格式并提供严格解析逻辑时 才能还原;但这通常比直接使用标准序列化/JSON 更脆弱且费力。


3) 原生 Java 序列化(存 Base64 字符串)——示例代码

import java.io.*;
import java.util.Base64;public class JavaSerializationUtil {public static String serializeToBase64(Object obj) throws IOException {ByteArrayOutputStream bos = new ByteArrayOutputStream();try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(obj);}return Base64.getEncoder().encodeToString(bos.toByteArray());}public static Object deserializeFromBase64(String base64) throws IOException, ClassNotFoundException {byte[] data = Base64.getDecoder().decode(base64);try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {return ois.readObject();}}
}

JDBC 示例(将 Base64 字符串存为 VARCHAR 或 TEXT):

import java.sql.*;public class JdbcExample {// 假设已经有 JDBC URL、用户名密码public static void savePersonAsBase64(Connection conn, int id, String base64) throws SQLException {String sql = "INSERT INTO persons_blob (id, data_base64) VALUES (?, ?)";try (PreparedStatement ps = conn.prepareStatement(sql)) {ps.setInt(1, id);ps.setString(2, base64);ps.executeUpdate();}}public static String loadPersonBase64(Connection conn, int id) throws SQLException {String sql = "SELECT data_base64 FROM persons_blob WHERE id = ?";try (PreparedStatement ps = conn.prepareStatement(sql)) {ps.setInt(1, id);try (ResultSet rs = ps.executeQuery()) {if (rs.next()) return rs.getString("data_base64");return null;}}}
}

安全注意:Java 原生反序列化可能存在反序列化漏洞(如果你从不可信来源反序列化)。只在受信环境或采取白名单/安全措施时使用。


4) 推荐:使用 JSON(以 Jackson 为例)

Maven 依赖

<!-- Jackson -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version> <!-- 示例,请以实际需要调整 -->
</dependency>

JSON 序列化/反序列化工具类

import com.fasterxml.jackson.databind.ObjectMapper;public class JsonUtil {private static final ObjectMapper mapper = new ObjectMapper();public static String toJson(Object obj) throws Exception {return mapper.writeValueAsString(obj);}public static <T> T fromJson(String json, Class<T> clazz) throws Exception {return mapper.readValue(json, clazz);}
}

JDBC 示例(把 JSON 存 VARCHAR/TEXT)

import java.sql.*;public class JdbcJsonExample {public static void savePersonAsJson(Connection conn, int id, String json) throws SQLException {String sql = "INSERT INTO persons_json (id, data_json) VALUES (?, ?)";try (PreparedStatement ps = conn.prepareStatement(sql)) {ps.setInt(1, id);ps.setString(2, json);ps.executeUpdate();}}public static String loadPersonJson(Connection conn, int id) throws SQLException {String sql = "SELECT data_json FROM persons_json WHERE id = ?";try (PreparedStatement ps = conn.prepareStatement(sql)) {ps.setInt(1, id);try (ResultSet rs = ps.executeQuery()) {if (rs.next()) return rs.getString("data_json");return null;}}}
}

使用示例(完整流程)

// 假设 conn 是已打开的 JDBC Connection
Person p = new Person("Alice", 30);// JSON 存取(推荐)
String json = JsonUtil.toJson(p);
JdbcJsonExample.savePersonAsJson(conn, 1, json);// 读取并还原
String loadedJson = JdbcJsonExample.loadPersonJson(conn, 1);
Person p2 = JsonUtil.fromJson(loadedJson, Person.class);// Java 原生序列化存取(可行,但需谨慎)
String base64 = JavaSerializationUtil.serializeToBase64(p);
JdbcExample.savePersonAsBase64(conn, 2, base64);String loadedBase64 = JdbcExample.loadPersonBase64(conn, 2);
Person p3 = (Person) JavaSerializationUtil.deserializeFromBase64(loadedBase64);

5) 小结与建议(要点)

  • 不要用 toString() 存数据库 —— 不可逆、格式不稳定、不能确保完整字段数据。
  • 推荐使用 JSON(Jackson/Gson):跨语言、人可读、易调试、向前兼容性好。存 VARCHAR/TEXT
  • 如果对象包含复杂类型或必须保持二进制完整性(比如图像、缓存对象),可以用 Java 序列化或 protobuf、Avro 等二进制序列化方案;注意 Java 反序列化的安全问题。
  • 在生产环境:考虑字段版本管理、兼容策略、字段升级、以及对敏感数据的加密/脱敏。
  • 若你必须从 toString() 恢复,只有在 toString() 明确按可逆格式定义并提供配套解析器时才可行 —— 否则放弃该方案。

终章

这里也有小伙伴喜欢使用fastjson或hutool的JSONUtil来做一些转换处理,这些都是可以的。

http://www.dtcms.com/a/469548.html

相关文章:

  • 纪检网站建设计划wordpress 防止被黑
  • MXIC旺宏NOR Flash实现微秒级光形切换
  • 5、docker存储卷
  • docker搭建高性能运营级流媒体服务框架ZLMediaKit——筑梦之路
  • 完美迁移:将 nvm 和 npm 完全安装到 Windows D 盘
  • 从零到一:用 Vue 打造一个零依赖、插件化的 JS 库
  • 创建好git项目仓库后如何将本地项目传上去
  • wordpress图片主题模板下载南山网站优化
  • 做外贸大大小小的网站有哪些新手如何做外贸生意
  • langchain4j+SpringBoot+DashScope(灵积)整合
  • MATLAB实现直流电法和大地电磁法的一维正演计算
  • IBM 开源轻量级多模态文档理解模型 Granite-Docling:258M 参数,精准还原 PDF、截图中的公式、表格与代码
  • Python PDF文档加密与保护:确保你的文件安全
  • 【Conda】Conda虚拟环境配置系统环境变量,Jupter可使用
  • 网站网页和网址的关系湘潭seo
  • 对象集合里的id用逗号拼装几种方式
  • 框架--MybatisPlus
  • Coze源码分析-资源库-编辑数据库-前端源码-核心逻辑与接口
  • TikTok SDE OA 2025 真题解析与秋招趋势
  • idea 中 mapper.xml黄线警告怎么去掉
  • NXP - MDK460的调试设置
  • 15.UE-游戏逆向-DumpUE struct
  • 百度统计api兰州企业网站排名优化
  • 网站右下角悬浮窗口js代码 兼容各浏览器页面置换算法课程设计
  • NeurIPS 2025 | 华中科大小米等提出语义提示扩散Transformer,实现精准深度估计新范式!
  • Ansible-playbook剧本
  • Mata Summon - Transform text prompts or photos into dynamic.
  • Arbess从入门到实战(11) - 使用Arbess+GitLab实现C++项目自动化部署
  • 做视频网站版权怎么解决企业建站费用情况
  • AICC2025 智算中心与算力服务论坛顺利举办