You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot REST API对接MySQL实现任意格式JSON的PUT存储与GET返回

问题核心原因

你现在遇到的转义问题本质是2个原因导致的:

  1. 上传时将JSON以字符串类型存储,SpringMVC序列化返回时会自动对字符串中的双引号做转义处理
  2. GET返回时把JSON字符串嵌套到了外层实体类中序列化,额外多了外层的包装字段

完整实现方案

1. 数据库与实体类配置

MySQL侧字段直接设为JSON类型即可,无需额外调整。
实体类的JSON存储字段优先用Jackson的JsonNode类型(通用JSON结构,不需要预定义字段),根据你用的ORM框架配好类型处理器:

  • 若使用MyBatis-Plus:实体类加@TableName(autoResultMap = true),JSON字段加@TableField(typeHandler = JacksonTypeHandler.class)
  • 若使用JPA:自定义转换器绑定JsonNode和数据库JSON类型,转换器示例如下:
@Converter
public class JsonNodeConverter implements AttributeConverter<JsonNode, String> {
  private static final ObjectMapper objectMapper = new ObjectMapper();

  @Override
  public String convertToDatabaseColumn(JsonNode jsonNode) {
    try {
      return objectMapper.writeValueAsString(jsonNode);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("JSON序列化失败", e);
    }
  }

  @Override
  public JsonNode convertToEntityAttribute(String s) {
    try {
      return objectMapper.readTree(s);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("JSON反序列化失败", e);
    }
  }
}

实体类示例:

// MyBatis-Plus版本
@Data
@TableName(autoResultMap = true)
public class Sample {
  private Long sampleNo;
  @TableField(typeHandler = JacksonTypeHandler.class)
  private JsonNode sampleData;
}

2. 调整PUT接口

将@RequestBody接收类型从String改为JsonNode,直接接收结构化的JSON对象,不需要手动做序列化转换:

@PutMapping("/sample/{sampleNo}")
public ResponseEntity<Object> addSampleData(
    @ApiParam("Sampleto PUT") @PathVariable Long sampleNo, 
    @RequestBody JsonNode sampleBody) {
  if (sampleBody!= null) {
    sampleService.save(new Sample(sampleNo, sampleBody));
    return new ResponseEntity<>(HttpStatus.OK);
  } else {
    return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
  }
}

3. 调整GET接口

查询到数据后直接返回JsonNode字段作为响应体,不要返回整个Sample实体,即可得到和上传格式完全一致的JSON:

@GetMapping("/sample/{sampleNo}")
public ResponseEntity<JsonNode> getSampleData(@PathVariable Long sampleNo) {
  Sample sample = sampleService.getById(sampleNo);
  if (sample == null) {
    return ResponseEntity.notFound().build();
  }
  // 直接返回JSON节点,Spring会自动序列化为原始JSON结构,无转义
  return ResponseEntity.ok(sample.getSampleData());
}

极简替代方案(不改实体类型,直接存字符串)

如果你不想调整实体类字段类型,坚持用String存JSON,只要修改GET接口即可避免转义:

// 直接返回字符串,指定响应类型为JSON,Spring不会对字符串做转义处理
@GetMapping(value = "/sample/{sampleNo}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getSampleData(@PathVariable Long sampleNo) {
  Sample sample = sampleService.getById(sampleNo);
  if (sample == null) {
    return ResponseEntity.notFound().build();
  }
  return ResponseEntity.ok(sample.getSampleData());
}

内容的提问来源于stack exchange,提问作者say_n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 17:36:03