2

我正在尝试使用 JAX-WS (SOAP) 创建允许对某些实体进行 CRUD 操作的 Web 服务。我还在编写一个带有 UI 的桌面客户端,它提供了通过 Web 服务对这些实体执行 CRUD 的简单方法。

但是,我遇到了一些设计问题。我希望客户端只能查看和操作实体的某些字段,我不确定施加此限制的最佳方法是什么。

例如,给定:

@Entity
public class Customer {

  @Id
  @GeneratedValue
  public Long id;

  public String name;

  // neither read nor write from the web service
  public String password;

  // read-only from the web service
  @Temporal(TemporalType.DATE)
  public Date joinedAt;

  @ManyToOne
  @LazyCollection(LazyCollectionOption.FALSE)
  private List<Order> orders;

  // .. boilerplate getters and setters
}

@Entity
public class Order {

  @Id
  @GeneratedValue
  public Long id;

  public String name;
}

我想为客户提供这些基本操作:

  1. 获取所有客户及其订单的列表
    • 他可以看到所有字段,除了password
  2. 用一些订单创建一个新客户
    • 允许控制除joinedAt和之外的所有字段password
  3. 修改客户
    • 同上,你不能修改joinedAtpassword

.

  1. 我目前针对 (1) 的解决方案是将 @XmlTransient 添加到密码字段。如果您想将密码发送给某些客户端但不发送给其他客户端,则会出现问题。另一种解决方案是customer.setPassword(null);在通过 Web 服务编组该实体之前执行此操作。但这真的是这样做的方法吗?第三种解决方案是创建一个基类BaseCustomer,其中包含除之外的所有字段password,然后 Customer 将是BaseCustomer具有添加password字段的一个。用户将收到 BaseCustomer 对象而不是 Customer 对象。但这也有创建/更新的问题。

  2. 与 (1) 相同,一种解决方案是customer.setJoinedAt(my_value); customer.setPassword(my_value); customer.setId(null);在客户想要创建新客户时执行。手动归零是id真正的最佳实践吗?我觉得很难相信。也应该id是 XmlTransient 吗?但是,Web 服务的用户如何能够修改/删除实体呢?

  3. 当客户想要更改 aCustomer时,他会检索客户列表,对其中一个对象进行更改Customer,然后编组该对象并将其传递回 Web 服务。这样做有一些问题:如果该id字段是 XmlTransient,那么 EntityManager 的持久性将不知道要修改哪一行,并且可能会创建一个新行。如果用户是邪恶的并且只是拒绝传递一个类似的问题id,所以我必须手动检查它id是非空的。而且,用户还没有收到该password字段,所以现在服务器收到了一个空的对象password它将尝试保留的字段。我相信这将导致 EntityManager 完全删除该现有客户的密码。让用户准确指定他想要修改哪些字段以及哪些值似乎不切实际。

请注意,这只是我需要做的简单的概念验证,我有更多的实体、关系和操作要提供。

我是使用这些技术的新手,我希望如此高的水平和如此多的抽象能让我的生活更轻松,但到目前为止,这主要是令人头疼的问题。完成这项常见的基本任务似乎非常困难。难道我做错了什么?请不要建议创建 Web 应用程序 :)

4

0 回答 0