英文:
JAXB - getting attributes from XML that not specified in XSD
问题
下午好,
在我的服务中,我必须调用一个下游服务,其SOAP响应包含许多属性,如下所示:
<section name="AA1">
<grp name="..." AB1001="1.5" AB1002="..." .../>
<grp name="..." CD1001="1.5" CD1F002="..." .../>
...
</section>
<section name="AB1">
<grp name="..." AB1001="1.5" AB1002="..." .../>
<grp name="..." CD1001="1.5" CD1F002="..." .../>
...
</section>
<section name="AB2">
...
</section>
...
在我的服务的响应中,我必须检索相同的结构。然而,由于属性的数量庞大,所以我认为不会将所有这些属性添加到我的服务的XSD中,而是会在下游服务的响应中遍历属性,并将我找到的任何属性添加到我的服务的SOAP响应中。
困难在于,我使用JAXB,因此Java XML bean是从XSD生成的。由于XML属性不在我的服务的XSD中,所以我应该以一种'手动'的方式(在JAXB bean被编组为XML(SOAP响应)之后)添加它们。
请问是否有一种方法可以做到这一点?
我使用Spring和Spring Integration。
出站网关配置如下:
@Configuration
public class MppWebServiceGatewayConfig {
...
@Bean(name="serviceOutboundGateway")
public MessageHandler serviceOutboundGateway() {
final MarshallingWebServiceOutboundGateway gateway = new ExceptionHandlingMarshallingWebServiceOutboundGateway(url, mppMarshaller(), mppUnMarshaller());
gateway.setMessageSender(httpPoolingWebServiceMessageSender);
return gateway;
}
@Bean
public Marshaller mppMarshaller() {
final Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(CONTEXTPATH);
return marshaller;
}
@Bean
public Unmarshaller mppUnMarshaller() {
final Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
unmarshaller.setContextPath(CONTEXTPATH);
return unmarshaller;
}
...
}
谢谢!
英文:
Good afternoon,
In my service I have to call a downstream service whose SOAP response contains lots of attributes like
<section name="AA1">
<grp name="..." AB1001="1.5" AB1002="..." .../>
<grp name="..." CD1001="1.5" CD1F002="..." .../>
...
</section>
<section name="AB1">
<grp name="..." AB1001="1.5" AB1002="..." .../>
<grp name="..." CD1001="1.5" CD1F002="..." .../>
...
</section>
<section name="AB2">
...
</section>
...
In my service's response I have to retrieve this same structure.
However as the number of the attributes are enormous so I thought I won't add all these attributes to my service's XSD but I'll go through the attributes in the response of the downstream service and whatever I'll find there will add them to my service's SOAP response.
The difficulty is that I use JAXB so Java XML beans are generated from the XSD. As the XML attributes are not in my service's XSD so somehow I should add them 'manually' (after the JAXB beans marshalled to XML (SOAP response)).
Is there a way of doing that please?
I use Spring & Spring Integration.
The outbound gateway is specified like
@Configuration
public class MppWebServiceGatewayConfig {
...
@Bean(name="serviceOutboundGateway")
public MessageHandler serviceOutboundGateway() {
final MarshallingWebServiceOutboundGateway gateway = new ExceptionHandlingMarshallingWebServiceOutboundGateway(url, mppMarshaller(), mppUnMarshaller());
gateway.setMessageSender(httpPoolingWebServiceMessageSender);
return gateway;
}
@Bean
public Marshaller mppMarshaller() {
final Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath(CONTEXTPATH);
return marshaller;
}
@Bean
public Unmarshaller mppUnMarshaller() {
final Jaxb2Marshaller unmarshaller = new Jaxb2Marshaller();
unmarshaller.setContextPath(CONTEXTPATH);
return unmarshaller;
}
...
}
Thanks!
答案1
得分: 0
我可能找到了一个答案,但它不够优雅,所以一般我不建议使用它,但有人可能会发现它有用:
@EnableWs
@Configuration
public class WebServiceConfig extends CommonWsConfigurerAdapter {
...
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(new CustomEndpointInterceptor());
}
}
@Component
class CustomEndpointInterceptor implements EndpointInterceptor {
...
@Override
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
String responseXmlString = toString(messageContext.getResponse());
Document doc = convertStringToDocument(responseXmlString);
// manipulting the response
...
// SaajSoapMessageFactory is thread safe so make sure the message factory is initialized only once
SaajSoapMessageFactory saajSoapMessageFactory = new SaajSoapMessageFactory();
saajSoapMessageFactory.afterPropertiesSet();
SaajSoapMessage saajSoapMessage = saajSoapMessageFactory.createWebServiceMessage();
saajSoapMessage.setDocument(doc);
messageContext.clearResponse();
messageContext.setResponse(saajSoapMessage);
return true;
}
...
private String toString(WebServiceMessage msg) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
return new String(out.toByteArray());
}
private Document convertStringToDocument(String xmlStr) throws Exception {
// also the DocumentBuilderFactory is supposed to be thread-safe
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse( new InputSource( new StringReader( xmlStr ) ) );
return doc;
}
}
英文:
I might have found an answer but it is not too elegant so generally I wouldn't recommend to use it but someone might find it useful:
@EnableWs
@Configuration
public class WebServiceConfig extends CommonWsConfigurerAdapter {
...
@Override
public void addInterceptors(List<EndpointInterceptor> interceptors) {
interceptors.add(new CustomEndpointInterceptor());
}
}
@Component
class CustomEndpointInterceptor implements EndpointInterceptor {
...
@Override
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
String responseXmlString = toString(messageContext.getResponse());
Document doc = convertStringToDocument(responseXmlString);
// manipulting the response
...
// SaajSoapMessageFactory is thread safe so make sure the message factory is initialized only once
SaajSoapMessageFactory saajSoapMessageFactory = new SaajSoapMessageFactory();
saajSoapMessageFactory.afterPropertiesSet();
SaajSoapMessage saajSoapMessage = saajSoapMessageFactory.createWebServiceMessage();
saajSoapMessage.setDocument(doc);
messageContext.clearResponse();
messageContext.setResponse(saajSoapMessage);
return true;
}
...
private String toString(WebServiceMessage msg) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
return new String(out.toByteArray());
}
private Document convertStringToDocument(String xmlStr) throws Exception {
// also the DocumentBuilderFactory is supposed to be thread-safe
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse( new InputSource( new StringReader( xmlStr ) ) );
return doc;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论