java - 提供链接而不是序列化集合

标签 java spring rest jackson jax-rs

我有两门课:

public class A{
    private String property;

    private Set<B> bs = new HashSet<B>();
}

public class B{
    private String property;

    private A owner;
}

我创建了一个基本的 JAX-RS + Spring boot 应用程序,我想返回 A。

问题是 A 包含 Set<B> ,所以我遇到了无限嵌套级别问题。

我找到了一个解决方案:提供一个链接而不是资源本身,这样我就可以得到这个:

{ "property" : "value", "bs" : "http://mywebsite/api/a/2/bs" }

而且我没有遇到任何嵌套级别问题,因为每个级别都是单独序列化的。

如何在我的 JAX-RS 应用程序中实现这样的事情?我什么也没找到,但我知道这是可能的,因为 Spring Data Neo4j REST正在使用它,并且效果很好。

最佳答案

我可以想到以下可能的方法来实现这一目标。

使用 XmlAdapter 在序列化期间将集合转换为 URI

@XmlRootElement
public class A
{
    private int id;

    private String property;

    @XmlJavaTypeAdapter(BsAdapter.class)
    private Set<B> bs = new HashSet<B>();
}


public class BsAdapter extends XmlAdapter<URI, Set<B>>
{

    @Override
    public Set<B> unmarshal(URI v) throws Exception
    {
        return new HashSet<>();
    }

    @Override
    public URI marshal(Set<B> v) throws Exception
    {
        return URI.create(
            Optional.ofNullable(v)
            .filter(b -> !b.isEmpty())
            .map(b -> "/" + b.stream().findFirst().get().getOwner().getId() + "/bs")
            .orElse(""));
    }

}

如果 A 的 id 是 URI 的一部分,则仅当集合不为空时才能检索它。结果是相对 URI,因为没有可用的进一步信息。

作为替代方法,手动设置 URI。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A
{

    private int id;

    private String property;

    @XmlTransient
    private Set<B> bs = new HashSet<B>();

    @XmlElement(name = "bs")
    private URI bsUri;
}

并设置 URL,如下所示:

@Context
UriInfo uriInfo;

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getA()
{
    // ... 
    a.setBsUri(UriBuilder.fromUri(uriInfo.getAbsolutePath())
        .path("a")
        .path("{id}")
        .path("bs")
        .build(2));     
    return Response.ok().entity(a).build();
}

或者,如果 HTTP header 中的链接也可以,只需这样做即可,这样您就不必使用 URI 扩展 A 类。

    return Response.ok().entity(a).link(UriBuilder.fromUri(uriInfo.getAbsolutePath())
        .path("a")
        .path("{id}")
        .path("bs")
        .build(2), "bs").build();

关于java - 提供链接而不是序列化集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35435710/

相关文章:

java - 查找任意两个列表值之和是否等于给定值

spring - Kotlin测试无法从命令行通过ClassNotFoundException进行失败,但可以通过IntelliJ进行

c# - 为 C# asp.net 电子商务网站构建用于移动应用程序(Android 和 iOS)的 REST API

java - 在Java中迭代时删除!但删除当前对象以外的对象

java - 为什么我的事务在 MySQL 中死锁?

java - Spring @Value 与多矿属性文件值

spring - Spring 安全性中的多个 antMatchers

java - 如何在 Spring 中使用 SipServlet?

http - 为 Web API 驱动程序使用 HTTP 持久连接?

javascript - 如何在我的机器上快速设置 "dummy"服务器? (电话间隙可访问)