带有JSON对象的Spring MVC POST

时间:2014-12-07 05:59:06

标签: json spring rest

我可能会遗漏一些简单的事情,或者不理解我想要做的事情。

我有一个RESTful界面,我试图发帖子。使用POSTMAN,以下JSON可以正常工作。

{ 
"username": "uname",
"password": "pass",
"role": "role"
}

我的控制器看起来像

@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<AccountResource> createAccount(@RequestBody AccountResource sentAccount) {
    try {
        Account createdAccount = accountService.createAccount(sentAccount.toAccount());
        AccountResource res = new AccountResourceAssembler().toResource(createdAccount);
        HttpHeaders headers = new HttpHeaders();
        headers.setLocation(URI.create(res.getLink("self").getHref()));
        return new ResponseEntity<AccountResource>(res, headers, HttpStatus.CREATED);
    }
    catch (AccountExistsException exception) {
        throw new ConflictException(exception);
    }
}

但是当我尝试使用复合JSON对象时

{
    "username": "uname",
    "password": "pass",
    "role": "role",
    "phones": {
        "phone": {
            "areacode": "303",
            "prefix": "555",
            "body": "6666",
            "ext": "12345"
        }
    }
}

我甚至没有去控制器,我收到错误......

The request sent by the client was syntactically incorrect.


public class AccountResource extends ResourceSupport {

private String username;
private String password;
private String fname;
private String lname;
private String role;
private List<Phone> phones = new ArrayList<Phone>();

public String getUsername() {
    return username;
}

public String getFname() {
    return fname;
}

public void setFname(String fname) {
    this.fname = fname;
}

public String getLname() {
    return lname;
}

public void setLname(String lname) {
    this.lname = lname;
}

public void setUsername(String username) {
    this.username = username;
}

@JsonIgnore
public String getPassword() {
    return password;
}

@JsonProperty
public void setPassword(String password) {
    this.password = password;
}

public String getRole() {
    return role;
}

public void setRole(String role) {
    this.role = role;
}

public List<Phone> getPhones() {
    return phones;
}

public void setPhones(List<Phone> phones) {
    this.phones = phones;
}

public Account toAccount() {
    Account account = new Account();
    account.setUsername(username);
    account.setFname(fname);
    account.setLname(lname);
    account.setPassword(password);
    account.setRole(role);
    account.setPhones(phones);
    return account;
}

}

@Entity
@Table(name = "phone")
@NamedQueries({
    @NamedQuery(name = "Phone.findPhonesByAreaCode", query = "Select p from Phone p where   p.areaCode=:areaCode")
})

public class Phone {

@Id
@GeneratedValue
private Long id;
private String areaCode;
private String prefix;
private String body;
private String ext;
private String type;

@ManyToOne
private Account account;

public Phone(String areaCode, String prefix, String body, String ext, String type) {
    this.areaCode = areaCode;
    this.prefix = prefix;
    this.body = body;
    this.ext = ext;
    this.type = type;
}

public Phone(String areaCode, String prefix, String body, String type) {
    this.areaCode = areaCode;
    this.prefix = prefix;
    this.body = body;
    this.type = type;
}

public Phone() {
}

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getAreaCode() {
    return areaCode;
}

public void setAreaCode(String areaCode) {
    this.areaCode = areaCode;
}

public String getPrefix() {
    return prefix;
}

public void setPrefix(String prefix) {
    this.prefix = prefix;
}

public String getBody() {
    return body;
}

public void setBody(String body) {
    this.body = body;
}

public String getExt() {
    return ext;
}

public void setExt(String ext) {
    this.ext = ext;
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public Account getAccount() {
    return account;
}

public void setAccount(Account account) {
    this.account = account;
}

有人能指出我正确的方向吗?

3 个答案:

答案 0 :(得分:1)

我认为你的json应该是这样的 -

{
    "username": "uname",
    "password": "pass",
    "role": "role",
    "phones": [
        "phone": {
            "areacode": "303",
            "prefix": "555",
            "body": "6666",
            "ext": "12345"
        }
    ]
}

答案 1 :(得分:0)

在这种情况下,编写Junit并使用Jackson ObjectMapper很容易(它应该已经在你的类路径中)。

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestAcountResource {

    protected ObjectMapper mapper = new ObjectMapper();

    @Test
    public void test() throws JsonProcessingException {
        Phone phone1 = new Phone();
        phone1.setAreaCode("303");
        phone1.setPrefix("555");
        phone1.setBody("6666");
        phone1.setExt("12345");
        Phone phone2 = new Phone();
        phone2.setAreaCode("304");
        phone2.setPrefix("556");
        phone2.setBody("6667");
        phone2.setExt("12346");
        List<Phone> phones = new ArrayList<>();
        phones.add(phone2);
        phones.add(phone1);
        AccountResource ar = new AccountResource();
        ar.setFname("fname");
        ar.setLname("lname");
        ar.setPassword("password");
        ar.setUsername("username");
        ar.setRole("role");
        ar.setPhones(phones);

        String accountAsJson = mapper.writeValueAsString(ar.toAccount());

        System.out.print(accountAsJson);

    }

}

所以基于你的类的模仿它应该类似于下面的文字:

{
    "username" : "username",
    "fname" : "fname",
    "lname" : "lname",
    "password" : "password",
    "role" : "role",
    "phones" : [{
            "id" : null,
            "areaCode" : "304",
            "prefix" : "556",
            "body" : "6667",
            "ext" : "12346",
            "type" : null
        }, {
            "id" : null,
            "areaCode" : "303",
            "prefix" : "555",
            "body" : "6666",
            "ext" : "12345",
            "type" : null
        }
    ]
}

答案 2 :(得分:0)

我认为您应该尝试在AccountResource bean中使用Phone数组而不是List

手机[]手机;

json应该像

 {
"username": "uname",
"password": "pass",
"role": "role",
"phones": {
     {
        "areacode": "303",
        "prefix": "555",
        "body": "6666",
        "ext": "12345"
    }
}

}