如何在JAX-WS中控制JAXBContext?

Osw*_*Osw 6 java osgi web-services jax-ws jaxb

我需要为每个客户部署相同的Web服务.这种@javax.jws.WebService使用Object方法参数和返回类型(导致<xs:anyType/>在WSDL).每个Web服务实例都与类路径上的客户jar一起部署.这个jar有已知的结构,并包含客户想要通过我的服务处理的JAXB注释类.

问题是,当客户通过自己班级的方法agrument的一个实例,服务器端JAXB上下文中,因为(我的理解)仅部署时间解编入一些奇怪的Xerces DOM节点@WebMethod@WebService注释进行扫描,正如已经说,都是Object只处理.

简单来说,我需要提示JAXB,WEB-INF/lib/customer_classes_14586.jar这意味着JAXBContext在JAX-WS部署期间对创建进行一些控制.

有可能吗?

服务器特定的解决方案很好(带有metro ws堆栈的glassfish 3.1)

UPDATE

我错过了一件可能很重要的事情:我通过Web管理控制台在运行时将这些Web服务部署为OSGI包.当我按下部署按钮时,新的jar是从客户库,webservice类,wsdl和manifests 以编程方式构建的.因此,如果有帮助的话,我可能会干扰构建过程并在此时提供提示信息.

Osw*_*Osw 4

第一个选项是@UsesJAXBContext注释。更多信息请参见:在 SLSB 和 JAX-WS 中指定 JAXB 包

我还没有测试过它,因为当我发现这个注释时,我已经转向其他可能对其他人有帮助的解决方案了。

关键是使用@WebServiceProvider而不是@WebService,有点低级但简单:

@WebServiceProvider(
  wsdlLocation = "WEB-INF/wsdl/injector.wsdl"
)
@ServiceMode(value = Service.Mode.PAYLOAD)
public class InjectorService implements Provider<Source> {
  private Unmarshaller unmarshaller;

  @Override
  public Source invoke(Source request) {
    try {
      DOMResult requestDom = new DOMResult();
      Transformer trans = TransformerFactory.newInstance().newTransformer();
      trans.transform(request, requestDom);
      Node requestNode = requestDom.getNode();
      // Get the operation name node.
      Node operationNode = requestNode.getFirstChild();
      // Get the parameter node.
      Node parameterNode = operationNode.getFirstChild();
      // Unmarshal
      JAXBElement<Object> element = unmarshaller.unmarshal(parameterNode, Object.class);
      Object unmarshalled = element.getValue();          

      //  Handling customer object and response ......
    } catch (Exception e) {
      throw new RuntimeException("Endpoint error", e);
    }
  }

  protected Class[] getCustomerClasses() {
    // return customer classes somehow
  }

  @PostConstruct
  public void init() throws Exception {
    JAXBContext jbc = JAXBContext.newInstance(getCustomerClasses());
    unmarshaller = jbc.createUnmarshaller();
  }
}
Run Code Online (Sandbox Code Playgroud)

就是这样。客户类可以从类路径、捆绑上下文等获取。