由于没有人知道作者字段和 URI 之间的关系,这不会自动发生。使用插件 resteasy-links,您可以使用两个注释 @AddLinks 和 @LinkResource 定义这些关系。你可以找到more information in the docs。
此插件不会更改字段的值,但会将原子链接添加到实体。它也仅适用于 Jettison 和 JAXB。
这是一个使用Jackson 的快速+脏示例,它真正替换了作者字段的值。
我们将使用这个注解来定义 POJO 和资源之间的关系:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Linked {
String path();
String rel() default "";
}
这个注解需要应用于Author类:
@Linked(path = "/rest/authors/{authorId}", rel = "list")
public class Author {}
在Book字段我们需要添加我们要使用的Serializer:
public class Book {
@JsonSerialize(using = LinkedSerializer.class)
private Author author;
}
序列化器可能如下所示:
public class LinkedSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
Linked linked = value.getClass().getAnnotation(Linked.class);
Matcher matcher = Pattern.compile("\\{(.+?)\\}").matcher(linked.path());
if (!matcher.find()) {
return;
}
String param = matcher.group(1);
try {
Field field = value.getClass().getDeclaredField(param);
field.setAccessible(true);
Object paramValue = field.get(value);
String path = linked.path().replaceFirst("\\{.*\\}", paramValue.toString());
jgen.writeStartObject();
jgen.writeFieldName("href");
jgen.writeString(path);
jgen.writeFieldName("rel");
jgen.writeString(linked.rel());
jgen.writeEndObject();
} catch (NoSuchFieldException | SecurityException | IllegalAccessException ex) {
throw new IllegalArgumentException(ex);
}
}
}
注意:我们在这里只使用路径而不是完整的 URI,因为我们不知道基本 URI 并且无法在此序列化程序中注入 UriInfo 或 ServletRequest。但是您可以通过ResteasyProviderFactory.getContextData(HttpServletRequest.class) 获取 ServletRequest。