简体   繁体   中英

Java REST service accepts POJO, but fields are always null

I have a REST service that uses a POJO. Here is the method:

@POST
@Path("terminate")
@Produces({"application/xml", "application/json"})
@Consumes({"application/xml", "application/json"})
public TerminateActorCommand terminateActor(TerminateActorCommand cmd) {
    System.out.println("Running terminate: " + cmd);
    Query query = em.createNamedQuery("Actor.terminate");
    query.setParameter("eid", cmd.getActorEid());
    query.executeUpdate();
    return cmd;
}

Here is the POJO

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author mike
 */
@XmlRootElement
public class TerminateActorCommand {

    String actorEid;
    String terminatorEid;
    String reason;
    Date effectiveTerminationDate;

    public TerminateActorCommand() {
    }

    @JsonCreator
    public TerminateActorCommand(@JsonProperty("actorEid") String actorEid, @JsonProperty("terminatorEid") String terminatorEid,
            @JsonProperty("reason") String reason) { //, @JsonProperty("effectiveTerminationDate") Date effectiveTerminationDate) {
        this.actorEid = actorEid;
        this.terminatorEid = terminatorEid;
        this.reason = reason;
        //this.effectiveTerminationDate = effectiveTerminationDate;
    }

    public CommandType getCommandType() {
        return CommandType.TERMINATE_ACTOR;
    }

    public String getActorEid() {
        return actorEid;
    }

    public String getTerminatorEid() {
        return terminatorEid;
    }

    public String getReason() {
        return reason;
    }

    public Date getEffectiveTerminationDate() {
        return effectiveTerminationDate;
    }

    @Override
    public String toString() {
        return "TerminateActorCommand{" + "actorEid=" + actorEid + ", terminatorEid=" + terminatorEid + ", reason=" + reason + ", effectiveTerminationDate=" + effectiveTerminationDate + '}';
    }
}

When I call this with CURL:

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d '{"actorEid":"mb995a", "terminatorEid":"mb995a","reason":"testing"}' http://127.0.0.1:8080/actor-service/webresources/net.mikeski.auth.entities.actors/terminate

I get the return value and see the print statement,but the TerminationCommand's fields are all null. I get an instantiated object but the JSON I'm sending does not get populated on the object.

Why???

Here's the output:

Info: Running terminate: TerminateActorCommand{actorEid=null, terminatorEid=null, reason=null, effectiveTerminationDate=null}

I've walked through all of the code included in your question and I have some suggestions:

Within the TerminateActorCommand POJO, add the @JsonProperty annotation to the members that match your JSON properties (the presence of the property accessor methods but absence of mutator methods may be confusing Jackson):


@JsonProperty String actorEid;
@JsonProperty String terminatorEid;
@JsonProperty String reason;

If adding the @JsonProperty doesn't resolve your issue, examine the no-arg constructor that is currently defined within your TerminateActorCommand class. When you use the Jackson @JsonCreator annotation, there is no need to define a no-arg constructor, but if Jackson is unable to find a good match during deserialization, it will fallback to using a no-arg constructor. My guess is that the no-arg constructor is what is currently being called during JSON deserialization (thus the null property values), so I would suggest either removing that constructor or, if it is needed (maybe in other parts of your code), add a System.out.println within the no-arg constructor, so you will know for certain if that constructor is being called when Jackson performs the JSON deserialization.

There is also an unnecessary space between the first and second properties in your cURL command -d payload specification and that shouldn't cause a problem, but removing that space will rule that out as a possible problem.

I think the properties are not set because your fields/setters are not marked as @JsonProperty . Even though you have marked those as json properties in the parameterized constructor, marking these fields or setters with annotations should help because your library/framework might be using no-arg constructor to instantiate the object and then set the properties lazily on the created object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM