0

I'm likely missing something simple or don't understand what I'm trying to do.

I've got a RESTful interface, I'm attempting to do a post. Using POSTMAN the following JSON works correctly.

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

My controller looks like

@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);
    }
}

But when I try to use a compound JSON object

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

I don't even get to the controller, I get an error ...

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;
}

Can someone point me in the right direction?

1
  • Thanks ... but not the answer either. It validates, likek my version does, but still get the error. I think the issue is my HATEOAS implementation. Time to drop back 10 and punt. Commented Dec 7, 2014 at 18:27

3 Answers 3

1

I think your json should be like this -

{
    "username": "uname",
    "password": "pass",
    "role": "role",
    "phones": [
        "phone": {
            "areacode": "303",
            "prefix": "555",
            "body": "6666",
            "ext": "12345"
        }
    ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

Show us you AccountResource class and Phone class
Thanks -- that didn't help, same bad syntax error. I've set break points all over the place and haven't found where it's hitting my code if it gets there. I've added my AccountResource and Phones classes to the original question.
BTW, that was correct syntax ... I had another issue which made me believe it was incorrect. Thx
0

In such cases it's easy to write a Junit and use Jackson ObjectMapper (it should be already in you class path).

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);

    }

}

So based on mimic of your classes it should be similar to the text below:

{
    "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
        }
    ]
}

1 Comment

Thank you! That was the answer! I need more tests -- and should become more of a fan of TDD.
0

I think you should try using array of Phone instead of List in your AccountResource bean

Phone[] phones;

And the json should be like

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

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.