RESTful POJO - > JSON映射没有拾取新字段

时间:2013-07-30 20:52:57

标签: rest jersey pojo

我有一个令人费解的RESTful问题。我使用REST使用REST,它使用POJO映射将Java对象(Beans?)转换为JSON。最初这很好用,但现在,在尝试向Bean添加新字段时,它们不会显示在客户端收到的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对象组成的List。 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()方法。这导致客户端对patientName进行“未定义”,如预期的那样。但是,在客户端JSON中,patientBleah和siteName根本不显示。

我为我的生活不知道为什么注释掉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 clean package”进行编译,但这没有用。我还尝试在重新编译后停止并重新启动tomcat。

1 个答案:

答案 0 :(得分:0)

我发现问题是发送到客户端的JSON响应是以未命名的数组开头的。换句话说,它看起来像这样:

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

JavaScript无法正确解析。必须命名数组,如下所示:

{"myArray":[...]}

我在RESTful Jersey代码中追溯到这一行:

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