使用 spring 数据 rest 创建带有引用的资源
Creating Resource with references using spring data rest
我正在使用 spring 数据休息,我通过 spring 数据休息
公开了以下实体
捐赠请求
@Data
@Entity
@Table(name="donation_request",schema="public")
public class DonationRequest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="donation_request_id")
Integer donationRequestId;
@Column(name="expiry_datetime")
Date expiryDatetime;
@Column(name="blood_group")
String bloodGroup;
@Column(name="no_of_bottles")
String noOfBottles;
@OneToOne
@JoinColumn(name="hospital_id")
Hospital hospital;
@OneToOne
@JoinColumn(name="user_data_id")
UserData requester;
@Column(name="active")
Boolean active;
}
医院
@Data
@Entity
@Table(name="hospital",schema="public")
public class Hospital {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="hospital_id")
Integer hospitalId;
@Column(name="name")
String name;
@Column(name="address")
String address;
@Column(name="loc",columnDefinition = "geometry")
Point loc;
}
现在我有一个 android 客户端,它具有与上述相同的 class 定义。医院在启动时缓存在 android 客户端上。现在我想在服务器上创建一个 donationRequest 实体。我可以通过将 donationRequest 对象的 json 发布到 /api/donationRequests 来轻松做到这一点。这个 json 也包含医院对象。但是新创建的 donationRequest 和 hospital 没有link一起编辑。
Postman 中的以下 json 类型不会创建 link:
{
"bloodGroup":"AB+",
"hospital":{
"hospitalId":1
}
}
我知道跟随 json 确实会创建 link:
{
"bloodGroup":"AB+",
"hospital":"/api/hospitals/1"
}
我的问题是如何使用第一种json创建link,因为这是从[=35]序列化dontaionRequest对象的自然方式=] 客户?此外,我希望通过 /api/hospitals 公开医院,因此 删除剩余资源不是一个选项 。
Spring REST 数据正在使用 HATEOAS。要引用相关资源,我们必须对它们使用 links:
先创建医院
POST /api/hospitals
{
//...
}
回应
{
//...
"_links": [
"hostpital": "http://localhost/api/hospitals/1",
//...
]
}
然后获取'hospital'(或'self')link并将其添加到'donationRequests' payload
POST /api/donationRequests
{
"bloodGroup":"AB+",
"hospital": "http://localhost/api/hospitals/1"
}
另一种方法 - 先创建 'donationRequests' 没有医院
POST /api/donationRequests
{
//...
}
回应
{
//...
"_links": [
"hostpital": "http://localhost/api/donationRequests/1/hospital"
//...
]
}
然后在有效负载中使用文本 link 将医院 PUT 到 donationRequests/1/hospital
到医院(注意内容类型:text/uri-list)
PUT http://localhost/api/donationRequests/1/hospital (Content-Type: text/uri-list)
http://localhost/api/hospitals/1
信息:Repository resources - The association resource
更新
如果有必要在没有 link 的情况下处理资源,我们必须制作一个 custom rest controller。
这可以通过使用自定义 HttpMessageConverter 并定义自定义内容类型来实现,它可以是标准以外的任何内容(我使用 application/mjson):
MHttpMessageConverter.java
public class MHttpMessageConverter implements HttpMessageConverter<Object>{
@Override
public boolean canRead(Class<?> aClass, MediaType mediaType) {
if (mediaType.getType().equalsIgnoreCase("application")
&& mediaType.getSubtype().equalsIgnoreCase("mjson"))
return true;
else
return false;
}
@Override
public boolean canWrite(Class<?> aClass, MediaType mediaType) {
return false;
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return new ArrayList<>(Arrays.asList(MediaType.APPLICATION_JSON));
}
@Override
public Object read(Class<?> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
ObjectMapper mapper = new ObjectMapper();
Object obj = mapper.readValue(httpInputMessage.getBody(),aClass);
return obj;
}
@Override
public void write(Object o, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
}
}
CustomRestConfiguration.java
@Configuration
public class CustomRestConfiguration extends RepositoryRestConfigurerAdapter {
@Override
public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(new MHttpMessageConverter());
}
}
我正在使用 spring 数据休息,我通过 spring 数据休息
公开了以下实体捐赠请求
@Data
@Entity
@Table(name="donation_request",schema="public")
public class DonationRequest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="donation_request_id")
Integer donationRequestId;
@Column(name="expiry_datetime")
Date expiryDatetime;
@Column(name="blood_group")
String bloodGroup;
@Column(name="no_of_bottles")
String noOfBottles;
@OneToOne
@JoinColumn(name="hospital_id")
Hospital hospital;
@OneToOne
@JoinColumn(name="user_data_id")
UserData requester;
@Column(name="active")
Boolean active;
}
医院
@Data
@Entity
@Table(name="hospital",schema="public")
public class Hospital {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="hospital_id")
Integer hospitalId;
@Column(name="name")
String name;
@Column(name="address")
String address;
@Column(name="loc",columnDefinition = "geometry")
Point loc;
}
现在我有一个 android 客户端,它具有与上述相同的 class 定义。医院在启动时缓存在 android 客户端上。现在我想在服务器上创建一个 donationRequest 实体。我可以通过将 donationRequest 对象的 json 发布到 /api/donationRequests 来轻松做到这一点。这个 json 也包含医院对象。但是新创建的 donationRequest 和 hospital 没有link一起编辑。
Postman 中的以下 json 类型不会创建 link:
{
"bloodGroup":"AB+",
"hospital":{
"hospitalId":1
}
}
我知道跟随 json 确实会创建 link:
{
"bloodGroup":"AB+",
"hospital":"/api/hospitals/1"
}
我的问题是如何使用第一种json创建link,因为这是从[=35]序列化dontaionRequest对象的自然方式=] 客户?此外,我希望通过 /api/hospitals 公开医院,因此 删除剩余资源不是一个选项 。
Spring REST 数据正在使用 HATEOAS。要引用相关资源,我们必须对它们使用 links:
先创建医院
POST /api/hospitals
{
//...
}
回应
{
//...
"_links": [
"hostpital": "http://localhost/api/hospitals/1",
//...
]
}
然后获取'hospital'(或'self')link并将其添加到'donationRequests' payload
POST /api/donationRequests
{
"bloodGroup":"AB+",
"hospital": "http://localhost/api/hospitals/1"
}
另一种方法 - 先创建 'donationRequests' 没有医院
POST /api/donationRequests
{
//...
}
回应
{
//...
"_links": [
"hostpital": "http://localhost/api/donationRequests/1/hospital"
//...
]
}
然后在有效负载中使用文本 link 将医院 PUT 到 donationRequests/1/hospital
到医院(注意内容类型:text/uri-list)
PUT http://localhost/api/donationRequests/1/hospital (Content-Type: text/uri-list)
http://localhost/api/hospitals/1
信息:Repository resources - The association resource
更新
如果有必要在没有 link 的情况下处理资源,我们必须制作一个 custom rest controller。
这可以通过使用自定义 HttpMessageConverter 并定义自定义内容类型来实现,它可以是标准以外的任何内容(我使用 application/mjson):
MHttpMessageConverter.java
public class MHttpMessageConverter implements HttpMessageConverter<Object>{
@Override
public boolean canRead(Class<?> aClass, MediaType mediaType) {
if (mediaType.getType().equalsIgnoreCase("application")
&& mediaType.getSubtype().equalsIgnoreCase("mjson"))
return true;
else
return false;
}
@Override
public boolean canWrite(Class<?> aClass, MediaType mediaType) {
return false;
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return new ArrayList<>(Arrays.asList(MediaType.APPLICATION_JSON));
}
@Override
public Object read(Class<?> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
ObjectMapper mapper = new ObjectMapper();
Object obj = mapper.readValue(httpInputMessage.getBody(),aClass);
return obj;
}
@Override
public void write(Object o, MediaType mediaType, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
}
}
CustomRestConfiguration.java
@Configuration
public class CustomRestConfiguration extends RepositoryRestConfigurerAdapter {
@Override
public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(new MHttpMessageConverter());
}
}