首页 > 解决方案 > InvalidDefinitionException:无法构造“com.vehicle.datatransferobject.VehicleDTO”的实例

问题描述

在我在 Spring Boot 中构建的 REST 端点中,我试图将我的传递vehicleDTO给我的控制器。但在它到达我的控制器之前,出现了一个错误。

InvalidDefinitionException:无法构造实例 com.vehicle.datatransferobject.VehicleDTO(没有创建者,如默认构造,存在):无法从对象值反序列化(没有基于委托或属性的创建者)

车辆DTO

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.myvehicle.EngineType;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class VehicleDTO {

    @JsonIgnore
    private Long id;

    @NotNull(message = "vehiclenumber can not be null!")
    private String vehiclenumber;

    @Min(2)
    @NotNull(message = "Seat count can not be less than 2!")
    private Integer vehicleseatcount;

    @NotNull(message = "Engine Type can not be null!")
    private EngineType enginetype;

    @Max(5)
    private Integer vehiclerating;



    private VehicleDTO(Long id, String vehiclenumber, Integer vehicleseatcount, EngineType enginetype,Integer vehiclerating){
        this.vehiclenumber=vehiclenumber;
        this.vehicleseatcount=vehicleseatcount;
        this.enginetype=enginetype;
        this.vehiclerating=vehiclerating;
        this.id=id;
    }

    public static VehicleDTOBuilder newBuilder()
    {
        return new VehicleDTOBuilder();
    }

    @JsonProperty
    public Long getId() {
        return id;
    }


    public String getvehiclenumber() {
        return vehiclenumber;
    }


    public Integer getvehicleseatcount() {
        return vehicleseatcount;
    }


    public EngineType getEnginetype() {
        return enginetype;
    }



    public Integer getvehiclerating() {
        return vehiclerating;
    }




    public static class VehicleDTOBuilder{

        private Long id;
        private String vehiclenumber;
        private Integer vehicleseatcount;
        private EngineType enginetype;
        private Integer vehiclerating;

        public VehicleDTOBuilder setId(Long id) {
            this.id = id;
            return this;
        }
        public VehicleDTOBuilder setvehiclenumber(String vehiclenumber) {
            this.vehiclenumber = vehiclenumber;
            return this;
        }
        public VehicleDTOBuilder setvehicleseatcount(Integer vehicleseatcount) {
            this.vehicleseatcount = vehicleseatcount;
            return this;
        }
        public VehicleDTOBuilder setEnginetype(EngineType enginetype) {
            this.enginetype = enginetype;
            return this;
        }
        public VehicleDTOBuilder setvehiclerating(Integer vehiclerating) {
            this.vehiclerating = vehiclerating;
            return this;
        }


        public VehicleDTO createVehicleDTO()
        {
            return new VehicleDTO(id, vehiclenumber, vehicleseatcount, enginetype,vehiclerating);
        }

    }

}

我的 DTO 有一个名为 EngineType 的枚举类型

public enum EngineType {
    ELECTRIC, DIESEL
}

我的控制器看起来像这样

@PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public VehicleDTO addvehicle(@Valid @RequestBody VehicleDTO vehicleDTO) 
    {
        VehicleDO vehicleDO = Mapper.VehicleDO(vehicleDTO);
        return Mapper.makeVehicleDTO(Service.addvehicle(vehicleDO));
    }

标签: restspring-bootjacksonspring-restcontroller

解决方案


这个例外:

InvalidDefinitionException:无法构造 com.vehicle.datatransferobject.VehicleDTO 的实例(没有创建者,如默认构造,存在):无法从对象值反序列化(没有基于委托或属性的创建者)

意味着杰克逊没有找到一种方法来实例化VehicleDTO默认构造函数(无 arg 构造函数)或JsonCreator.
当您使用构建器模式时,您将配置VehicleDTO类以使 Jackson 实例化VehicleDTOVehicleDTOBuilder例如:

@JsonDeserialize(builder = VehicleDTO.VehicleDTOBuilder.class)
public class VehicleDTO {
      ...         
}

并使用JsonPOJOBuilder将您的构建器注释为:

@JsonPOJOBuilder(buildMethodName = "createVehicleDTO", withPrefix = "set")
public static class VehicleDTOBuilder{ 
   ...
}

根据javadoc,JsonPOJOBuilder是:

用于配置 Builder 类的详细信息:其实例用作反序列化 POJO 值的 Builder,而不是使用构造函数或工厂方法实例化 POJO。请注意,此注解不用于定义 POJO 的 Builder 类:而是由 JsonDeserialize 的 JsonDeserialize.builder() 属性确定。


推荐阅读