0

不可解なRESTfulの問題があります。POJO マッピングを使用して Java オブジェクト (Beans?) を JSON に変換する Jersey を使用して REST を使用します。最初はこれでうまくいきましたが、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;
    }
}

患者名、患者ID、患者SEX、患者DOB、患者サイトなどのほとんどのフィールドは、このBeanの元のバージョンの一部であり、JSON経由で問題なく返されます。PatientBleah や siteName などの新しいフィールドは返されません。

このファイルが実際に maven によって再コンパイルされていることを確認するために、getPatientName() メソッドをコメントアウトしてみました。これにより、予想どおり、クライアントは患者名に対して「未定義」を取得しました。ただし、クライアントの JSON には、patientBleah と siteName はまったく表示されません。

getPatientName() をコメントアウトすると効果があるのに、他のフィールド (および対応する getter メソッド) を追加しても効果がない理由は、今のところわかりません。

私は RESTful サービスと POJO にかなり慣れていないので、明らかな何かが欠けている可能性があります。POJO マッピングには、フィールドと対応する public 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を停止して再起動しようとしました。

4

1 に答える 1