Java 使用JAX-WS向客户机提供实体
我正在尝试使用JAX-WS(SOAP)创建一个web服务,允许对某些实体执行CRUD操作。我还编写了一个带有UI的桌面客户端,它提供了通过web服务在这些实体上执行CRUD的简单方法 然而,我遇到了一些设计问题。我希望客户端只能查看和操作实体的某些字段,我不确定施加此限制的最佳方式是什么 例如,假设:Java 使用JAX-WS向客户机提供实体,java,jpa,jax-ws,Java,Jpa,Jax Ws,我正在尝试使用JAX-WS(SOAP)创建一个web服务,允许对某些实体执行CRUD操作。我还编写了一个带有UI的桌面客户端,它提供了通过web服务在这些实体上执行CRUD的简单方法 然而,我遇到了一些设计问题。我希望客户端只能查看和操作实体的某些字段,我不确定施加此限制的最佳方式是什么 例如,假设: @Entity public class Customer { @Id @GeneratedValue public Long id; public String name;
@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;
}
@实体
公共类客户{
@身份证
@生成值
公共长id;
公共字符串名称;
//既不从web服务读取也不从web服务写入
公共字符串密码;
//从web服务只读
@时态(TemporalType.DATE)
公开日期联合日期;
@许多酮
@LazyCollection(LazyCollectionOption.FALSE)
私人名单订单;
//..样板间的接受者和接受者
}
@实体
公共阶级秩序{
@身份证
@生成值
公共长id;
公共字符串名称;
}
我想向客户提供以下基本操作:
- 他可以看到除密码之外的所有字段
- 允许对所有字段进行控制,除了
和joinedAt
password
- 同上,不允许修改
或joinedAt
密码
customer.setPassword(null)代码>在通过编组该实体之前
网络服务。但这真的是这样吗?第三种解决方案是创建一个基类BaseCustomer
,它包含除password
之外的所有字段,然后Customer将是一个BaseCustomer
,并添加了password
字段。用户将接收BaseCustomer对象,而不是Customer对象。但这在创建/更新方面也存在问题
customer.setJoinedAt(my_值);customer.setPassword(我的值);customer.setId(空)代码>当客户想要创建新客户时。手动清空id
真的是最佳实践吗?我觉得很难相信。id
也应该是瞬时的吗?但是,web服务的用户如何能够修改/删除实体呢
客户
时,他检索客户列表,对其中一个客户
对象进行更改,然后封送该对象并将其传递回web服务。
这有几个问题:如果id
字段是XmlTransient,那么EntityManager的persist将不知道要修改哪一行,并且可能会创建一个新的行。如果用户是邪恶的,只是拒绝传递id
,则会出现类似的问题,因此我必须手动检查id
是否为非空。此外,用户还没有收到密码
字段,因此现在服务器收到了一个带有空密码
字段的对象,它将尝试保留该字段。我相信这将导致EntityManager完全删除现有客户的密码。让用户精确地指定他想要修改的字段和值似乎不切实际我对使用这些技术还不熟悉,我希望如此高的水平和如此多的抽象将使我的生活更轻松,但到目前为止,这主要是令人头痛的。似乎很难完成这项共同的基本任务。我做错什么了吗?请不要建议创建web应用程序:)我建议不要通过soap将对象作为实体传输。考虑使用传输对象:从实体到映射对象的映射数据。但是这不会导致大量的代码复制吗?或者实体会继承传输对象吗?另外,我是否需要手动编写大量的
entityobj.setField(transferobj.getField())
来从一个转换到另一个?这样可以吗?如果问题域不同,那么拥有两行相同的代码不应被视为代码重复-正确使用传输对象可以并且将使代码更加冗长。对于实体,您仅限于以下操作:getCustomer()和getCustomerOrders(),而对于传输对象,您可以编写具有业务意义的操作,例如:getCustomerDetails()和getCustomerDetailsWithOrderSummary()。是的,您将不得不手动编写大量映射代码-这完全可以。考虑为映射创建单独的类。