【问题标题】:Jackson JSON - "no single-String constructor/factory method" error on unmarshalJackson JSON - 解组时出现“无单字符串构造函数/工厂方法”错误
【发布时间】:2014-10-01 06:35:52
【问题描述】:

最简单的情况就是给我带来麻烦。我第一次遇到它。我能够解组稍微复杂一点的 json,但这个简单的失败了。

什么会导致这种情况,为什么杰克逊只有一个字符串有问题?

一个包含用户角色名称的简单类。

public class UpdateUserRole {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }    
}

控制器内部

public void updateUserRole(@PathVariable Long id, @RequestBody UpdateUserRoleReq req) {
}

Jackson 看到这个就抛出这个错误

org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not instantiate value of type [simple type, class com.mycompany.UpdateUserRoleReq] from String value ('{"name":"admin_1407445357682"}'); no single-String constructor/factory method; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.mycompany.UpdateUserRoleReq] from String value ('{"name":"admin_1407445357682"}'); no single-String constructor/factory method
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:228)
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.read(MappingJackson2HttpMessageConverter.java:220)
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:183)
    at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:98)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:79)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:874)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:649)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:110)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextFilterConfiguration$1.doFilterInternal(EndpointWebMvcAutoConfiguration.java:257)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)

【问题讨论】:

  • 你能发布你的 JSON 字符串吗?
  • 只是为了确定,你能确认一下你说UpdateUserRole的意思是UpdateUserRoleReq吗?
  • @Alexey - 不知道如何共享 json。它通过集成测试运行。除非我做一个 wireshark 什么的,否则它是一个 http 请求。
  • @ccjmne - 是的。它设置为正确使用 UpdateUserRoleReq。如果我像这样在 UpdateUserRoleReq 中创建一个构造函数:UpdateUserRoleReq(String name),它就会开始工作。不知道为什么。我按照错误消息中的说明进行操作。它想要一个用于单个字符串的构造函数/工厂方法。
  • @sat 听起来您是从 json 字符串节点而不是对象节点构造对象。

标签: java json spring-mvc jackson


【解决方案1】:

通过完全遵守错误消息,我能够解决一个非常相似的问题。

我在您的单字符串构造函数中添加了等效项。

public class UpdateUserRole {

  private String name;

  public UpdateUserRole() {}

  public UpdateUserRole(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }    
}

【讨论】:

  • 是的,以上是正确的,我也遇到过同样的问题,当我创建单字符串构造函数时它起作用了。
【解决方案2】:

我的情况。我正在发送双重转义的 JSON 字符串,例如"{\"name\":\"abc\", \"age\":21}" 和我的 String 构造函数只接收完整的 JSON 字符串。其他属性(年龄)根本没有更新。一旦我将输入更改为 {"name":"abc", "age":21}。 Jackson 能够自动将 JSON 输入解析为对象。

【讨论】:

    【解决方案3】:

    您必须添加包含单个参数的构造方法。 试试看吧。

    【讨论】:

    • 你没看到其他答案吗?
    【解决方案4】:

    我关注了 OAuth 的 Jira 教程 (https://developer.atlassian.com/server/jira/platform/oauth/)。就我而言,我使用 dto 到 GSON lib 的 json 转换,但是我无法让它工作。我稍后会提供源代码,但为了快速解决,请参阅:https://stackoverflow.com/a/59981597/1551368

    【讨论】:

      猜你喜欢
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      • 2018-02-12
      • 2023-03-16
      • 2018-02-02
      • 2014-07-20
      • 2018-01-21
      • 1970-01-01
      相关资源
      最近更新 更多