Spring Boot REST API对接MySQL实现任意格式JSON的PUT存储与GET返回
问题核心原因
你现在遇到的转义问题本质是2个原因导致的:
- 上传时将JSON以字符串类型存储,SpringMVC序列化返回时会自动对字符串中的双引号做转义处理
- 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
相关产品推荐
相关产品推荐

