JSON POST请求在服务器端获得异常

时间:2017-08-05 05:00:27

标签: json spring spring-data-jpa

我正在尝试设置基于Spring JPA的REST API。我正在使用com.fasterxml.jackson.core来处理JSON请求和响应。在我的控制器中,我有一个帖子请求,我基本上创建操作。以下是执行此操作的代码:

@Autowired
    CustomerRepository repository;

    @RequestMapping(value = "/postcustomer", method = RequestMethod.POST)
    public void postCustomer(@RequestBody Customer customer) {

        repository.save(new Customer(customer.getFirstName(), customer.getLastName()));
    }

所以你可以看到,我需要在我的身体中发送一个类型为客户的对象。我正在尝试使用邮递员来测试它,以下是我发送给服务器的JSON:

{
    "status": "Done",
    "data": [
        "Customer" : {
            "firstname" : "test",
            "lastname" : "123"
        }
    ]
}

我发错的请求了吗?因为我一直在说例外:

{
"timestamp":1501908753094,
"status":400,
"error":"Bad Request",
"exception":"org.springframework.http.converter.HttpMessageNotReadableException",
"message":"JSON parse error: Unexpected character (':' (code 58)): was expecting comma to separate Array entries; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character (':' (code 58)): was expecting comma to separate Array entries\n at [Source: java.io.PushbackInputStream@6f57265c; line: 4, column: 18]",
"path":"/uzmi/postcustomer"
}

更新 根据答案改变我的解决方案后,我有这个: CustomerCOntroller.java

import com.test.message.Response;
import com.test.repo.CustomerRepository;    
@RestController
public class CustomerController {    
    @Autowired
    CustomerRepository repository;    
    @RequestMapping(value = "/postcustomer", method = RequestMethod.POST)
    public void postCustomer(@RequestBody Response request) {
        request.getData().forEach((data) -> {
            repository.save(data.getCustomer());
        });
    }    
}

Response.java

package com.test.message;    
import java.io.Serializable;
import java.util.List;    
public class Response implements Serializable {    
    private String status;    
    private List<Data> data;    
    public Response(String status, List<Data> data) {
        this.status = status;
        this.data = data;
    }    
    public Response() {
    }    
    public String getStatus() {
        return status;
    }    
    public void setStatus(String status) {
        this.status = status;
    }    
    public List<Data> getData() {
        return data;
    }    
    public void setData(List<Data> data) {
        this.data = data;
    }    
}

Data.java

package com.test.message;    
import com.fasterxml.jackson.annotation.JsonProperty;
import com.test.model.Customer;    
public class Data {    
    @JsonProperty("Customer")
    private Customer customer;    
    public Customer getCustomer() {
        return customer;
    }    
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    public Data() {
    }
    public Data(Customer customer) {
        this.customer = customer;
    }
}

但是现在当我使用以下JSON尝试postcontroller api时:

{
    "status": "Done",
    "data": [ {
        "Customer": {
            "firstname" : "test",
            "lastname" : "123"
        }
    }]
}

我收到以下错误:

{
    "timestamp": 1502014916458,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
    "message": "JSON parse error: Can not construct instance of com.test.message.Response: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.test.message.Response: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)\n at [Source: java.io.PushbackInputStream@157f2538; line: 2, column: 5]",
    "path": "/test/postcustomer"
}

UPDATE2: customer.java

package com.test.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "customer")
public class Customer implements Serializable {
    private static final long serialVersionUID = -3009157732242241606L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    @Column(name = "firstname")
    private String firstName;
    @Column(name = "lastname")
    private String lastName;
    protected Customer() {
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

我出错的任何想法?

2 个答案:

答案 0 :(得分:2)

首先,您给定的json格式不正确。我已经改变了以下格式。

{
    "status": "Done",
    "data": [ {
        "Customer": {
            "firstname" : "test",
            "lastname" : "123"
        }
    }]
}

如果您想接受上述json作为请求正文,则需要再添加两个类并分别更改控制器。

更改了控制器方法

@RequestMapping(value = "/postcustomer", method = RequestMethod.POST)
public void postCustomer(@RequestBody PostCustomerRequest request) {
    for(Data data : request.getData()) {
        repository.save(data.getCustomer());
    }
}

显然,您需要PostCustomerRequestData课程。

PostCustomerRequest类

public class PostCustomerRequest implements Serializable {
    private String status;

    private List<Data> data;

    // Respective constructor, getter and setter methods
}

数据类

public class Data {
    @JsonProperty("Customer")
    private Customer customer;

    // Respective constructor, getter and setter methods
}

然后你可以在json上面发帖。

<强> N.B

在这里,您可以很容易地注意到,Data类在没有包装Customer的情况下没有用处。你可以放弃它。这也最小化了您的json格式。如果您不想使用Data课程,请在List<Customer>内使用PostCustomerRequest。如果是这样,那么json将被最小化为

{
    "status": "Done",
    "data": [ 
        {
            "firstname" : "test",
            "lastname" : "123"
        }
    ]
}

我认为每个人都会建议这种格式。

上次更新

您在json中提供了firstname,但变量名称为firstName。这是不匹配。您可以更改变量名称。最好将@JsonProperty("firstname")添加到firstName变量之上。同样适用于姓氏。它会工作。

还有一件事是,您可以在线将json转换为POJO。有几个,但我使用了JSON Schema to POJO

答案 1 :(得分:0)

你需要将status , data发送到json,你只能将json主体发送到请求中,RequestBody可以将它的属性映射到实体或pojo。你只能将参数和值发送到JSON boby,你可以在下面找到它:

    {
        "firstname" : "test",
        "lastname" : "123"
    }