Spring RESTController中的Java记录-没有主构造函数或单个唯一构造函数

k4ymrczo  于 2022-12-29  发布在  Spring
关注(0)|答案(2)|浏览(448)

我已经尝试了新代码中的java记录。它看起来不错,但我在Spring REST控制器中从JSON反序列化时遇到了麻烦。
记录

public record Order(UUID uuid, List<OrderItem> items) {}

主计长

@PostMapping(value = "/allocations")
public Allocation allocate(Order order) throws Exception {
    return planningService.allocate(order);
}

请求:

{
    "uuid": "123e4567-e89b-12d3-a456-556642440000",
    "items": [
        {  "amount" : 3000 }
    ]
}

这不起作用,因为记录中的uuid为null。没有隐式的String到UUID的转换。所以我添加了非默认构造函数:

public Order(String uuid, List<OrderItem> items) {
    this(UUID.fromString(uuid), items);
}

但Spring不喜欢这样:

java.lang.IllegalStateException: No primary or single unique constructor found for class com.example.fueltransport.beans.Order
    at org.springframework.beans.BeanUtils.getResolvableConstructor(BeanUtils.java:267) ~[spring-beans-5.3.21.jar:5.3.21]

我应该写一些整理程序来记录还是有更简单的方法?

kq0g1dla

kq0g1dla1#

将默认构造函数添加到类:

class Order{
//some code and field

    public Order(){
        this.uuid = null;
        this.items = null;
    }

}

我认为解决方案将修复此异常,但问题仍然存在,因为带有JSON转换器的控制器首先创建一个对象,然后填充对象的接收字段。但java记录具有最终字段,无法再次设置java记录的字段。
为了解决你的问题,你的转换器支持转换java记录,例如,如果你使用Jackson转换器,应该使用Jackson 2. 12+。阅读此link可能会有用。

34gzjxbg

34gzjxbg2#

对于任何可能偶然发现这一点的人,我认为更好的解决方案可能如下所示(假设OrderItem类是可序列化的):

public record Order(UUID uuid, List<OrderItem> items) {
  
  @ConstructorProperties({"uuid", "items"})
  public Order(String uuid, List<OrderItems> items) {
    this(UUID.fromString(uuid), items);
  }

}

相关问题