I have a problem processing a SOAP request. I can read everything from the envelope but the name space decorated parameter (cs:measurand) cannot be parsed.
Here you can find the SOAP Envelope:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:cs="urn://Ocpp/Cs/2012/06/" xmlns:soap-enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<cs:identity>17083A00001101</cs:identity>
<a:From>
<a:Address>http://172.0.0.0:9080</a:Address>
</a:From>
<a:MessageID>urn:uuid:xxxxxxxxxxxx</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To>http://172.0.0.0:8080/ws/ocp</a:To>
<a:Action>/MValues</a:Action>
</soap:Header>
<soap:Body>
<cs:mValuesRequest>
<cs:id>1</cs:id>
<cs:transactionId>1881</cs:transactionId>
<cs:values>
<cs:timestamp>2019-03-07T13:41:52.405Z</cs:timestamp>
<cs:value cs:measurand="e.a.i.r" cs:unit="Wh">300</cs:value>
<cs:value cs:measurand="c.i" cs:unit="Amp">38.5</cs:value>
<cs:value cs:measurand="v" cs:unit="Volt">399.5</cs:value>
<cs:value cs:measurand="p.a.i" cs:unit="W">15380</cs:value>
<cs:value cs:measurand="t" cs:unit="Celsius">35</cs:value>
</cs:values>
</cs:mValuesRequest>
</soap:Body>
</soap:Envelope>
Here is the service which receive the request:
#Action("/MValues")
#ResponsePayload
public JAXBElement<MValuesResponse> receive(#RequestPayload MValuesRequest request,
MessageContext messageContext) {
....
}
And here is the MValuesRequest:
...
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ValuesRequest", propOrder = {
"id",
"transactionId",
"values"
})
public class MValuesRequest {
protected int id;
protected Integer transactionId;
protected List<MValue> values;
// getters setters...
}
Any your thoughts would be really appreciated.
try with this,
MValuesRequest.java
#XmlRootElement(name="cs:mValuesRequest")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name ="ValuesRequest", propOrder = { "id", "transactionId", "values" })
public class MValuesRequest {
#XmlElement(name="cs:id")
protected int id;
#XmlElement(name="cs:transactionId")
protected Integer transactionId;
#XmlElement(name="cs:values")
protected Values values;
// getters and setters...
}
Values.java
#XmlRootElement(name="cs:values")
public class Values{
#XmlElement(name="cs:timestamp")
protected String timestamp;
#XmlElement(name="cs:value")
protected List<Value> value;
// getters and setters...
}
Value.java
#XmlRootElement(name="cs:value")
public class value{
#XmlAttribute(name="measurand" namespace="http://www.w3.org/XML/1998/namespace")
protected String measurand;
#XmlAttribute(name="unit" namespace="http://www.w3.org/XML/1998/namespace")
protected String unit;
#XmlValue
protected String elementValue;
// getters and setters...
}
I finally could solve this is issue, big thanks to Rathnayake.
I didn't have to add #XmlRootElement but only add the namespace parameter to #XmlAttribute.
So currently my XML parameters look like this:
#XmlAttribute(name = "context", namespace="urn://Ocpp/Cs/2012/06/")
protected ReadingContext context;
#XmlAttribute(name = "format", namespace="urn://Ocpp/Cs/2012/06/")
protected ValueFormat format;
#XmlAttribute(name = "measurand", namespace="urn://Ocpp/Cs/2012/06/")
protected Measurand measurand;
#XmlAttribute(name = "location", namespace="urn://Ocpp/Cs/2012/06/")
protected Location location;
#XmlAttribute(name = "unit", namespace="urn://Ocpp/Cs/2012/06/")
protected UnitOfMeasure unit;
Just to remember here is my SOAP header:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:cs="urn://Ocpp/Cs/2012/06/" xmlns:soap-enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
And I added as namespace="..." value xmlns:cs="..." from the header.
Related
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:cs=\"urn:CardServices\" xmlns:ebppif1=\"urn:PaymentServer\" xmlns:el=\"urn:ExtListsServices\" xmlns:iiacs=\"urn:IIACardServices\" xmlns:lm=\"urn:Limits\">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring></faultstring>
<detail>
<ebppif1:PaymentServerException>
<provider>RSW</provider>
<error>129</error>
<description>201433</description>
<screen>RSW129</screen>
</ebppif1:PaymentServerException>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How to create java object using #XmlRootElement,#XmlElement.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "Fault", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
#Data
public class FaultDto {
#XmlElement(name = "faultcode")
private String faultCode;
#XmlElement(name = "detail")
private DetailDto detail;
}
#XmlRootElement(name = "detail")
#XmlAccessorType(XmlAccessType.FIELD)
public class DetailDto {
#XmlElement(name = "PaymentServerException")
private PaymentExcepDto excepDto;
}
#XmlRootElement(name = "PaymentServerException")
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymentExcepDto {
#XmlElement(name = "provider")
protected String provider;
#XmlElement(name = "error")
protected String error;
//others
}
I am getting this result : FaultDto(faultCode=SOAP-ENV:Client, detail=DetailDto(excepDto=null))
How to catch PaymentServerException ?
I need help to convert the soap request and response to Java Object. So that I can marshal and un-marshal it.
Note: I am new to soap services and tried built in tool but not able to convert into Java Object.
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sen="http://schemas.xmlsoap.org/sendSmsMSDP" xmlns:met="http://schemas.xmlsoap.org/soap/MetaInfoReq">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>ravi</wsse:Username>
<wsse:Password>more</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<sen:SendSmsMSDPRequest>
<sen:MetaInfo>
<met:ConsumerReqInfo>
<met:circleId>1</met:circleId>
<met:serviceName>sendSmsMSDP_SV</met:serviceName>
<met:channelName>CG</met:channelName>
<met:segment>PREPAID</met:segment>
<met:key>345</met:key>
<met:version>1.0</met:version>
</met:ConsumerReqInfo>
</sen:MetaInfo>
<sen:SRVsendSmsMSDPReq>
<sen:requestType>SMSSubmitReq</sen:requestType>
<sen:userName>usernME</sen:userName>
<sen:password>PASSWORD</sen:password>
<sen:mobileNumber>XXXXXXXXXX</sen:mobileNumber>
<sen:message>hello</sen:message>
<sen:originAddress>0987</sen:originAddress>
<sen:type>0</sen:type>
</sen:SRVsendSmsMSDPReq>
</sen:SendSmsMSDPRequest>
</soapenv:Body>
</soapenv:Envelope>
Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sen="http://schemas.xmlsoap.org/soap/envelope/" xmlns:met="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<sen:SendSmsMSDPResponse>
<sen:MetaInfo>
<met:ConsumerReqInfo>
<met:circleId>123</met:circleId>
<met:serviceName>sendSmsMSDP_SV</met:serviceName>
<met:channelName>cc</met:channelName>
<met:segment>pre</met:segment>
<met:key>345</met:key>
<met:version>1.0</met:version>
</met:ConsumerReqInfo>
<met:StatusInfo>
<met:errorCode>WWI00000I</met:errorCode>
<met:errorStatus>0</met:errorStatus>
<met:errorDesc>The Request has been processed Successfully</met:errorDesc>
<met:errorCategory>SUCCESS</met:errorCategory>
</met:StatusInfo>
</sen:MetaInfo>
</sen:SendSmsMSDPResponse>
</soapenv:Body>
</soapenv:Envelope>
Also, if you know some resources for soap services that will be really helpful.
Thanks for your time.
**For Response **
Here is my classes but its failing.
#XmlRootElement(name = "SendSmsMSDPResponse")
#XmlAccessorType(XmlAccessType.FIELD)
public class SendSmsMSDPResponse {
#XmlElement(name = "MetaInfo")
private MetaInfo MetaInfo;
public MetaInfo getMetaInfo() {
return MetaInfo;
}
public void setMetaInfo(MetaInfo metaInfo) {
MetaInfo = metaInfo;
}
}
#XmlRootElement(name = "MetaInfo")
#XmlAccessorType(XmlAccessType.FIELD)
public class MetaInfo {
#XmlElement(name = "ConsumerReqInfo")
private ConsumerReqInfo ConsumerReqInfo;
#XmlElement(name = "StatusInfo")
private StatusInfo StatusInfo;
public ConsumerReqInfo getConsumerReqInfo() {
return ConsumerReqInfo;
}
public void setConsumerReqInfo(ConsumerReqInfo consumerReqInfo) {
ConsumerReqInfo = consumerReqInfo;
}
public StatusInfo getStatusInfo() {
return StatusInfo;
}
public void setStatusInfo(StatusInfo statusInfo) {
StatusInfo = statusInfo;
}
}
#XmlRootElement(name = "ConsumerReqInfo")
#XmlAccessorType(XmlAccessType.FIELD)
public class ConsumerReqInfo {
#XmlElement(name = "circleId")
private String circleId;
#XmlElement(name = "serviceName")
private String serviceName;
#XmlElement(name = "channelName")
private String channelName;
#XmlElement(name = "segment")
private String segment;
#XmlElement(name = "key")
private String key;
#XmlElement(name = "version")
private String version;
//setters and getters
}
#XmlRootElement(name = "StatusInfo")
#XmlAccessorType(XmlAccessType.FIELD)
public class StatusInfo {
#XmlElement(name = "errorCode")
private String errorCode;
#XmlElement(name = "errorStatus")
private String errorStatus;
#XmlElement(name = "errorDesc")
private String errorDesc;
#XmlElement(name = "errorCategory")
private String errorCategory;
// setters and getters
}
Hi guys i am trying to convert soap xml to java classes fields but response gives null values into targeted class fields. I haven't worked with soap before, I work with soap for the first time, so I did a bit of google in 2 days and tried to use it. Attached screenshots from intellij debug
It is a SOAP XML file. In fact this is the value of xml that comes to me as a response from another API because I got it via SOAPUI because I had a request for it. So I tried to convert this xml in a new project without working on a real project. I also mentioned the classes in this project below
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:queryTransactionHistoryResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="urn:IssuingWS/binding">
<ResponseInfo>
<response_code>0</response_code>
<error_description xsi:nil="true"/>
<error_action xsi:nil="true"/>
<EXTERNAL_SESSION_ID>TEST111_20211111111111212201191210111511</EXTERNAL_SESSION_ID>
</ResponseInfo>
<Details>
<row>
<item>
<name>CARD_ACCT</name>
<value>0901095000004266</value>
</item>
<item>
<name>ACCOUNT_NO</name>
<value>8186</value>
</item>
<item>
<name>CL_ACCT_KEY</name>
<value>8096</value>
</item>
<item>
<name>CLIENT</name>
<value>00003660</value>
</item>
</row>
<row>
<item>
<name>CARD2_ACCT</name>
<value>0901095000004266</value>
</item>
<item>
<name>ACCOUNTSSO</name>
<value>8186</value>
</item>
<item>
<name>CL_ACCT_KEY22</name>
<value>8096</value>
</item>
<item>
<name>SOMENAME</name>
<value>00003660</value>
</item>
</row>
</Details>
</ns1:queryTransactionHistoryResponse>
</soapenv:Body>
</soapenv:Envelope>
It is rootclass parent class got it from the name after ns1 in the XML, but I don't know if the situation I'm using is correct and one of the things I don't understand is the xmlns.
package uz.paynet.test.Xml;
import lombok.ToString;
import javax.xml.bind.annotation.*;
#ToString
#XmlRootElement(namespace = "urn:IssuingWS/binding")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "queryTransactionHistoryResponse")
public class QueryTransactionHistoryResponse {
#XmlElement(name = "ResponseInfo", required = true,nillable = true)
private ResponseInfo responseInfo;
#XmlElement(name = "Details", required = true,nillable = true)
private Details details;
public QueryTransactionHistoryResponse() {
}
public QueryTransactionHistoryResponse(ResponseInfo responseInfo, Details details) {
this.responseInfo = responseInfo;
this.details = details;
}
public ResponseInfo getResponseInfo() {
return responseInfo;
}
public void setResponseInfo(ResponseInfo responseInfo) {
this.responseInfo = responseInfo;
}
public Details getDetails() {
return details;
}
public void setDetails(Details details) {
this.details = details;
}
}
it is my ResponseInfo class but this class get value you show on screenshop
package uz.paynet.test.Xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.FIELD)
public class ResponseInfo{
#XmlElement(name = "response_code")
private int responseCode;
#XmlElement(name = "error_description",nillable = true)
private String errorDescription;
#XmlElement(name="error-action",nillable = true)
private String errorAction;
#XmlElement(name = "EXTERNAL_SESSION_ID")
private String externalSessionId;
public ResponseInfo(int responseCode, String errorDescription, String errorAction, String externalSessionId) {
this.responseCode = responseCode;
this.errorDescription = errorDescription;
this.errorAction = errorAction;
this.externalSessionId = externalSessionId;
}
public ResponseInfo() {
}
public int getResponseCode() {
return responseCode;
}
public void setResponseCode(int responseCode) {
this.responseCode = responseCode;
}
public String getErrorDescription() {
return errorDescription;
}
public void setErrorDescription(String errorDescription) {
this.errorDescription = errorDescription;
}
public String getErrorAction() {
return errorAction;
}
public void setErrorAction(String errorAction) {
this.errorAction = errorAction;
}
public String getExternalSessionId() {
return externalSessionId;
}
public void setExternalSessionId(String externalSessionId) {
this.externalSessionId = externalSessionId;
}
}
this is Details class which Covers Row class
package uz.paynet.test.Xml;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import java.util.List;
#XmlAccessorType(XmlAccessType.FIELD)
public class Details{
#XmlElement(name = "row")
List<Row> rowList;
public Details() {
}
public Details(List<Row> rowList) {
this.rowList = rowList;
}
public List<Row> getRowList() {
return rowList;
}
public void setRowList(List<Row> rowList) {
this.rowList = rowList;
}
}
and last is Row class which covered value and name
which i need to get xml value and name
package uz.paynet.test.Xml;
import javax.xml.bind.annotation.*;
import java.io.Serializable;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(namespace = "urn:IssuingWS/binding")
public class Row {
#XmlElement(name = "name")
public String name;
#XmlElement(name = "value")
private String value;
public Row(String name, String value) {
this.name = name;
this.value = value;
}
public Row() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
I'm new to SOAP service, this is my output and java class detail.
How to add the blank xmlns in sub level class?
Out-Put Request:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sendEmail xmlns="http://ws.cns.channel.sendnotification.sdfsfds.com/">
<EmailNotificationRequest>
<requestHeader>
<channel>fsdfs</channel>
<subChannel>sdfds</subChannel>
<systemName>sdfsd</systemName>
<applicationName>dsfs</applicationName>
</requestHeader>
</EmailNotificationRequest>
</sendEmail>
Package Class
#javax.xml.bind.annotation.XmlSchema(namespace = "http://ws.cns.channel.sendnotification.sdfsfds.com/",
elementFormDefault = XmlNsForm.QUALIFIED
)
package com.etisalat.sendnotification.channel.cns.ws;
import javax.xml.bind.annotation.XmlNsForm;
Request Header Class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "requestHeader", propOrder = {
"channel",
"subChannel",
"agentID",
"systemName",
"applicationName",
"hostID",
"requestDate"
})
public class RequestHeader {
#XmlElement(required = true)
protected String channel;
protected String subChannel;
protected String agentID;
#XmlElement(required = true)
protected String systemName;
protected String applicationName;
}
Required Input Request
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sendEmail xmlns="http://ws.cns.channel.sendnotification.sdfsfds.com/">
<EmailNotificationRequest>
<requestHeader xmlns="">
<channel>fsdfs</channel>
<subChannel>sdfds</subChannel>
<systemName>sdfsd</systemName>
<applicationName>dsfs</applicationName>
</requestHeader>
</EmailNotificationRequest>
</sendEmail>
I am having issues marshalling a bean into XML using JAXB. I have multiple REST API endpoints and I want to return a uniform response from all the endpoints, like the following:
<response>
<responseHeader> <!-- this will be same for all the end points -->
<status>OK</status>
<stausCode>AB-123<statusCode>
</responseHeader>
<responseBody>
<!-- contains end point specific data, could be differnet-->
</responseBody>
</response>
So what I did is created a generic response DTO:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "response")
public class GenericResponseDto implements Serializable {
#XmlElement(name="responseHeader")
private GenericResponseHeaderDto responseHeader;
#XmlAnyElement(name="responseBody")
private Object responseBody;
public GenericResponseHeaderDto getResponseHeader() {
return responseHeader;
}
public void setResponseHeader(GenericResponseHeaderDto responseHeader) {
this.responseHeader = responseHeader;
}
public Object getResponseBody() {
return responseBody;
}
public void setResponseBody(Object responseBody) {
this.responseBody = responseBody;
}
}
Where the response body field will be replaced by the following object for one of the endpoint responses:
#XmlRootElement(name = "responseBody")
#XmlAccessorType(XmlAccessType.FIELD)
public class Person implements Serializable {
#XmlElement(required = false)
private String phoneNumber;
#XmlElement(required = false)
private Integer personId;
public Integer getPersonId() {
return personId;
}
public void setPersonId(Integer personId) {
this.personId = personId;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
Here is my Jersey endpoint:
#POST
#Path("/myAPIFirstEndPoint")
#Produces({MediaType.APPLICATION_XML})
public GenericResponseDto myAPIFirstEndPoint(ABC abc) {
// some work and getting person dto
Person person = someWork.doWork();
GenericResponseDto genericResponseDto = new GenericResponseDto();
// not setting any responseHeader for now, so ignore
genericResponseDto.setResponseBody(row);
return genericResponseDto;
}
But it's not working as expected. The toString() method is being called on the Person object, instead of it being marshalled to XML. I'm getting the following incorrect response:
<?xml version="1.0" encoding="UTF-8" ?>
<response>
<responseBody>
path.to.package.Person#36af3690[phoneNumber=+123456789,personId=-1]
</responseBody>
</response>
Can you please tell me what I'm doing wrong? I am using Jersey and JAXB with Spring.
EDIT:
Introduced generics:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "response")
#XmlSeeAlso({Person.class})
public class GenericResponseDto<T> implements Serializable {
#XmlElement(name="responseHeader")
private GenericResponseHeaderDto responseHeader;
#XmlElement(name="responseBody")
private T responseBody;
public GenericResponseHeaderDto getResponseHeader() {
return responseHeader;
}
public void setResponseHeader(GenericResponseHeaderDto responseHeader) {
this.responseHeader = responseHeader;
}
public T getResponseBody() {
return responseBody;
}
public void setResponseBody(T responseBody) {
this.responseBody = responseBody;
}
}
changed Jersey endpoint as follows:
#POST
#Path("/myAPIFirstEndPoint")
#Produces({MediaType.APPLICATION_XML})
public GenericResponseDto<Person> myAPIFirstEndPoint(ABC abc) {
// some work and getting person dto
Person person = someWork.doWork();
GenericResponseDto<Person> genericResponseDto = new GenericResponseDto<Person>();
// not setting any responseHeader for now, so ignore
genericResponseDto.setResponseBody(row);
return genericResponseDto;
}
Still getting the same response as mentioned above.
Now getting this response, after adding #XmlSeeAlso({Person.class}) in GenericResponseDto
<?xml version="1.0" encoding="UTF-8" ?>
<response>
<responseBody xsi:type="Person">
<phoneNumber>+923454502dd0559</phoneNumber>
<personId>-1</personId>
<token />
</responseBody>
</response>