I can think of the following possible ways how to achieve that.
Convert the set to URI during serialization by using a XmlAdapter
@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(""));
}
}
If the id of A is part of the URI then it can only be retrieved if the set is not empty. The result is a relative URI, since there are no further information available.
As an alternative set the URI manually.
@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;
}
And set the URL like this:
@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();
}
Or if a link in HTTP Header is also fine, simply do it this way so you do not have to extend class A with the URI.
return Response.ok().entity(a).link(UriBuilder.fromUri(uriInfo.getAbsolutePath())
.path("a")
.path("{id}")
.path("bs")
.build(2), "bs").build();