我有一个令人费解的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。
答案 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;
}
}