Android 使用spring数据rest创建具有引用的资源

Android 使用spring数据rest创建具有引用的资源,android,spring-boot,spring-data-rest,Android,Spring Boot,Spring Data Rest,我使用的是SpringDataREST,我通过SpringDataREST公开了以下实体 捐赠请求 @Data @Entity @Table(name="donation_request",schema="public") public class DonationRequest { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="donation_request_id")

我使用的是SpringDataREST,我通过SpringDataREST公开了以下实体

捐赠请求

@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客户端,它具有与上面所述相同的类定义。医院在启动时缓存在android客户端上。现在我想在服务器上创建一个donationRequest实体。通过将donationRequest对象的json发布到/api/donationRequests,我可以轻松做到这一点。此json还包含hospital对象。但是新创建的捐赠请求和医院没有联系在一起

postman中的以下json类型不创建链接:

{
    "bloodGroup":"AB+",
    "hospital":{
        "hospitalId":1
    }
}
{
    "bloodGroup":"AB+",
    "hospital":"/api/hospitals/1"
}
我知道以下json确实创建了链接:

{
    "bloodGroup":"AB+",
    "hospital":{
        "hospitalId":1
    }
}
{
    "bloodGroup":"AB+",
    "hospital":"/api/hospitals/1"
}
我的问题是如何使用第一种类型的json创建链接,因为这是从android客户端序列化dontaionRequest对象的自然方式?我还希望医院通过/api/hospitals公开,因此删除该rest资源不是一个选项。

Spring数据rest正在使用。要引用相关资源,我们必须使用它们的链接:

先创建医院

POST /api/hospitals
{
    //...
}
回应

{
    //...
    "_links": [
        "hostpital": "http://localhost/api/hospitals/1",
        //...
    ]
}
然后获取“hospital”(或“self”)链接并将其添加到“donationRequests”负载中

POST /api/donationRequests
{
    "bloodGroup":"AB+",
    "hospital": "http://localhost/api/hospitals/1"
}
另一种方法-在没有医院的情况下创建第一个“捐赠请求”

POST /api/donationRequests
{
    //...
}
回应

{
    //...
    "_links": [
        "hostpital": "http://localhost/api/donationRequests/1/hospital"
        //...
    ]
}
然后在有效负载中使用指向医院的文本链接将医院设置为
donationRequests/1/hospital
(注意内容类型:text/uri列表)

信息:

更新

如果有必要在没有资源链接的情况下进行处理,那么我们必须做出一个选择。

Spring数据REST正在使用。要引用相关资源,我们必须使用它们的链接:

先创建医院

POST /api/hospitals
{
    //...
}
回应

{
    //...
    "_links": [
        "hostpital": "http://localhost/api/hospitals/1",
        //...
    ]
}
然后获取“hospital”(或“self”)链接并将其添加到“donationRequests”负载中

POST /api/donationRequests
{
    "bloodGroup":"AB+",
    "hospital": "http://localhost/api/hospitals/1"
}
另一种方法-在没有医院的情况下创建第一个“捐赠请求”

POST /api/donationRequests
{
    //...
}
回应

{
    //...
    "_links": [
        "hostpital": "http://localhost/api/donationRequests/1/hospital"
        //...
    ]
}
然后在有效负载中使用指向医院的文本链接将医院设置为
donationRequests/1/hospital
(注意内容类型:text/uri列表)

信息:

更新


如果有必要在没有资源链接的情况下进行处理,我们必须创建一个。

可以通过使用自定义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 {

    }
}
公共类MHttpMessageConverter实现HttpMessageConverter{
@凌驾
公共布尔canRead(类aClass,MediaType MediaType){
if(mediaType.getType().equalsIgnoreCase(“应用程序”)
&&mediaType.getSubtype().equalsIgnoreCase(“mjson”))
返回true;
其他的
返回false;
}
@凌驾
公共布尔canWrite(类aClass,MediaType MediaType){
返回false;
}
@凌驾
公共列表getSupportedMediaTypes(){
返回新的ArrayList(Arrays.asList(MediaType.APPLICATION_JSON));
}
@凌驾
公共对象读取(类aClass,HttpInputMessage,HttpInputMessage)引发IOException,HttpMessageNodeReadableException{
ObjectMapper mapper=新的ObjectMapper();
Object obj=mapper.readValue(httpInputMessage.getBody(),aClass);
返回obj;
}
@凌驾
public void write(对象o、MediaType、MediaType、HttpOutputMessage、HttpOutputMessage)引发IOException、HttpMessageGenetWritableException{
}
}
CustomRestConfiguration.java

@Configuration
public class CustomRestConfiguration extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        messageConverters.add(new MHttpMessageConverter());
    }
}
@配置
公共类CustomRestConfiguration扩展了RepositoryRestConfigurerAdapter{
@凌驾

public void配置HttpMessageConverter(列表可通过使用自定义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 {

    }
}
公共类MHttpMessageConverter实现HttpMessageConverter{
@凌驾
公共布尔canRead(类aClass,MediaType MediaType){
if(mediaType.getType().equalsIgnoreCase(“应用程序”)
&&mediaType.getSubtype().equalsIgnoreCase(“mjson”))
返回true;
其他的
返回false;
}
@凌驾
公共布尔canWrite(类aClass,MediaType MediaType){
返回false;
}
@凌驾
公共列表getSupportedMediaTypes(){
返回新的ArrayList(Arrays.asList(MediaType.APPLICATION_JSON));
}
@凌驾
公共对象读取(类aClass,HttpInputMessage,HttpInputMessage)引发IOException,HttpMessageNodeReadableException{
ObjectMapper mapper=新的ObjectMapper();
Object obj=mapper.readValue(httpInputMessage.getBody(),aClass);
返回obj;
}
@凌驾
public void write(对象o、MediaType、MediaType、HttpOutputMessage、HttpOutputMessage)引发IOException、HttpMessageGenetWritableException{
}
}
CustomRestConfiguration.java

@Configuration
public class CustomRestConfiguration extends RepositoryRestConfigurerAdapter {

    @Override
    public void configureHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        messageConverters.add(new MHttpMessageConverter());
    }
}
@配置
公共类CustomRestConfiguration扩展了RepositoryRestConfigurerAdapter{
@凌驾

公共无效配置HttpMessageConverters(列出两件事:-1-医院已经创建。我只想参考。2-我已经告诉过我知道rest资源链接可以用于创建关联链接。我想知道是否有其他解决方案?请检查我的答案。两件事:-1-医院已经创建。我只想参考。2-我已经告诉过我知道rest资源链接可用于创建关联链接。我想知道是否有其他解决方案?检查我的答案。非常有趣的解决方案。自定义控制器不会更容易?使用自定义控制器,我将不得不单独处理所有实体。非常有趣的解决方案。自定义控制器不会更容易?使用自定义控制器,我将我必须单独处理所有实体。