拦截没有EJB

时间:2016-05-04 17:43:02

标签: java tomcat java-ee soap jax-ws

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

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

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

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

我的问题是:

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

1 个答案:

答案 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参数并在没有这个的情况下返回。