0

I wrote a controller for receiving a post request that posts json however when i try to access the object fields it returns null. The code for the Controller is below

package com.example;

import com.example.Services.ZesaServices;
import com.example.models.Zesa.ZesaRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class MoneyResource {

@RequestMapping("/services")
public String getServices(){
    return "We do everything";
}

@PostMapping(value="/zesa")
public String payZesa(@RequestBody ZesaRequest newZesaRequest){

    Logger log = LoggerFactory.getLogger(YomoneyResource.class);
    log.info("Json Object parsed works eg: "+newZesaRequest.getMeterNumber());


    return newZesaRequest.getMeterNumber().toString();
  }
}

And the ZesaRequest Object is as follows

package com.example.models.Zesa;

public class ZesaRequest {
private Double Amount;
private String MeterNumber;
private String PaymentAccountNumber;
private String PaymentAccountDetails;
private int PaymentMethod;
private String MobileNumber;
private String AgentAccountDetails;
private int TransactionType;

public ZesaRequest() {
}


public ZesaRequest(Double amount, String meterNumber, String paymentAccountNumber, String paymentAccountDetails,
                   int paymentMethod, String mobileNumber, String agentAccountDetails, int transactionType) {
    this.Amount = amount;
    this.MeterNumber = meterNumber;
    this.PaymentAccountNumber = paymentAccountNumber;
    this.PaymentAccountDetails = paymentAccountDetails;
    this.PaymentMethod = paymentMethod;
    this.MobileNumber = mobileNumber;
    this.AgentAccountDetails = agentAccountDetails;
    this.TransactionType = transactionType;
}


public String getPaymentAccountDetails() {
    return PaymentAccountDetails;
}

public void setPaymentAccountDetails(String paymentAccountDetails) {
    PaymentAccountDetails = paymentAccountDetails;
}

public String getMobileNumber() {
    return MobileNumber;
}

public void setMobileNumber(String mobileNumber) {
    MobileNumber = mobileNumber;
}


public Double getAmount() {
    return Amount;
}

public void setAmount(Double amount) {
    Amount = amount;
}

public String getMeterNumber() {
    return MeterNumber;
}

public void setMeterNumber(String meterNumber) {
    MeterNumber = meterNumber;
}

public String getPaymentAccountNumber() {
    return PaymentAccountNumber;
}

public void setPaymentAccountNumber(String paymentAccountNumber) {
    PaymentAccountNumber = paymentAccountNumber;
}

public int getPaymentMethod() {
    return PaymentMethod;
}

public void setPaymentMethod(int paymentMethod) {
    PaymentMethod = paymentMethod;
}

public String getAgentAccountDetails() {
    return AgentAccountDetails;
}

public void setAgentAccountDetails(String agentAccountDetails) {
    AgentAccountDetails = agentAccountDetails;
}

public int getTransactionType() {
    return TransactionType;
}

public void setTransactionType(int transactionType) {
    TransactionType = transactionType;
}
}

My code is printing null When I send the request below

{
   "AgentAccountDetails":"example:123",
   "MeterNumber":"1110-52-8867",
   "PaymentMethod":1,
   "Amount":10.50,
   "MobileNumber":"0123456789",
   "TransactionType":1,
   "PaymentAccountNumber":"0123456789",
   "PaymentAccountDetails":"null"
}

When I run it it returns an empty String. I am not sure where the problem is I have looked into other examples and they followed a similar pattern and I ran their code and it worked as expected but mine seems to not be converting the json body into the Java object.

OrangeDog
  • 36,653
  • 12
  • 122
  • 207

2 Answers2

3

You can solve this by using the @JsonProperty annotation above the fields like this:

...
@JsonPropety(value = "Amount")
private Double amount;
...

Or you can rename your properties to start with lowercase letter (both in the VM and in the incoming json), as @OrangeDog suggested in the comments.

NiVeR
  • 9,644
  • 4
  • 30
  • 35
  • This is the wrong approach. You now have Jackson making direct access to private fields, and a bunch of pointless getters and setters for an unused property. – OrangeDog Oct 18 '18 at 12:11
  • I’ve renamed the fields so the bean properties actually work. I’ve also explained what’s going on, and covered the other null issue in the code. – OrangeDog Oct 18 '18 at 12:54
2

Your class defines a property called meterNumber, but your JSON object says MeterNumber instead.

If you must have MeterNumber in your JSON you will need to add @JsonProperty annotations.

It is against both Java and JSON naming conventions to start field names with a capital letter.

As an aside, you can avoid all the boilerplate by using Lombok:

@Data
public class ZesaRequest {
    @JsonProperty("Amount")
    private Double amount;

    @JsonProperty("MeterNumber")
    private String meterNumber;

    @JsonProperty("PaymentAccountNumber")
    private String paymentAccountNumber;

    @JsonProperty("PaymentAccountDetails")
    private String paymentAccountDetails;

    @JsonProperty("PaymentMethod")
    private int paymentMethod;

    @JsonProperty("MobileNumber")
    private String mobileNumber;

    @JsonProperty("AgentAccountDetails")
    private String agentAccountDetails;

    @JsonProperty("TransactionType")
    private int transactionType;
}

You also probably don't want "PaymentAccountDetails":"null". It should be either "PaymentAccountDetails":null, or omitted entirely.

OrangeDog
  • 36,653
  • 12
  • 122
  • 207
  • To be clear, you don't need the `@JsonProperty` annotations if you change the JSON to use the same case as the (correctly-cased) fields. – OrangeDog Oct 18 '18 at 11:29
  • @KudzaiMutsvairo "this worked" - then you should upvote and accept this answer. – OrangeDog Oct 18 '18 at 12:12