无法解决databind.exc.InvalidDefinitionException:无法构造实例问题



我的spring启动服务器上的post端点有问题。我有我想发送的模型:

public class UpdateFiles {
private final String name;
private final ArrayList<File> fileList;
public UpdateFiles(String name, ArrayList<File> fileList) {
this.name = name;
this.fileList = fileList;
}
public String getName() {
return name;
}
public ArrayList<File> getFileList() {
return fileList;
}
}

下面是一个简单的休息控制器,当我想要返回与我收到的相同的身体时。


@RestController
public class RestClientController {
@RequestMapping(value = "/greeting", produces = MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.POST)
public HttpEntity<String> greeting(@RequestHeader(name = "Content-Type", required = true) String contentType,
@RequestHeader(name = "Accept", required = true) String accept,
@RequestBody UpdateFiles updateFilesRQ) throws IOException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
ObjectMapper objectMapper = new ObjectMapper();
String requestString = objectMapper.writeValueAsString(updateFilesRQ);
return new ResponseEntity<>(
requestString, httpHeaders, HttpStatus.OK);
}
}

在这里,我有一个简单的测试来调用post-action。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {RestTemplateConfig.class, HttpClientConfig.class})
public class TestApplication {
@Autowired
RestTemplate restTemplate;
@Test
public void getEmployees() throws IOException {
final String uri = "http://localhost:8888/greeting";
ArrayList<com.licencjat.filesynchronizer.client.model.File> listOfFiles = new ArrayList<>();
listOfFiles.add(new com.licencjat.filesynchronizer.client.model.File("src/a", "01.01.01"));
listOfFiles.add(new com.licencjat.filesynchronizer.client.model.File("src/b", "02.02.02"));
UpdateFiles updateFiles = new UpdateFiles("yellow", listOfFiles);
ObjectMapper objectMapper = new ObjectMapper();
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
String requestString = objectMapper.writeValueAsString(updateFiles);
HttpEntity<String> request = new HttpEntity<>(requestString, httpHeaders);
ResponseEntity<UpdateFiles> personResultAsJsonStr = restTemplate.postForEntity(uri, request, UpdateFiles.class);
System.out.println(personResultAsJsonStr);
}
}

在呼叫postForEntity后,我收到:

org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.licencjat.filesynchronizer.client.model.UpdateFiles]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.licencjat.filesynchronizer.client.model.UpdateFiles` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:246)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:228)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:104)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:998)
at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:981)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:741)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:674)
at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:449)
at com.licencjat.filesynchronizer.client.TestApplication.getEmployees(TestApplication.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.licencjat.filesynchronizer.client.model.UpdateFiles` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (PushbackInputStream); line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1589)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1055)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3258)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:240)
... 38 more

我知道这可能是一个简单的问题,但我已经挣扎了很长一段时间。我试着找到答案,但似乎没有任何话题与我的问题有关。我在代码中做了不正确的事情?你知道我为什么会收到这样的错误吗?

可以有多种解决方案来解决这个问题。

  1. 如果您的类是可变的:定义一个默认构造函数并创建setter方法
public class UpdateFiles {
private final String name;
private final ArrayList<File> fileList;
// default constructor
public UpdateFiles() {
}
// AllArgsConstructor, getters and setters
}
  1. 如果您的类是不可变的:用@JsonCreator注释构造函数,用@JsonProperty注释字段:
public class UpdateFiles {
private final String name;
private final ArrayList<File> fileList;
@JsonCreator
public UpdateFiles(@JsonProperty('name') String name, @JsonProperty('fileList') ArrayList<File> fileList) {
this.name = name;
this.fileList = fileList;
}
...

(这里需要注意的是:虽然UpdateFiles类中没有setter,但这并不意味着它是不可变的。fileList是一个ArrayList,我们有一个getter,这意味着它可以从外部突变。(

最新更新