2016-03-08 21 views
0

我有一個使用POJO的REST服務。下面是方法:Java REST服務接受POJO,但字段始終爲空

@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 -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的字段全爲空。我得到一個實例化的對象,但我發送的JSON沒有被填充到對象上。

爲什麼?

下面是輸出:

信息:運行終止:TerminateActorCommand {actorEid = NULL,terminatorEid = NULL,原因= NULL,effectiveTerminationDate = NULL}

回答

2

我已經遍歷你問題中包含的所有代碼,我有一些建議:

TerminateActorCommand POJO,a DD的@JsonProperty註釋,以配合您的JSON屬性的成員(存在的mutator方法的屬性訪問方法,但沒有可能會產生混淆傑克遜):


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

如果添加@JsonProperty不能解決你的問題,檢查當前在您的TerminateActorCommand類中定義的無參數構造函數。當您使用Jackson註釋時,不需要定義無參數構造函數,但是如果Jackson在反序列化過程中找不到合適的匹配項,它將回退到使用無參數構造函數。我的猜測是,無參數構造函數是當前在JSON反序列化過程中調用的內容(因此屬性值爲null),所以我會建議刪除該構造函數,或者如果需要(可能在代碼的其他部分),在無參數構造函數中添加一個System.out.println,因此當Jackson執行JSON反序列化時,您將確定是否正在調用該構造函數。

還有在cURL命令-d有效載荷規範的第一和第二性能之間的不必要的空間,並且應該不會造成問題,但去除空間將排除這種可能性作爲一個可能的問題。

+0

嗯,這很有趣。按照預期,我添加了註釋,沒有任何區別。我添加了setters,並且使用了無參數構造函數。當我添加一個@JsonCreator構造函數像我的原始代碼並擺脫其他構造函數時,我得到'MessageBodyReader not found for media type = application/json'。我希望這個對象是不可變的。我怎麼做? – mikeb

+0

構造函數上的'@ JsonCreator'註釋,沒有setter方法,是保持不變性的正確方法。你使用什麼版本的Jackson('jackson-core','jackson-annotations'和'jackson-databind')?你的項目是否包含獨立的Jackson配置文件? –

+0

這是正確的,我沒有**需要擺脫默認的構造函數,只是創建了一個@JsonCreator標記的構造函數與我想設置的字段,它的工作原理。 – mikeb

2

我認爲這些屬性未設置,因爲您的字段/設置者未被標記爲@JsonProperty。儘管在參數化構造函數中將這些屬性標記爲json屬性,但使用註釋標記這些字段或設置程序應該有所幫助,因爲您的庫/框架可能使用無參數構造函數來實例化對象,然後在創建的對象上懶洋洋地設置屬性。

+0

我希望該對象是不可變的。帶註釋的屬性/設置器可以工作,但它不是不可變的。 – mikeb

+0

@mikeb我同意不變性。就像在黑暗中拍攝,你可以嘗試添加編譯器標誌javac -d:vars,看看是否有效。如果您使用的是Java 8,請嘗試使用javac -parameters – Atul