我有一个使用Jersey实现REST API的Web应用程序。 Web容器ID Tomcat
以下是API的摘要:
/rest/patients
获取患者元数据的列表。
/rest/patients/{id}
获取有关特定患者的详细数据。
/rest/patients/{id}/visits
获取特定患者的访问元数据列表。
/rest/patients/{id}/visits/{visitId}
获取有关特定患者特定就诊的详细数据。
我的问题是我无法获得子资源。例如,当我请求/rest/patients/1
时,正确接收患者#1的详细数据
但是当我请求/rest/patients/1/visits
时,我收到404错误,并且流程甚至没有输入getVisits()
方法。
看起来,当收到特定患者ID的请求(patients/{id}
)时,Jersey会正确地将其从PatientsMetadataResource
引导至PatientsResource
。
但是当请求访问子子资源(patients/{id}/visits
)时,Jersey不会将其指向PatientsResource
。
那么如何将子资源及其所有子资源引导到同一个类中呢?
PatientsMetadataResource
的代码(名称有点模糊,我需要更改它):
@Path("/patients")
public class PatientsMetadataResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPatients(@QueryParam("page") int pageIndex) {
//.... Loads, Builds and returns the patients' metadata list correctly
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/{uid:\\d+}")
public PatientResource getPatient(@PathParam("uid") int uid) {
return new PatientResource(uid);
}
}
PatientResource
的代码:
public class PatientResource {
private final int uid;
public PatientResource(int uid) {
this.uid = uid;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getPatient() {
//Returns the patient correctly
System.out.println("A Patient was asked");
Patient patient = PersistentDataProvider.loadPatientByUid(uid);
return Response.ok(patient).build();
}
@GET
@Path("/visits")
@Produces(MediaType.APPLICATION_JSON)
public VisitsResource getVisits(@PathParam("uid") int patientUid) {
//The flow doesn't even enter here. A 404 is being returned instead.
System.out.println("Visits were asked");
return new VisitsResource(patientUid);
}
}
web.xml中泽西部分的代码:
<servlet>
<servlet-name>Jersey REST Service</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>il.co.site_building.dvardy.resources</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>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
答案 0 :(得分:2)
子资源定位器不应该具有HTTP方法注释
// @GET <--- Remove this
// @Produces(MediaType.APPLICATION_JSON)
@Path("/{uid:\\d+}")
public PatientResource getPatient(@PathParam("uid") int uid) {
return new PatientResource(uid);
}
他们的主要目的是简单地将请求转发给子资源类,而不是GET / POST / etc。当Jersey看到HTTP方法注释时,它不再被视为子资源定位器。
此外,您不需要传递ID。它会相应地传递
@Path("parent")
class ParentResource {
@Path("{id}")
public ChildResource getChild() {
return new ChildResource();
}
}
class ChildResource {
@GET
public Response get(@PathParam("id") long id) {}
@GET
@Path("something")
public Response something(@PathParam("id") long id) {}
}
这里GET&#39; parent / 1&#39;转到ChildResource.get
,传递路径参数,GET parent/1/something
转到ChilsResource.something
,传递路径参数