无法读取HTTP消息:org.springframework.http.converter.HttpMessageNotReadableException:JSON解析错误:无法构造实例

时间:2018-03-23 11:19:36

标签: spring-boot jersey spring-restcontroller jersey-client rest-client

我使用JSF编写了java web应用程序(前端)。

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

后端是使用jax-rs的{​​{1}} RESTful Web服务。

在前端我有spring boot个方法(使用GET),这些方法没有任何问题。

当我使用Jersey-client软件发布JSON数据时,它也没有任何问题,但是当我使用前端应用程序(使用Jersey客户端)发送我的Postman对象时,它给了我这个错误:

Customer

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

    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

前端 pom.xml

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>

1 个答案:

答案 0 :(得分:0)

我可以让你的例子工作,直到我添加这个库

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

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

  

com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造com.example.demo.model.Customer的实例(尽管至少存在一个Creator): no String-argument constructor / factory 反序列化方法from String value('{“id”:0,“name”:“abc”,“city”:“def”,“contactNum”:334455}')

所以我假设错误是由这个库创建的。我也尝试了1.4,这是最后一个版本,它也会中断。

在最少的代码上为我工作的解决方案我再现了您的问题。你可以尝试一下。

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

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后端尝试将JSON字符串转换为Customer时,会调用此方法。如果您想使用genson,似乎有必要。

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