I'm trying to unmarshal a XML with JAXB to convert it into an object, but the SOAPPArt, SOAPEnvelope and the SOAPBody are coming null I don't know why..
I've tried to unmarshal without the SOAPMessage as well but with no success.
Here is the XML i'm trying to unmarshal:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ObjectXmlResponse
xmlns="http://tempuri.org/testing">
<ResultadoXml xmlns="www.site.com.br">
<CodigoOperacao>dsadsdas</CodigoOperacao>
<OperacoesObjetoAnalise />
<Respostas>
<Resposta Final="true">
<Sistema>dsadfd</Sistema>
<Criterio>fdsfdsf</Criterio>
<Resposta>.</Resposta>
</Resposta>
</Respostas>
</ResultadoXml>
</ObjectXmlResponse>
</soap:Body>
</soap:Envelope>
Here are the classes:
#XmlRootElement(name="ObjectXmlResponse", namespace="http://tempuri.org/testing")
#XmlAccessorType(XmlAccessType.FIELD)
public class ObjectXmlResponse {
#XmlElement(name="ResultadoXml", namespace="www.site.com.br")
private ResultadoXml resultadoXml;
public ResultadoXml getResultadoXml() {
return resultadoXml;
}
public void setResultadoXml(ResultadoXml resultadoXml) {
this.resultadoXml = resultadoXml;
}
}
#XmlRootElement(name="ResultadoXml", namespace="www.site.com.br")
#XmlAccessorType(XmlAccessType.FIELD)
public class ResultadoXml {
private static final long serialVersionUID = 1L;
#XmlElement(name="CodigoOperacao")
private String codigoOperacao;
#XmlElement(name="OperacoesObjetoAnalise")
private String OperacoesObjetoAnalise;
#XmlElement(name="Respostas")
private Respostas respostas;
#XmlElement(name="Drivers")
private Drivers drivers;
public String getCodigoOperacao() {
return codigoOperacao;
}
public void setCodigoOperacao(String codigoOperacao) {
this.codigoOperacao = codigoOperacao;
}
public Respostas getRespostas() {
return respostas;
}
public void setRespostas(Respostas respostas) {
this.respostas = respostas;
}
public Drivers getDrivers() {
return drivers;
}
public void setDrivers(Drivers drivers) {
this.drivers = drivers;
}
public String getOperacoesObjetoAnalise() {
return OperacoesObjetoAnalise;
}
public void setOperacoesObjetoAnalise(String operacoesObjetoAnalise) {
OperacoesObjetoAnalise = operacoesObjetoAnalise;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public String toString(){
return "ResultadoXml [codigoOperacao=" + codigoOperacao +"]";
}
}
And here is the unmarshal:
public static void main(String[] args) {
JAXBContext jaxbContext;
try {
String relatorio = <the xml>;
InputStream is = new ByteArrayInputStream(relatorio.getBytes());
SOAPMessage message = MessageFactory.newInstance().createMessage(null, is);
SOAPPart sp = message.getSOAPPart();
SOAPEnvelope env = sp.getEnvelope();
SOAPBody bdy = env.getBody();
jaxbContext = JAXBContext.newInstance(ObjectXmlResponse.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ObjectXmlResponse response = (ObjectXmlResponse) jaxbUnmarshaller.unmarshal(new StringReader(relatorio));
System.out.println(response);
} catch(Exception ex) {
ex.printStackTrace();
}
System.exit(0);
}
I need to populate ObjectXmlResponse object and its attributes, like ResultadoXml.
Specify the namespace on all elements (or use #XmlSchema on the package) and unmarshall the SOAP body content using
ObjectXmlResponse response = (ObjectXmlResponse) jaxbUnmarshaller.unmarshal(bdy.extractContentAsDocument());
Related
I have soap-to-soap proxy server in spring using org.springframework.ws.* Both sides have identical wsdls.
I am able to pass the success response from external service to proxy consumer however there's a problem when fault message from external service gets returned.
The problem is my proxy server removes soap detail from the original response (I have no idea why). My goal is to pass the response from external service just as it is to proxy client without shortening. Anyone could help how to avoid fault detail being deleted ? Thank you in advance.
External Server response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Fault occurred while processing.</faultstring>
<detail>
<ns2:getCFUSubscriberStateFaultBusiness xmlns="example.system.messaging.common.v1.datatypes" xmlns:ns2="example.system.ot.managepcccfu.v2.datatypes">
<ns2:messageContext>
<requestId>273140800423344000</requestId>
<transactionId>8200</transactionId>
<timeLeft>10000</timeLeft>
<timestamp>2022-09-30T14:08:00</timestamp>
<user>x_turan</user>
<consumingComponent>urn:example.business.intr:SELFCARE3.</consumingComponent>
<providingService>urn:example.system.ot.managepccprovisioning.v1.service:ManagePccProvisioning</providingService>
<providingOperation>modifycontroffer</providingOperation>
</ns2:messageContext>
<ns2:messageDataBusinessException>
<errorCode>3001</errorCode>
<errorMessage>ESE Problem</errorMessage>
</ns2:messageDataBusinessException>
</ns2:getCFUSubscriberStateFaultBusiness>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Proxy Client Receives:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring xml:lang="en">Fault occurred while processing.</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Endpoint:
#Endpoint
public class ServiceEndpoint {
public static final String NAMESPACE_URI="example.system.ot.managepcccfu.v2.datatypes";
#Autowired
CFUSoapClient soapClient;
#PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCFUSubscriberState" )
#ResponsePayload
public GetCFUSubscriberStateResponse getCFUSubscriberState(#RequestPayload GetCFUSubscriberState request) throws GetCFUSubscriberStateFaultBusinessMessage, GetCFUSubscriberStateFaultSystemMessage {
final GetCFUSubscriberStateResponse response = soapClient.getCFUSubscriberStateResponse(request);
return response;
}
}
Soap Client:
public class CFUSoapClient extends WebServiceGatewaySupport {
public GetCFUSubscriberStateResponse getCFUSubscriberStateResponse(GetCFUSubscriberState request) throws GetCFUSubscriberStateFaultBusinessMessage {
Object response = getWebServiceTemplate().marshalSendAndReceive(request);
return (GetCFUSubscriberStateResponse) response;
}
}
Config:
#Configuration
#EnableWs
public class Config extends WsConfigurerAdapter {
#Bean
public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
MessageDispatcherServlet servlet = new MessageDispatcherServlet();
servlet.setApplicationContext(applicationContext);
return new ServletRegistrationBean(servlet, "/ws/CFU/*");
}
#Bean(name="CFU")
public Wsdl11Definition defaultWsdl11Definition() {
SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
wsdl11Definition.setWsdl(new ClassPathResource("/wsdl/CFU.wsdl"));
return wsdl11Definition;
}
#Bean(name = "cfuDatatypesV2")
public XsdSchema cfuDatatypesV2() {
return new SimpleXsdSchema(
new ClassPathResource("wsdl/cfuDatatypesV2.xsd"));
}
#Bean(name = "common")
public XsdSchema common() {
return new SimpleXsdSchema(
new ClassPathResource("wsdl/common.xsd"));
}
#Bean
public Jaxb2Marshaller marshaller() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath("com.ot.cfu");
return jaxb2Marshaller;
}
#Bean
public CFUSoapClient soapClient() {
CFUSoapClient client = new CFUSoapClient();
client.setDefaultUri("http://localhost:41420/CFU");
client.setMarshaller(marshaller());
client.setUnmarshaller(marshaller());
// ClientInterceptor [] interceptors = new ClientInterceptor[]{new SoapClientInterceptor()};
// client.setInterceptors(interceptors);
return client;
}
}
After hours I managed to workaround this issue following wsdl definition and implemented custom exception classes wrapping the wsdl generated fault details:
#WebFault(name = "getCFUSubscriberStateFaultBusiness", targetNamespace = "example.system.ot.managepcccfu.v2.datatypes")
public class GetCFUSubscriberStateFaultBusinessMessage extends Exception {
private GetCFUSubscriberStateFaultBusiness getCFUSubscriberStateFaultBusiness;
public GetCFUSubscriberStateFaultBusinessMessage() {
super();
}
public GetCFUSubscriberStateFaultBusinessMessage(String message) {
super(message);
}
public GetCFUSubscriberStateFaultBusinessMessage(String message, java.lang.Throwable cause) {
super(message, cause);
}
public GetCFUSubscriberStateFaultBusinessMessage(String message, GetCFUSubscriberStateFaultBusiness getCFUSubscriberStateFaultBusiness) {
super(message);
this.getCFUSubscriberStateFaultBusiness = getCFUSubscriberStateFaultBusiness;
}
public GetCFUSubscriberStateFaultBusinessMessage(String message, GetCFUSubscriberStateFaultBusiness getCFUSubscriberStateFaultBusiness, java.lang.Throwable cause) {
super(message, cause);
this.getCFUSubscriberStateFaultBusiness = getCFUSubscriberStateFaultBusiness;
}
public GetCFUSubscriberStateFaultBusiness getFaultInfo() {
return this.getCFUSubscriberStateFaultBusiness;
}
}
#WebFault(name = "getCFUSubscriberStateFaultSystem", targetNamespace = "example.system.ot.managepcccfu.v2.datatypes")
public class GetCFUSubscriberStateFaultSystemMessage extends Exception {
private GetCFUSubscriberStateFaultSystem getCFUSubscriberStateFaultSystem;
public GetCFUSubscriberStateFaultSystemMessage() {
super();
}
public GetCFUSubscriberStateFaultSystemMessage(String message) {
super(message);
}
public GetCFUSubscriberStateFaultSystemMessage(String message, java.lang.Throwable cause) {
super(message, cause);
}
public GetCFUSubscriberStateFaultSystemMessage(String message, GetCFUSubscriberStateFaultSystem getCFUSubscriberStateFaultSystem) {
super(message);
this.getCFUSubscriberStateFaultSystem = getCFUSubscriberStateFaultSystem;
}
public GetCFUSubscriberStateFaultSystemMessage(String message, GetCFUSubscriberStateFaultSystem getCFUSubscriberStateFaultSystem, java.lang.Throwable cause) {
super(message, cause);
this.getCFUSubscriberStateFaultSystem = getCFUSubscriberStateFaultSystem;
}
public GetCFUSubscriberStateFaultSystem getFaultInfo() {
return this.getCFUSubscriberStateFaultSystem;
}
}
I filled the received soap fault detail into exception placeholder upon SoapFaultClientException based on type of detail:
public class CFUSoapClient extends WebServiceGatewaySupport {
public GetCFUSubscriberStateResponse getCFUSubscriberStateResponse(GetCFUSubscriberState request) throws GetCFUSubscriberStateFaultBusinessMessage, IOException, GetCFUSubscriberStateFaultSystemMessage {
try {
return (GetCFUSubscriberStateResponse) getWebServiceTemplate().marshalSendAndReceive(request);
} catch (SoapFaultClientException e) {
final Iterator<SoapFaultDetailElement> detailEntries = e.getSoapFault().getFaultDetail().getDetailEntries();
if (detailEntries.hasNext()) {
final SoapFaultDetailElement next = detailEntries.next();
final Source source = next.getSource();
final Object faultDetail = getWebServiceTemplate().getUnmarshaller().unmarshal(source);
if (faultDetail instanceof GetCFUSubscriberStateFaultBusiness) {
throw new GetCFUSubscriberStateFaultBusinessMessage(e.getSoapFault().getFaultStringOrReason(), (GetCFUSubscriberStateFaultBusiness) faultDetail, e.getCause());
} else if (faultDetail instanceof GetCFUSubscriberStateFaultSystem) {
throw new GetCFUSubscriberStateFaultSystemMessage(e.getSoapFault().getFaultStringOrReason(), (GetCFUSubscriberStateFaultSystem) faultDetail, e.getCause());
}
}
throw new RuntimeException("Unexpected error", e);
}
}
}
Eventually, I marshalled the details in the resolver class:
#Component
public class Resolver extends AbstractEndpointExceptionResolver {
private final Jaxb2Marshaller marshaller;
#Autowired
public Resolver(Jaxb2Marshaller marshaller) {
this.marshaller = marshaller;
}
#Override
protected boolean resolveExceptionInternal(MessageContext messageContext, Object endpoint, Exception e) {
if (e instanceof GetCFUSubscriberStateFaultBusinessMessage) {
final GetCFUSubscriberStateFaultBusinessMessage getCFUSubscriberStateFaultBusinessMessage = (GetCFUSubscriberStateFaultBusinessMessage) e;
final GetCFUSubscriberStateFaultBusiness faultInfo = getCFUSubscriberStateFaultBusinessMessage.getFaultInfo();
final Result result = createFaultDetailResult(messageContext, getCFUSubscriberStateFaultBusinessMessage);
marshaller.marshal(faultInfo, result);
return true;
} else if (e instanceof GetCFUSubscriberStateFaultSystemMessage) {
final GetCFUSubscriberStateFaultSystemMessage getCFUSubscriberStateFaultSystemMessage = (GetCFUSubscriberStateFaultSystemMessage) e;
final GetCFUSubscriberStateFaultSystem faultInfo = getCFUSubscriberStateFaultSystemMessage.getFaultInfo();
final Result result = createFaultDetailResult(messageContext, getCFUSubscriberStateFaultSystemMessage);
marshaller.marshal(faultInfo, result);
return true;
}
return false;
}
private Result createFaultDetailResult(MessageContext messageContext, Exception exception) {
final SoapMessage response = (SoapMessage) messageContext.getResponse();
final SoapBody soapBody = response.getSoapBody();
final SoapFault soapFault = soapBody.addServerOrReceiverFault(exception.getMessage(), Locale.ENGLISH);
final SoapFaultDetail faultDetail = soapFault.addFaultDetail();
return faultDetail.getResult();
}
}
While parsing response in Soap Services use of Retrofit iam facing this exception.My exception is below
Failure: org.simpleframework.xml.core.ElementException: Element 'Body' does not have a match in class org.cainfo.arun.model.response.VerifyMobileResEnvelopeModel at line 1
Here is my request and response
My Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.router.ees.com/">
<soapenv:Header/>
<soapenv:Body>
<web:verifyMobile>
<arg0>12345678</arg0>
</web:verifyMobile>
</soapenv:Body>
</soapenv:Envelope>
My Response
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:verifyMobileResponse xmlns:ns1="http://webservice.router.ees.com/">
<return>name</return>
</ns1:verifyMobileResponse>
</soap:Body>
</soap:Envelope>
VerifyMobileResEnvelopeModel
#Root(name = "soap:Envelope")
#Namespace( prefix = "soap", reference = "http://schemas.xmlsoap.org/soap/envelope/")
public class VerifyMobileResEnvelopeModel {
#Element(name = "soap:Body", required = false)
private VerifyMobileResBodyModel verifyMobileResBodyModel;
public VerifyMobileResBodyModel getVerifyMobileResBodyModel() {
return verifyMobileResBodyModel;
}
public void setBody(VerifyMobileResBodyModel verifyMobileResBodyModel) {
this.verifyMobileResBodyModel = verifyMobileResBodyModel;
}
}
VerifyMobileResBodyModel
#Root(name = "soap:Body", strict = false)
public class VerifyMobileResBodyModel {
#Element(name = "ns1:verifyMobileResponse", required = false)
#Namespace(prefix = "ns1", reference = "http://webservice.router.ees.com/")
private VerifyMobileResDataModel verifyMobileResModel;
public VerifyMobileResDataModel getVerifyMobileResModel() {
return verifyMobileResModel;
}
public void setVerifyMobileResModel(VerifyMobileResDataModel verifyMobileResModel) {
this.verifyMobileResModel = verifyMobileResModel;
}
}
VerifyMobileResDataModel
#Root(name = "ns1:verifyMobileResponse", strict = false)
#Namespace(prefix = "ns1", reference = "http://webservice.router.ees.com/")
public class VerifyMobileResDataModel {
#Element(name = "return", required = false)
private String customerName;
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
}
Method
public void getResponse() {
VerifyMobileRqstDataModel mVerifyMobileRqstDataModel = new VerifyMobileRqstDataModel();
mVerifyMobileRqstDataModel.phoneNo = mobileNo;
VerifyMobileRqstBodyModel mVerifyMobileRqstBodyModel = new VerifyMobileRqstBodyModel();
mVerifyMobileRqstBodyModel.verifyMobileRqstDataModel = mVerifyMobileRqstDataModel;
VerifyMobileRqstEnvelopeModel mVerifyMobileRqstEnvelopeModel = new VerifyMobileRqstEnvelopeModel();
mVerifyMobileRqstEnvelopeModel.verifyMobileRqstBodyModel = mVerifyMobileRqstBodyModel;
Call<VerifyMobileResEnvelopeModel> call = webService.rqstVerifyMobileNo(mVerifyMobileRqstEnvelopeModel);
call.enqueue(new Callback<VerifyMobileResEnvelopeModel>() {
#Override
public void onResponse(Call<VerifyMobileResEnvelopeModel> call, Response<VerifyMobileResEnvelopeModel> response) {
if (response.isSuccessful() && response.body() != null) {
// String customerName = response.body().verifyMobileResBodyModel.verifyMobileResModel.customerName;
String customerName = response.body().getBody().getVerifyMobileResModel().getCustomerName();
Log.i("CustomerName", customerName);
}
}
#Override
public void onFailure(Call<VerifyMobileResEnvelopeModel> call, Throwable t) {
Log.e("Failure", t.getMessage());
}
});
}
I am facing some parsing issue. But getting the respone. In the method its not coming to response block, failure block get executed and it throws this exception. Its cumbersome to find out issue. I tried a lot. Please anyone help me. Thanks in advance.
Response in my code. But it didn't come inside the response block
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:verifyMobileResponse xmlns:ns1="http://webservice.router.ees.com/">
<return>Ramesh</return>
</ns1:verifyMobileResponse>
</soap:Body>
</soap:Envelope>
Its too late though but this might help some poor soul like me, I have faced similar issue. Try by setting "strict = false" in root tag of ResponseBody as follows
#Root(name = "soap:Envelope", strict = false)
#Namespace( prefix = "soap", reference = "http://schemas.xmlsoap.org/soap/envelope/")
public class VerifyMobileResEnvelopeModel { #Element(name = "soap:Body", required = false)
private VerifyMobileResBodyModel verifyMobileResBodyModel;
public VerifyMobileResBodyModel getVerifyMobileResBodyModel() {
return verifyMobileResBodyModel; }
public void setBody(VerifyMobileResBodyModel verifyMobileResBodyModel) {
this.verifyMobileResBodyModel = verifyMobileResBodyModel; } }
I have a jax-ws client ganerated with CXF
The request have a string-parameter (MGRequest) that contains an xml, all work's but the generated request is like this:
<S:Body>
<ns5:MGRequest><mytag>hello</mytag></ns5:MGRequest>
</S:Body>
I need to generate the body like:
<S:Body>
<ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest>
</S:Body>
(because i can't control the server..)
The client is like a standard jax-ws:
#WebService(name = "ServiceSoap")
#XmlSeeAlso({ ObjectFactory.class})
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface ServiceSoap {
#WebMethod(operationName = "ProcessMessage")
#WebResult(name = "MGResponse")
public String processMessage(
#WebParam(partName = "input", name = "MGRequest") String input);
}
And i call like this:
Service client = new Service(url);
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler()));
ServiceSoap service = client.getServiceSoap();
String msgToSend = JaxbUtil.jaxbObjToString(xmlObj, false);
String response = service.processMessage(msgToSend);
I have tried adding #XmlJavaTypeAdapter(CDataAdapter.class) before #WebParam but the result was:
<S:Body>
<ns5:MGRequest><![CDATA[<mytag>hello</mytag>]]></ns5:MGRequest>
</S:Body>
Where CDataAdapter:
public class CDataAdapter extends XmlAdapter<String, String> {
#Override
public String marshal(String v) throws Exception {
return "<![CDATA[" + v + "]]>";
}
#Override
public String unmarshal(String v) throws Exception {
return v;
}
}
Any idea how to archive that?
Thanks
After a working night i've found the solution:
adding a javax.xml.ws.handler.Handler to the client like this:
client.setHandlerResolver(HandlerFactory.build(new LoggerHandler(), new CDataHandler()));
where my HandlerFactory build a Handler:
public static HandlerResolver build(final Handler... handlers) {
return new HandlerResolver() {
#Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
if (handlers != null) {
for (Handler handler : handlers) {
handlerChain.add(handler);
}
}
return handlerChain;
}
};
}
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class CDataHandler implements SOAPHandler<SOAPMessageContext> {
#Override
public void close(MessageContext context) {
}
#Override
public boolean handleMessage(SOAPMessageContext soapMessage) {
try {
SOAPMessage message = soapMessage.getMessage();
boolean isOutboundMessage = (Boolean) soapMessage
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
// is a request?
if (isOutboundMessage) {
// build a CDATA NODE with the text in the root tag
Node cddata = (Node) message.getSOAPPart().createCDATASection(
message.getSOAPBody().getFirstChild().getTextContent());
// add the CDATA's node at soap message
message.getSOAPBody().getFirstChild().appendChild(cddata);
// remove the text tag with the raw text that will be escaped
message.getSOAPBody().getFirstChild()
.removeChild(message.getSOAPBody().getFirstChild().getFirstChild());
}
} catch (Exception ex) {
// fail
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext soapMessage) {
return true;
}
#Override
public Set<QName> getHeaders() {
return Collections.EMPTY_SET;
}
}
This is a simple class, i had only one tag with text, but in more complex scenario you can take the necessary action navigating the DOM.
I am newbie in JAVA programming and trying to convert XML to JAVA using the below snipet.
Input File:
<?xml version="1.0" encoding="UTF-8"?>
-<ns0:MT_ECCJDBC xmlns:ns0="urn:xml:json">
-<REQUEST>
<ID>46565665</ID>
</REQUEST>
</ns0:MT_ECCJDBC>
The output :
{
"#xmlns:ns0": "urn:xml:json",
"REQUEST": ["46565665"]
}
The expected output in JSON is
{
"REQUEST":
{
" ID " : ["46565665"]
}
}
Below is my java code :
public class ConversionXMLtoJSON {
public static void main(String[] args) throws Exception {
{
InputStream is = ConversionXMLtoJSON.class.getResourceAsStream("instance.xml");
String xml = IOUtils.toString(is);
XMLSerializer xmlSerializer = new XMLSerializer();
JSON json = xmlSerializer.read( xml );
System.out.println( json.toString(2) );
}
}
}
Please suggest me to add in the code
To remove the tag "#xmlns:ns0": "urn:xml:json",
To add the ID element in the JAVA code.
Regards
You can map the XML into Java objects and then use JSON generator to generate the JSON. I like to use jackson-mapper-asl, jackson-core-asl and jackson-dataformat-xml.
To bind the XML to Java:
public class XmlRequest {
#JacksonXmlElementWrapper(localName="REQUEST")
private REQUEST request;
public static class REQUEST {
#JacksonXmlProperty(localName="ID")
protected int ID;
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
}
public REQUEST getRequest() {
return request;
}
public void setRequest(REQUEST request) {
this.request = request;
}
}
To Generate the JSON:
XmlMapper mapper = new XmlMapper();
XmlRequest request = (XmlRequest) mapper.readValue(App.class.getResourceAsStream("/NewFile.xml"), XmlRequest.class);
StringWriter sw = new StringWriter();
JsonGenerator jsongen = new JsonFactory().createJsonGenerator(System.out);
jsongen.writeStartObject();
jsongen.writeFieldName("REQUEST");
jsongen.writeStartObject();
jsongen.writeFieldName("ID");
jsongen.writeStartArray();
jsongen.writeNumber(request.getRequest().getID());
jsongen.writeEndArray();
jsongen.writeEndObject();
jsongen.writeEndObject();
jsongen.close();
I have written custom soaphandler class which extends javax.xml.rpc.GenericHandler. And my requirement is to pass a primitive variable into this handler class from my other caller java class. This variable should pass at run time and should be thread safe because multiple thread is going to access that handler same time.
I tried to store the value into HandlerConfig object and injected it to the HandlerInfo, but I couldn't found this value in my handler.
This Soap Handler concept is new for me, so please help me to fix this issue.
below I'm posting my raw code for handler class and the class from where I'm calling it.
public class MilerHandler extends GenericHandler {
private HandlerInfo info;
private static final String AUTHORIZATION = "Authorization";
private static final String DATE = "Date";
private static final String URI = "http://-----.com";
public MilerHandler() {
}
public void init(HandlerInfo info) {
this.info = info;
}
public QName[] getHeaders() {
return info.getHeaders();
}
public boolean handleRequest(MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext)context;
SOAPMessage message = smc.getMessage();
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPFactory factory = SOAPFactory.newInstance();
SOAPElement authorization = factory.createElement(AUTHORIZATION, PCMilerClientService.PREFIX, URI);
SOAPElement date = factory.createElement(DATE, PCMilerClientService.PREFIX, URI);
authorization.addTextNode((String)value1); //Value1 need to be pass from my business class.
date.addTextNode((int)value2); //Value2 need to be pass from my business class.
SOAPElement authHeader = factory.createElement(PCMilerClientService.AUTH_HEADER, PCMilerClientService.PREFIX, URI);
authHeader.addChildElement(authorization);
authHeader.addChildElement(date);
SOAPHeader header = envelope.getHeader();
header.addChildElement(authHeader);
message.saveChanges();
if(log.debug()) {
log.debug(message);
}
}
catch (Exception ex) {
log.error(ex);
}
return true;
}
public boolean handleResponse(javax.xml.rpc.handler.MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext)context;
SOAPMessage message = smc.getMessage();
if(log.debug()) {
log.debug(message);
}
return true;
}
public boolean handleFault(javax.xml.rpc.handler.MessageContext context) {
SOAPMessageContext smc = (SOAPMessageContext)context;
SOAPMessage message = smc.getMessage();
if(log.debug()) {
log.debug(message);
}
return true;
}
}
public class MilerDistanceLookupWorker {
public void run() {
IService_Stub stub = null;
Service_Impl impl = null;
try {
impl = new Service_Impl();
setPCMilerHandler(impl);
stub = (IService_Stub) impl.getBasicHttpBinding_IService();
} catch (ServiceException e) {
-----------------
}
}
private void setMilerHandler(Service_Impl impl) {
HandlerInfo handlerInfo = new HandlerInfo();
handlerInfo.setHandlerClass(MilerHandler.class);
QName authHeader = new QName(NAMESPACE, AUTH_HEADER, PREFIX);
List<HandlerInfo> headerList = impl.getHandlerRegistry().getHandlerChain(authHeader);
headerList.add(handlerInfo);
impl.getHandlerRegistry().setHandlerChain(authHeader, headerList);
}
}
If you are trying to implement SOAP auth handler then you need to do something like this:
public class SOAPAuthenticationHandler implements SOAPHandler<SOAPMessageContext> {
private String username;
private String password;
public SOAPAuthenticationHandler (String username, String password) {
this.username = username;
this.password = password;
}
#Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!outboundProperty) {
return outboundProperty;
}
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
security.addNamespaceDeclaration("common", "some xmlns");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement usernameElement = usernameToken.addChildElement("Username", "wsse");
usernameElement.addTextNode(username);
SOAPElement passwordElement = usernameToken.addChildElement("PasswordSaltedDigest", "common");
passwordElement.setAttribute("Type", "http://www.w3.org/2001/04/xmldsig-more#gostr341194");
passwordElement.addTextNode(password);
} catch (SOAPException | DOMException e) {
getLogger().error(e.getMessage());
}
return outboundProperty;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
#Override
public void close(MessageContext context) {
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
And after that you need to add this handler to port' HandlerChain:
List handlerChain = ((BindingProvider) port).getBinding().getHandlerChain();
if (handlerChain == null) {
handlerChain = new ArrayList();
}
handlerChain.add(new SOAPAuthenticationHandler(username, password));
((BindingProvider) port).getBinding().setHandlerChain(handlerChain);