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
.
好像是必须的
我不知道这是正确的解决方案还是只是一种解决方法,但它确实有效。
我已经使用 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
.
我不知道这是正确的解决方案还是只是一种解决方法,但它确实有效。