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

Spring Boot中PostMapping接收binary16字符串转UUID问题求助

Binary16字符串转UUID问题求助

我需要将请求中的binary16格式字符串转换为UUID,尝试了多种方法都没解决。场景是从MySQL数据库读取binary16类型的UUID数据,同时接口接收的JSON请求里也是这种无分隔符的32位字符串(比如5a61a32a5ab045dbb5a2bf25425da963)。我试过在DTO或实体类里用String类型接收,但还是无法正确转换为UUID存入数据库。

相关代码如下:

实体类代码

@NoArgsConstructor
@ToString
@Entity
@Table(name = "attendant")
public class AttendantModel implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Getter
    private UUID attendantID;

    @Column(nullable = false, length = 100)
    @Getter @Setter
    private String name;

    @Column
    @Getter @Setter
    private UUID productID1;

    @Column
    @Getter @Setter
    private UUID productID2;

    @Column
    @Getter @Setter
    private UUID instructionID;
}

控制器代码

@RestController
@RequestMapping("/api/attendant")
public class AttendantController {
    final AttendantService attendantService;

    public AttendantController(AttendantService attendantService) {
        this.attendantService = attendantService;
    }

    @Autowired
    private AttendantRepository attendantRepository;

    @PostMapping
    public ResponseEntity<Object> saveInstructions(@RequestBody @Valid AttendantDto attendantDto) {
        var attendantModel = new AttendantModel();
        BeanUtils.copyProperties(attendantDto, attendantModel);
        return ResponseEntity.status(HttpStatus.CREATED).body(attendantService.save(attendantModel));
    }
}

DTO类代码

public class AttendantDto {
    @NotBlank
    @Size(max = 100)
    @Getter @Setter
    private String name;

    @Getter @Setter
    private UUID productID1;

    @Getter @Setter
    private UUID productID2;

    @Getter @Setter
    private UUID instructionID;
}

JSON请求示例

{
    "name": "Júlia - vendedora",
    "productID1": "5a61a32a5ab045dbb5a2bf25425da963"
}

解决方案

方法1:自定义JSON转换器(适配无分隔符UUID字符串)

Spring默认的UUID转换器只识别带-分隔符的标准UUID格式,你需要自定义转换器处理无分隔符的32位字符串:

  1. 编写自定义反序列化器:
public class CustomUuidDeserializer extends StdDeserializer<UUID> {
    protected CustomUuidDeserializer() {
        super(UUID.class);
    }

    @Override
    public UUID deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String uuidStr = p.getText().trim();
        // 给无分隔符字符串插入分隔符,转为标准UUID格式
        if (uuidStr.length() == 32) {
            String formatted = String.format("%s-%s-%s-%s-%s",
                    uuidStr.substring(0, 8),
                    uuidStr.substring(8, 12),
                    uuidStr.substring(12, 16),
                    uuidStr.substring(16, 20),
                    uuidStr.substring(20));
            return UUID.fromString(formatted);
        }
        // 兼容标准格式UUID
        return UUID.fromString(uuidStr);
    }
}
  1. 在DTO的UUID字段上指定该反序列化器:
@Getter @Setter
@JsonDeserialize(using = CustomUuidDeserializer.class)
private UUID productID1;

@Getter @Setter
@JsonDeserialize(using = CustomUuidDeserializer.class)
private UUID productID2;

@Getter @Setter
@JsonDeserialize(using = CustomUuidDeserializer.class)
private UUID instructionID;

方法2:DTO用String接收,手动转换为UUID

如果不想自定义转换器,可以在DTO中用String接收字段,转换实体类时手动处理格式:

  1. 修改DTO字段类型:
@Getter @Setter
private String productID1;

@Getter @Setter
private String productID2;

@Getter @Setter
private String instructionID;
  1. 在控制器中手动转换:
@PostMapping
public ResponseEntity<Object> saveInstructions(@RequestBody @Valid AttendantDto attendantDto) {
    var attendantModel = new AttendantModel();
    BeanUtils.copyProperties(attendantDto, attendantModel);
    
    // 转换productID1
    if (attendantDto.getProductID1() != null && !attendantDto.getProductID1().isEmpty()) {
        String pid1 = attendantDto.getProductID1();
        String formattedPid1 = String.format("%s-%s-%s-%s-%s",
                pid1.substring(0,8), pid1.substring(8,12), pid1.substring(12,16),
                pid1.substring(16,20), pid1.substring(20));
        attendantModel.setProductID1(UUID.fromString(formattedPid1));
    }
    // 同理处理productID2和instructionID
    
    return ResponseEntity.status(HttpStatus.CREATED).body(attendantService.save(attendantModel));
}

方法3:配置JPA适配MySQL的binary16存储

确保MySQL中对应字段为BINARY(16)类型,JPA会自动处理UUID与binary16的转换。若字段类型不符,先修改表结构:

ALTER TABLE attendant MODIFY COLUMN productID1 BINARY(16);
ALTER TABLE attendant MODIFY COLUMN productID2 BINARY(16);
ALTER TABLE attendant MODIFY COLUMN instructionID BINARY(16);

同时在实体类的UUID字段上明确指定列类型,避免JPA自动生成错误类型:

@Column(columnDefinition = "BINARY(16)")
@Getter @Setter
private UUID productID1;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 19:43:10