如何在JAX-WS中获得对JAXBContext的控制? [英] How to get control over JAXBContext in JAX-WS?

查看:123
本文介绍了如何在JAX-WS中获得对JAXBContext的控制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to deploy the same web service for each customer. This @javax.jws.WebService uses Object as method arguments and return types (resulting in <xs:anyType/> in wsdl). Each instance of web service is deployed along with customer's jar on the classpath. This jar has known structure and contains JAXB-annotated classes which client wants to handle via my service.

问题在于,当客户通过方法实例传递其类的实例时,服务器端JAXB上下文会将其解组到某个奇怪的xerces dom节点,因为(据我所知)在部署期间只有@WebMethod已扫描注释,就像已经说过的那样,它们都只处理Object.

The problem is that when customer passes an instance of his class as method agrument, server-side JAXB context unmarshals it into some strange xerces dom node because (as I understand it) during the deployment time only @WebMethod and @WebService annotations were scanned which, as was already said, are all dealing with Object only.

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

Simply speaking, I need to hint JAXB at WEB-INF/lib/customer_classes_14586.jar which means taking some control over JAXBContext creation during JAX-WS deployment.

有可能吗?

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

Server-specific solutions are fine (glassfish 3.1 with metro ws stack)

更新

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

I've missed one thing that might be important: I deploy these web services as OSGI bundles at runtime via web admin console. When I press deploy button new jar is programmatically built up from customer library, webservice class, wsdl and manifests. So I could interfere in build process and provide hinting information at this point of time if this helps.

推荐答案

第一个选项是@UsesJAXBContext批注.此处了解更多信息:在SLSB和JAX-中指定JAXB软件包WS

First option is @UsesJAXBContext annotation. More info here: Specify JAXB Packages in SLSB and JAX-WS

我没有测试它的原因,因为当我发现此注释时,我已经在其他解决方案的中间,这可能对其他人有所帮助.

I haven't tested it cause when I found this annotation I've been already halfway towards other solution which might be helpful for others.

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

The key is using @WebServiceProvider instead of @WebService, a bit low-level but simple:

@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();
  }
}

就是这样.客户类可以从类路径,捆绑上下文或其他任何东西中获取.

That's it. Customer classes can be obtained from classpath, bundle context or whatever.

这篇关于如何在JAX-WS中获得对JAXBContext的控制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆