不可解な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を停止して再起動しようとしました。