我正在为一家公司进行项目改造,他们希望在前端/客户端和后端/服务器之间拆分他们的系统(更像是前端和数据库服务器之间的中间人),我应该使用JAX-WS RPC并维护当前的功能。
通过维护功能,它们意味着某些方法应该返回null,这是WS-I禁止的。
在搜索可能的解决方案时,我偶然发现了这篇文章:http://victor-ichim.blogspot.com.br/2011/03/rpcliteral-and-null-object-pattern.html它基本上通过使用EJB拦截器拦截并用空对象替换null结果来解决类似的问题。
围绕这个概念,我想要拦截结果就像这样,用类似字符串模板的东西替换null,在客户端上再次拦截它,然后用null替换该模板。
我的问题是:
答案 0 :(得分:0)
由于我也遇到了JAXB没有处理接口的问题,我最终做的是使用@XmlJavaTypeAdapter
注释来启用(有选择地,因为每个返回和可能为null的参数都需要注释)转换来自然后以某种hackjob的方式回到null。我为Serializable
个对象创建了一个泛型适配器,并对其他类型的Object
采用了相同的方法:
public class SerializableAdapter extends XmlAdapter<String, Serializable>>{
private static final String NULL = "'NULL'"; // Will never collide, since it has 's
@Override
public Serializable unmarshal(String e) throws Exception {
if (e == NULL) {
return null;
}
byte [] eB = e.getBytes("ISO-8859-1");
InputStream iS = new ByteArrayInputStream(Base64.getDecoder().decode(eB));
ObjectInputStream oIS = new ObjectInputStream(iS);
return (Serializable) oIS.readObject();
}
@Override
public String marshal(Serializable o) throws Exception {
if (o == null) {
return NULL;
}
ByteArrayOutputStream bAOS = new ByteArrayOutputStream();
ObjectOutputStream oOS = new ObjectOutputStream(bAOS);
oOS.writeObject(o);
return Base64.getEncoder().encodeToString(bAOS.toByteArray());
}
}
然后使用Serializable
对每个@XmlJavaTypeAdapter(SerializableAdapter.class)
个实例进行注释,因为使用包级@XmlJavaTypeAdapters
由于某种原因没有工作,对于其他情况也是如此。 JAXB似乎急切地在调用适配器时强制转换编码类型,因此即使要编组的对象不是预期类/接口的实例,它也只会在运行时编译并抛出异常。
我不建议这样做,因为它需要注释每个方法/参数或包,并且会在第一个没有注释但仍然收到null的方法中断这个适配器仍然用于我需要使用接口的情况,并且实现类也实现Serializable,尽管有些情况仍然需要特定的适配器,但这通常很糟糕 - 出代码。
部分原因是由于这种黑客行为以及注释所有内容的麻烦,我可以说服公司放弃SOAP RPC绑定,因此我能够使用null参数并在没有这个的情况下返回。