2013-07-30 43 views
0

我有一個令人費解的RESTful問題。我使用使用Jersey的REST,它使用POJO映射將Java對象(Bean?)轉換爲JSON。最初這個工作很好,但現在,在嘗試向Bean添加新字段時,它們不會顯示在客戶端收到的JSON中。我會稍後解釋我的意思,但首先讓我展示一些代碼。RESTful POJO - > JSON映射不拾取新字段

控制器代碼在這裏(編輯簡化它......關鍵部位保持):

@Path("study") 
public class StudyQueryController 
{ 
    @Path("/query") 
    @GET 
    @Produces({ MediaType.APPLICATION_JSON }) 
    public List<PatientBean> queryForStudies(
      @QueryParam("keyword") String keyword, 
      @QueryParam("fromDate") String fromDate, 
      @QueryParam("toDate") String toDate, 
      @QueryParam("sites") Set<Integer> sites, 
      @DefaultValue(CLOUD_STYPE) @QueryParam("stypes") Set<Integer> stypes, 
      @DefaultValue("false") @QueryParam("incDeleted") boolean incDeleted) 
    { 
     UserModel user = AuthFilter.requestingUser; 

     try (KHDatabase khdb = new KHDatabase()) 
     { 
       [... code is here that sets up the queries, keys, etc...] 

      CommonQueries.PSSTree tree = CommonQueries.getPatientStudySeriesTree(khdb, keys); 
      List<PatientBean> ret = PatientBean.mapPSSTree(tree); 

      return ret; 
     } 
     catch (SQLException e) 
     { 
      [...throws error here...] 
     } 
    } 
} 

注意列表由PatientBean對象返回。該PatientBean代碼是在這裏:

public class PatientBean { 

    private String patientName; 
    private String patientBleah; 
    private String patientID; 
    private String patientSex; 
    private String patientDOB; 
    private int patientSite; 
    private String siteName; 
    private StudyBean[] studies; 

// public String getPatientName() { 
//  return patientName; 
// } 
    public String getPatientBleah() {  // TEST 
     return patientBleah; 
    } 
    public String getPatientID() { 
     return patientID; 
    } 
    public String getPatientSex() { 
     return patientSex; 
    } 
    public String getPatientDOB() { 
     return patientDOB; 
    } 
    public int getPatientSite() { 
     return patientSite; 
    } 
    public void setSiteName(String newName) { 
     siteName = newName; 
    } 
    public String getSiteName() { 
     return siteName; 
    } 
    public StudyBean[] getStudies() { 
     return studies; 
    } 

    /** Maps a <code>KHPatient</code>, its collection of <code>KHStudy</code>, and the map of 
    * study keys to lists of <code>KHSeries</code> of the studies, to an instance of this class. */ 
    public PatientBean(KHPatient pt, List<KHStudy> sts, Map< String, List<KHSeries> > srs ) 
    { 
     patientName = pt.getFullName().toDICOMPN(); 
     patientBleah = pt.getFullName().toDICOMPN(); 
     patientID = pt.id; 
     patientSex = Character.toString(pt.sex.getDICOMCode()); 
     patientDOB = pt.birthdate != null ? StringUtils.printISODate(pt.birthdate) : ""; 
     patientSite = pt.site_key; 


     List<StudyBean> lst = new ArrayList<StudyBean>(sts.size()); 
     for (KHStudy st : sts) 
     { 
      List<KHSeries> lsr = srs.get(st.key()); 
      if (lsr == null) 
       lsr = Collections.emptyList(); 
      lst.add(new StudyBean(st, lsr)); 
     } 
     studies = lst.toArray(new StudyBean[ lst.size() ]); 
    } 

    /** Maps a <code>CommonQueries.PSSTree</code> to an array of {@link PatientBean}. */ 
    public static List<PatientBean> mapPSSTree(CommonQueries.PSSTree tree) 
    { 
     List<PatientBean> lpt = new ArrayList<PatientBean>(tree.pts.size()); 
     for (Map.Entry< Integer, KHPatient > entry : tree.pts.entrySet()) 
     { 
      KHPatient pt = entry.getValue(); 
      List<KHStudy> lst = tree.sts.get(entry.getKey()); 
      PatientBean bpt = new PatientBean(pt, lst, tree.srs); 
      lpt.add(bpt); 
     } 
     return lpt; 
    } 
} 

大部分領域,如patientName,patientID,patientSEX,patientDOB和patientSite的是這個bean的原始版本的一部分,並通過JSON就好返回。不會返回新的字段,例如patientBleah和siteName。

爲了確保這個文件確實得到了maven的重新編譯,我試着註釋掉getPatientName()方法。正如預期的那樣,這導致客戶端變得對患者姓名「未定義」。但是,patientBleah和siteName在客戶端JSON中完全不顯示。

我對於我的生活不知道爲什麼註釋掉getPatientName()有效果,而添加其他字段(和相應的getter方法)沒有效果。

我對RESTful服務和POJO相當陌生,所以也許我錯過了一些明顯的東西。我覺得POJO映射只需要一個帶有字段和相應的公共getter方法的類,剩下的就完成了。從服務器的web.xml

片段的情況下,這是有益的還有:

<servlet> 
    <servlet-name>AimCloudREST</servlet-name> 
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> 
    <init-param> 
     <param-name>com.sun.jersey.config.property.packages</param-name> 
     <param-value>com.aimcloud.server;com.aimcloud.util</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name> 
     <param-value>com.aimcloud.util.AuthFilter</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name> 
     <param-value>com.aimcloud.util.ErrorFilter;com.aimcloud.util.AuthFilter</param-value> 
    </init-param> 
    <init-param> 
     <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    </servlet> 

我也嘗試使用「MVN清潔包」來編譯,但這並沒有幫助。重新編譯後,我也嘗試停止並重新啓動tomcat。

+0

您的PatientBean上沒有任何JAXB註釋? – TheArchitect

回答

0

我發現問題是發送給客戶端的JSON響應以未命名的數組開頭。換句話說,它看起來像這樣:

[{"patients":[{"patientName":"ASHA01^^^^==","patientBleah":"ASHA01^^^^==",[...],"patientSite":1}] 

這不會被JavaScript正確解析。數組必須命名,例如:

{"myArray":[...]} 

我追查這回該線路的RESTful新澤西代碼:

List<PatientBean> ret = PatientBean.mapPSSTree(tree); 

這個「RET」的對象是什麼返回給用戶。這是導致未命名的數組作爲JSON返回的結果,無法通過JavaScript正確解析。 (儘管被http://www.jsoneditoronline.org/正確解析)

這裏的解決方案是將我的結果包裝在一個更高級別的對象中,該對象具有單個元素:List。然後我返回這個對象,然後我的數組有一個名稱,並且生成的JSON被正確解釋。

public class ResultBean { 

    private List<PatientBean> patients; 

    public List<PatientBean> getPatients() { 
     return patients; 
    } 

    public ResultBean(List<PatientBean> inPatients) 
    { 
     patients = inPatients; 
    } 
}