如何在JAX-WS中获得对JAXBContext的控制? [英] How to get control over JAXBContext in JAX-WS?
问题描述
我需要为每个客户部署相同的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屋!