接口类型的Java数组列表



我在spring引导中有两个java端点:

@PostMapping(path="/my-import-1")
@ResponseStatus(HttpStatus.OK)
public String myImport1(@Valid @RequestBody ParameterDto1 params) {
return this.serviceImpl.import(params);
}

@PostMapping(path="/my-import-2")
@ResponseStatus(HttpStatus.OK)
public String myImport2(@Valid @RequestBody ParameterDto2 params) {
return this.serviceImpl.import(params);
}

两者都使用相同的服务进行导入,但在参数上有一些不同。

我像这样创建了服务的导入方法

@Override
public String import(ParameterInterface params) throws Exception {
...
}

和这样的ParameterInterface

public interface ImportMetaData {
public default ArrayList<FileInterface> getFiles() {
return null;
}
public void setFiles(ArrayList<FileInterface> files);
}
为了实现这个接口,我创建了两个ParameterDto类(ParameterDto1和ParameterDto2)。IDE显示一切正常,我的服务也开始工作,但是一旦我向其中一个端点发送请求,我就会得到以下错误:

servlet .service()为servlet [dispatcherServlet]在上下文与路径[]抛出异常[请求处理失败;嵌套异常是org.springframework.http.converter.HttpMessageConversionException:类型定义错误:[简单类型,类。com.beo.services.myImportService.rest.domain.dto.metadata.interfaces.ParameterInerface];嵌套异常是com.fasterxml.jackson.databind.exc.InvalidDefinitionException:不能的构造实例com.beo.services.myImportService.rest.domain.dto.metadata.interfaces.ParameterInerface(不存在像默认构造函数一样的创建者):抽象类型需要映射到具体类型,具有自定义反序列化器,或者在[来源:(PushbackInputStream);行:3,列:5](通过引用链:com.beo.services.myImportService.rest.domain.dto.metadata.ParameterDto("files"→java.util.ArrayList [0])有根本原因

我能知道如何从接口创建这样一个数组列表并使这两个端点运行吗?还是有别的解决办法?

问题在于ParameterDto1和ParameterDto2。Jackson库需要一个默认的、无参数的构造函数,或者一个带@JsonProperty("field_name")注释参数的构造函数,否则它不能转换你的消息。

解决方案:

为ParameterDto1和ParameterDto2添加一个无参数的构造函数或用@JsonProperty("field_name")注释构造函数参数

我猜这里是因为您没有共享ParameterDto1ParameterDto2的实现-并且由于某种原因,您的接口称为ImportMetaData,其中根据例外,您的解释和其他文件应该是ParameterInterface

问题是getFiles/setFiles被jackson认为是一个属性,它的类型是一个接口,而你没有发送任何类型信息。

一般来说,假设ParameterDto1ParameterDto2使用FileInterface的具体实现,你可以改变你的接口方法getFiles/setFiles,这样他们就使用泛型参数,并在每个实现中设置你正在使用的FileInterface的具体类型,这将允许jackson理解FileInterface的具体类型。

如果ParameterDto1ParameterDto2没有使用FileInterface的具体实现,你应该添加@JsonTypeInfo@JsonSubTypes(参见https://www.baeldung.com/jackson-annotations第5节了解更多信息)-注意,调用api的客户端也应该在json类型字段

中指定实际类型

建议实施

public interface ParameterInterface {
@JsonIgnore
public List<FileInterface> getParameters() default { return null;}
.....
}
public class ParameterDto1 implements ParameterInterface {
private List<FileImpl1> files;
public List<FileImpl1> getFiles(){return files;}
public void setFiles(List<FileImpl1> files){this.files=files;}
....
}

public class ParameterDto2 implements ParameterInterface {
private List<FileImpl2> files;
public List<FileImpl2> getFiles(){return files;}
public void setFiles(List<FileImpl2> files){this.files=files;}
...
}

public class FileImpl1 implements FileInterface{
...
}
public class FileImpl2 implements FileInterface{
...
}

最新更新