Java REST服务接受POJO,但字段始终为null

时间:2016-03-08 02:35:10

标签: java json rest

我有一个使用POJO的REST服务。这是方法:

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

这是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 + '}';
    }
}

当我用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

我得到返回值并看到print语句,但TerminationCommand的字段都是null。我得到一个实例化的对象,但是我发送的JSON没有填充到该对象上。

为什么???

这是输出:

  
    

信息:正在运行终止:TerminateActorCommand {actorEid = null,terminatorEid = null,reason = null,effectiveTerminationDate = null}

  

2 个答案:

答案 0 :(得分:2)

我已经浏览了您问题中包含的所有代码,我有一些建议:

TerminateActorCommand POJO中,将@JsonProperty注释添加到与您的JSON属性匹配的成员中(存在属性访问器方法,但缺少mutator方法可能会让Jackson感到困惑):


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

如果添加@JsonProperty无法解决您的问题,请检查当前在TerminateActorCommand类中定义的无参数构造函数。当你使用Jackson @JsonCreator注释时,没有必要定义一个无参数的构造函数,但如果杰克逊在反序列化期间无法找到一个好的匹配,它将回退到使用一个无参数的构造函数。我的猜测是no-arg构造函数是当前在JSON反序列化期间调用的(因此null属性值),所以我建议删除该构造函数,或者,如果需要(可能在其他部分)你的代码),在no-arg构造函数中添加System.out.println,这样你就可以确定当Jackson执行JSON反序列化时是否正在调用该构造函数。

cURL命令-d有效负载规范中的第一个和第二个属性之间也存在不必要的空间,这不应该导致问题,但删除该空间会将其排除在外问题

答案 1 :(得分:2)

我认为未设置属性,因为您的字段/设置器未标记为@JsonProperty。即使您在参数化构造函数中将它们标记为json属性,使用注释标记这些字段或setter也应该有帮助,因为您的库/框架可能正在使用no-arg构造函数来实例化对象,然后在创建的对象上懒惰地设置属性。