Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance

Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance

我已经使用 JSF 编写了 java 网络应用程序(前端)。

我使用Jersey RESTful Web Services framework版本1.8向后端发送数据。

后端是 jax-rs RESTful 使用 spring boot 的 Web 服务。

在前端我有 GET 方法(使用 Jersey-client),这些方法没有任何问题。

当我使用 post JSON 数据使用 Postman 软件时,它也可以正常工作,但是当我使用前端应用程序发送我的 Customer 对象时(使用 Jersey 客户端)它给了我这个错误:

    WARN 2156 --- [io-8089-exec-53] .w.s.m.s.DefaultHandlerExceptionResolver :Failed
to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: 
JSON parse error: Cannot construct instance of `com.example.demo.model.Customer` 
(although at least one Creator exists): no String-argument constructor/factory
 method to deserialize from String value 
 ('{"id":0,"name":"abc","city":"def","contactNum":334455}'); nested exception is 
 com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct 
 instance of `com.example.demo.model.Customer` (although at least one Creator exists):
 no String-argument constructor/factory method to deserialize from String value 
 ('{"id":0,"name":"abc","city":"def","contactNum":334455}')

这是我发送数据的前端方法。

public static void saveCustomer(Customer customer) throws IOException {

    Gson gson = new Gson();
    String custJson = gson.toJson(customer);
    System.out.println(custJson);

    Client create = Client.create();
    WebResource webResorce = create.resource("http://localhost:8089/springHibernate/addCus");
    ClientResponse response = webResorce.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(ClientResponse.class, custJson);

    if (response.getStatus() != 201) {
        response.close();
        throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
    }

    System.out.println("Output from Server .... \n");
    String output = response.getEntity(String.class);
    System.out.println(output);
    response.close();

}

这里是后台服务

@RequestMapping(value = "/addCus", method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
public Customer process( @RequestBody Customer cus) throws Exception {

    Customer saveCus = customerSrvice.saveCus(cus);
    return saveCus;
}

编辑 Customer class

package com.example.demo.model; 

@Entity 
@Table(name="customer")
public class Customer implements Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO ) 
    private int id;

    @Column(name = "name") 
    private String name; 

    @Column(name = "city") 
    private String city; 

    @Column(name = "contactNum") 
    private int contactNum;


    public Customer() { } 
    public Customer(String name, String city, int contactNum) { /**/ } 
    public Customer(int id, String name, String city, int contactNum) { /**/ } 

}

前端pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.keylesson.jsf22</groupId>
<artifactId>PrimeFaces-Hello-World-Example</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>PrimeFaces-Hello-World-Example</name>
<url>http://maven.apache.org</url>

<dependencies>

    <!-- JSF2.2 dependency -->
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.2.8</version>
    </dependency>
    <dependency>
        <groupId>com.sun.faces</groupId>
        <artifactId>jsf-impl</artifactId>
        <version>2.2.8</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2.1-b03</version>
    </dependency>

    <!-- PrimeFaces dependency -->
    <dependency>
        <groupId>org.primefaces</groupId>
        <artifactId>primefaces</artifactId>
        <version>6.2</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.9</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.8</version>
    </dependency>
    <!-- this dependancy help to map json to java object dependency -->
    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>0.99</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.2</version>
        <type>jar</type>
    </dependency>
</dependencies>

后端pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.demo</groupId>
    <artifactId>springHibernate</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>springHibernate</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
                <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

在我添加这个库之前我可以让你的例子工作

<dependency>
    <groupId>com.owlike</groupId>
    <artifactId>genson</artifactId>
    <version>0.99</version>
</dependency>

然后我得到了和你一样的错误:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.example.demo.model.Customer (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"id":0,"name":"abc","city":"def","contactNum":334455}')

所以我假设错误是由这个库造成的。我也试过1.4,这是最后一个版本,它也坏了。

用最少的代码为我工作的解决方案 我在其中重现了您的问题。你可以试试看。

我向 Customer 添加了一个 String-argument 构造函数(这就是错误所抱怨的):

public Customer(String json) throws IOException {
    Customer c = new ObjectMapper().readValue(json, Customer.class);
    this.id = c.id;
    this.name = c.name;
    this.city = c.city;
    this.contactNum = c.contactNum;
}

Spring back-end 尝试将 JSON 字符串转换为 Customer 时调用此方法。如果要用genson.

好像是必须的

我不知道这是正确的解决方案还是只是一种解决方法,但它确实有效。