在没有EJB的情况下截获SOAP RPC方法响应



我正在为一家公司进行项目改造,他们希望在前端/客户端和后端/服务器之间拆分系统(更像是前端和数据库服务器之间的中间人),我应该使用JAX-WS RPC并维护当前的功能。

通过维护功能,它们意味着一些方法应该返回null,这是WS-I所禁止的。

在寻找可能的解决方案时,我偶然发现了这篇文章:http://victor-ichim.blogspot.com.br/2011/03/rpcliteral-and-null-object-pattern.html它通过使用EJB拦截器来拦截空结果并用空对象替换空结果,基本上解决了类似的问题。

围绕这个概念,我想像这样截取结果,用字符串模板之类的东西替换null,在客户端上再次截取它,然后用null替换回该模板。

我的问题是:

  1. 它们默认不使用EJB,因此本身没有拦截器。是否有一些实现可以同时适用于Tomcat和JBoss?
  2. 即使我能够在服务器端拦截返回,我怎么能在客户端完成呢
  3. 如果我可以使用SOAPHandlers,我如何避免由于试图返回null而引发SOAP Fault

由于我也遇到了JAXB不处理接口的问题,所以我最终使用@XmlJavaTypeAdapter注释来启用(有选择地,因为实际上可能为null的每个返回和参数都需要注释)将值从null转换回null,这有点像黑客作业。我为Serializable对象创建了一个通用的ish适配器,并对其他类型的Object对象采用了相同的方法:

public class SerializableAdapter extends XmlAdapter<String, Serializable>>{
    
    private static final String NULL = "'NULL'"; // Will hopefully never collide
    
    @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());
    }
    
}

然后用@XmlJavaTypeAdapter(SerializableAdapter.class)对每个Serializable实例进行注释,因为使用包级别的@XmlJavaTypeAdapters由于某些原因而不起作用,等等。JAXB在调用适配器时似乎急切地将编码的类型转换为和转换为,因此即使要编组的对象不是预期类/接口的实例,它也会编译得很好,并且只在运行时抛出异常。

我不建议这样做,因为它需要注释每一个方法/参数或包,并且会在第一个没有注释但收到null的方法/参数包处中断这个适配器仍然适用于我需要使用接口的情况,并且实现类也实现了Serializable,尽管有些情况仍然需要特定的适配器,但这通常是经过深思熟虑的代码。

部分原因是这很麻烦,加上注释所有内容的麻烦,我设法说服公司放弃SOAP RPC绑定,所以我可以在没有这一点的情况下使用null参数和返回。

最新更新