无法读取文档:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例
Posted
技术标签:
【中文标题】无法读取文档:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例【英文标题】:Could not read document: Can not deserialize instance of java.lang.String out of START_OBJECT token 【发布时间】:2022-01-02 17:27:46 【问题描述】:我正在通过 POSTMAN 对我的 POST 方法进行调用,该方法应该返回一个 String 类型,但是当我进行调用时,它给了我错误 "Could not read document: Can not deserialize instance of java. lang.String out of START_OBJECT token"
。为什么会这样?
实体中的属性:
@Column(name = "CIF_NIF")
@JsonView(Views.Buscador.class)
@JsonProperty("cifNif")
private String cifNif;
RestController:
@PostMapping(value = "/recuperaNombreLegalCliente")
public String recuperaNombreLegalCliente(@RequestBody String cifNif)
return contratoService.getNombreLegalCliente(cifNif);
存储库
@Query(value="SELECT c.nombreSociedadPersona FROM Contrato c WHERE c.cifNif= ?1")
public String getNombreLegalCliente(String cifNif);
我在进行方法调用时的输入:
"cifNif": "E85882355"
现在编辑 1 堆栈跟踪错误(@sigur 回答后)
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [Contrato [id=null, tipoSolicitud=null, tipoContratoDiscriminator=null, cifNif=E85882355] did not match expected type [java.lang.String (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [Contrato [id=null, tipoSolicitud=null, tipoContratoDiscriminator=null, cifNif=E85882355] did not match expected type [java.lang.String (n/a)]
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy174.getNombreLegalCliente(Unknown Source)
at com.xxx.xxxx.servicio.ContratoService.getNombreLegalCliente(ContratoService.java:24)
at com.xxxx.xxxx.acciones.rest.SolicitudAutorizacionPreciosRestController.recuperaNombreLegalCliente(SolicitudAutorizacionPreciosRestController.java:56)
【问题讨论】:
更新了答案,但如果您需要更多支持,您应该打开另一个问题,因为原来的问题看起来已经解决了@okjfokjrf 【参考方案1】:@RequestBody
的映射器正在尝试读取您的输入并将其数据转换为请求的类型/对象。
在您的情况下,它正在尝试将您的 json 文本转换为 String
。默认情况下不允许这样做,您应该更改反映 json 输入模型的 POJO 类中的输入。
将public String recuperaNombreLegalCliente(@RequestBody String cifNif)
更改为String recuperaNombreLegalCliente(@RequestBody Cliente cifNif)
,其中Cliente
是这样的类:
class Cliente
private String cifNif;
public void setCifNif(String cifNif) this.cifNif = cifNif;
public String getCifNif() return cifNif;
案例编辑 1 -> org.springframework.dao.InvalidDataAccessApiUsageException
该错误与存储库中的查询生成有关。当您将String
更改为Cliente
类时,您还需要为您的存储库或查询提供足够的调用;因为现在您正尝试将 Cliente
实例作为参数映射到字符串字段/列的查询中。
如果您想使用Cliente
,您需要在查询中使用cifNif
属性。示例:
@Query(value="SELECT c.nombreSociedadPersona FROM Contrato c WHERE c.cifNif=cliente.cifNif")
public String getNombreLegalCliente(@Param("cliente") Cliente cliente);
...
或者,如果您想使用字符串值,只需从控制器调用存储库函数:
String recuperaNombreLegalCliente(@RequestBody Cliente cifNif)
repository.getNombreLegalCliente(cifNif.getCifNif());
...
存储库方法在哪里:
@Query(value="SELECT c.nombreSociedadPersona FROM Contrato c WHERE c.cifNif= ?1")
public String getNombreLegalCliente(String cifNif);
...
【讨论】:
那么我应该输入类似 "cliente" : "cifNif" : "xxxx" 的内容? Request 将是相同的,但是当映射器将其数据反映到您的模型中时,它使用 getter 和 setter POJO 样式。因此,当请求 "cifNif": "E85882355" 将“进入”您的控制器时,映射器和 @RequestBody 将转换为 Cliente。他们从您的 json 中提取字段(在您的情况下只有 cifNif),并将它们找到 Cliente 类(通过“pojo setter”样式 -> setCiNif)。 在相同的输入和您的更改下无法为我工作原因:java.lang.IllegalArgumentException:参数值 [Contrato [id=null,tipoSolicitud=null,tipoContratoDiscriminator=null,cifNif= E85882355] 您应该为该案例添加堆栈跟踪,因为我怀疑错误不再是“无法读取文档:无法将 java.lang.String 实例反序列化出 START_OBJECT 令牌”所以它已经改变了,因为现在看起来你比以前更进一步。 是的,这不是同一个错误,我在问题中添加了轨迹跟踪错误以上是关于无法读取文档:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例的主要内容,如果未能解决你的问题,请参考以下文章
JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 `byte[]` 的实例
无法从 START_OBJECT 令牌中反序列化 `java.lang.Boolean` 的实例
无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例
JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例
com.fasterxml.jackson.databind.exc.MismatchedInputException:无法从 START_OBJECT 令牌中反序列化 `java.util.Arra
无法从 START_OBJECT 令牌中反序列化 `java.lang.Long` 的实例;在 Spring Boot 帖子上