1

我正在为一个项目创建一个 RESTful API。我在尝试用球衣实现它时遇到了一些问题:

  1. 我的对象模型显然不包含 uri 信息。例如,假设我有一个水果课。Fruit 对象有一个 FruitName 和一个 FruitColor。但在响应中,我还需要发送一个 URI。这通常是如何处理的?我应该创建一个单独的“FruitResource”,它有一个构造函数,它接受一个“Fruit”并从中创建一个完整的资源,包括 URI?我还需要嵌套对象中的 URI,例如,如果我返回一个Child对象列表,我需要每个Child对象也有一个 URI,但我不希望 URI 成为对象模型的一部分。最干净的方法是什么?

  2. 我希望能够返回同一资源的完整和部分视图。例如,部分视图只有名称和 URI。如何完成这项工作?

现在我拥有的是一个Service接受请求的类,它使用DAO来创建和返回对象,因为它们是从数据库建模的,使用杰克逊序列化为 JSON。

4

4 回答 4

2

我正在开发一个支持这两个问题的项目:https ://github.com/skyscreamer/yoga,在http://yoga.skyscreamer.org/提供更多信息,包括演示。

它将 JAX-RS(或 Spring MVC)渲染机制替换为更符合 REST 系统需求的定制构建解决方案。

对于#1,我们有一个注释,您必须将其应用于您的 Child pojo。JAX-RS 的注解旨在将 URL 映射到控制器而不是底层对象,因此我们需要一个自定义解决方案……但它实际上只是归结为每个 pojo 1 个额外的注解。

对于#2,我们有一个基于 URL 的机制,用于指定您希望从 pojo 或 pojo 的子项中获得哪些附加信息(并且可以进一步嵌套)。

我希望这有帮助。

于 2012-09-07T18:48:37.057 回答
2

有一种使用 JaxB 类的方法,您可以将对象模型传递给 JaxB 类,然后 JaxB 类生成 URI。下面是小样机。

用户资源类

@Path("/user")
public class UserResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{user-id}")
public UserJaxB getUser(@PathParam("user-id") String userId, @Context
HttpServletRequest request) {
    // now XYZ is hard-coded value 
    String serviceEndpoint = request.getContextPath() + "/" + "user";
    UserModel userModel = new UserModel(userId, "XYZ");
    return new UserJaxB(serviceEndpoint,userModel);
}
}

用户 JAXB 类

@XmlRootElement
public class UserJaxB {

private String name;
private String id;
private String serviceEndpoint;
private String URI;

public UserJaxB(String serviceEndpoint, UserModel userModel) {
    this.name = userModel.getName();
    this.id = userModel.getId();
    this.serviceEndpoint = serviceEndpoint;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getURI() {
    return this.serviceEndpoint + "/" + id;
}
}

用户模型类 public class UserModel {

String name;
String id;

public UserModel(String name, String id) {
    this.name = name;
    this.id = id;
}

public String getId() {
    return id;
}


public String getName() {
    return name;
}
}
于 2012-09-07T18:33:54.943 回答
1

1)我不知道有任何 Jersey 或 JAX-RS 机制支持这一点。不过,必须将 URI 添加到每个域类的构造函数中似乎是一种不好的做法。您可以创建一个方面来拦截该方法并将响应包装在一个新对象中 - 在包装器中添加资源的 URI(您可以通过拦截器的反射获取 URIInfo)。我在构建 etag 支持时已经这样做了,所以我不必为每个响应添加缓存代码。我想你也可以在同一方面添加一些东西来处理子 URI 问题......

您可能还想看看这些讨论:

2)为了构建“更轻”的响应实体,我通常有一个BeanLite.class只包含摘要所需的属性,然后Bean.class用更多细节对其进行扩展。您可以将两者都添加到您的 ORM 中,并提供一个选项以在您的 DAO 中切换表示。

于 2012-09-07T18:37:09.797 回答
0

感谢您的所有回复。通过你们提出的所有方法,经过我自己的一些研究,这就是我决定的:

1)我将 uri 添加为对象模型的一部分。这似乎是我目前最干净的解决方案。无论何时创建对象(使用对象的其他属性),都可以自动填充 URI。早些时候我认为这是一个坏主意,但我无法预见这种方法的任何问题,除了必须与对象一起移动的额外字段。

2)为了支持完整/部分视图,我正在尝试使用@JsonView注释。这似乎是一个很好的方法。

让我知道这种处理方式是否还有其他潜在问题。

于 2012-09-09T13:55:57.547 回答