我的系统由一个后端部分组成,用 Java 编写,公开一组使用 WSDL 和 XSD 以契约优先方式定义的 Web 服务。通过 Web 服务传输的数据中有大量产品类型(准确地说,它们是不同类型的银行账户)。我们的前端是一个 Grails Web 应用程序。它使用并公开后端托管的数据和操作。前端出于安全原因没有自己的数据库;所有数据都存储在后端。相当标准的架构。
现在,这组产品庞大、不断增长且不稳定。每个产品类型都必须在 Web 应用程序用户界面上进行 CRUD。如果我能告诉 Grails 使用产品类型的 XSD 规范作为域类型,并为它们生成视图和控制器,那就太好了。
即使经过大量的实验和大量的网页浏览,我还没有找到解决这个难题的方法。我在 Grails 方面拥有大约一年的专业经验。任何帮助或想法将不胜感激。
一些细节:
产品类型是一个简单的 POJO 数据载体。一些简化的例子:
package jaxbgenerated;
public class Product1 {
protected Account from;
protected Account to;
protected String name;
// + getters and setters
}
public class Product2 {
protected List<Account> accounts;
protected String name;
// + getters and setters
}
public class Account {
protected String id1;
protected String id2;
// + getters and setters
}
请注意,“Account”不是产品类型,而是 JAXB 生成的类型。除了 String、int 和 Date 等简单数据类型的属性外,产品还可以包含此类属性,但它们从不包含其他产品类型。
我想要的最终结果是 Grails 生成的表单,用户可以在其中编辑带有嵌套表单的 Product1 实例,以编辑其组成帐户。Product2 也是如此。
我的想法是首先为每个 JAXB 生成的类型手动编写一个 Grails 域类:
//in grails-app/domain:
import utilities.Copier
class Product1 extends jaxbgenerated.Product1 {
Product1(jaxbgenerated.Product1 jaxb) {
Copier.copy(jaxb, this)
}
static constraints = {
}
}
这里有一些样板代码,但我只能忍受。Copier.copy() 函数(我认为)需要将从后端获取的 jaxbegenerated.Product 实例转换为可以在 Grails 中使用的 Product1 实例。它递归地在 jaxb 源中查找 jaxb 生成的属性,并将它们的值复制到相应的 Grails 域类型。构造函数是从从后端获取数据的层调用的。
我可以使用约束块在需要的地方手动添加语义约束,例如“from”和“to”帐户不一样。
接下来,我为由此构建的所有 Grails 域类生成控制器和视图,并运行应用程序。并得到一堆异常:
Caused by MappingException: Could not determine type for: Account, at table:
product1_type, for columns: [org.hibernate.mapping.Column(from)]
我认为这里的问题是Product1 的“from”和“to”属性不是Account 类型,而是jaxbgenerated.Account 类型。
我尝试了不同的方法,但无济于事。一些注意事项:
- 正如我所说,所有数据存储都发生在我的后端,所以我不需要 Grails 的 GORM/Hibernate 方面。因此,我尝试将“static mapWith =”none”添加到域类中,但这没有帮助。
- 我尝试通过添加“static mapping = { from type: Account }”明确告诉 Hibernate Product1 中的 Accounts 类型,但这也不起作用。
任何帮助或想法将不胜感激。
/Jan Reher,Systematic A/S,丹麦