WSO2 ESB problem with convert xml to json - wso2

I use property mediator to convert xml to json <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
It's work, but when the xml message contains a number like 50103015080000000550022052 then after converting to json the value changes to 5.010301508E25.
I need to have the original value. Any idea how to do this?
Thanks in advance.

This happens due to the auto primitive feature available with the wso2 ESB servers. Here when a conversion happens from XML JSON primitive types are automatically identified. Therefore the number 50103015080000000550022052 is identified as a number and represented in the scientific notation.
The auto primitive feature is by default enabled in the EI server [1].
We can disable the auto primitive feature globally by configuring synapse.commons.json.output.autoPrimitive=false in the following location. And this will be applied for all the primitive data types globally.
[EI_HOME]/conf/synapse.properties
Also, we can also disable the auto primitive feature only for a set of data by providing a regex pattern. If you want to disable the auto primitive feature only for the above data set you configure the following in [EI_HOME]/conf/synapse.properties file.
synapse.commons.json.output.disableAutoPrimitive.regex=^-?(0|[1-9][0-9]*)(.[0-9]+)?$
After configuring the above please restart the servers.
[1]-https://docs.wso2.com/display/EI650/Working+with+JSON+Message+Payloads

Related

Why is it designed to be {uri.var.variable} instead of using the plain {variable}?

I understand that the WSO ESB/EI users need to use "uri.var" prefix when they want to allow a RESTful URI to contain variables that can be populated during mediation runtime using property values whose names have the "uri.var." prefix.
But why do we need "uri.var" isn't surrounding it with curly braces like a/{pathvar}/b enough to determined that it is a variable? Is this a room for improvement in the future or am I just missing something?
"uri.var" prefix is used to identify path parameters of endpoints that the ESB/EI needs to correspond with, these variables should allow the endpoint to be resolved to different values based on the values set into them.
"{pathvar}" are already used in API proxies to identify path parameters associated with API resources. The purpose of these variables is to allow mediation logic access to invocation time path parameters.
...
<resource methods="DELETE PUT GET" uri-template="/order/{orderId}" faultSequence="fault">
...
Since the intent is different in the two scenarios, having different conventions is justifiable.

Cannot Set Value to Variable in Mule ESB

I tried to get value from soap using Web Consumer, then I want to get the value with set-variable.
the problem, i can get the value to input in set-variabel.
this the design.
view image
Not sure if I understand your question, but I think you are trying to extract value from SOAP response. If this is the case, then note that Web Service consumer returns NamespaceRestorerXMLStreamReader.
You can drag "Transform Message" which is Mule DataWeave Transform Component from palette and drop it after Web Service Consumer component. You will then notice response structure in the left hand side. Define appropriate output format in right side and map the elements as needed.
You can then extract values to store in flow variable and continue with further logic.
Add a dom to xml the use xpath in a variable to pick the value

different Response objects from SOAP Webservice?

In JAX-WS usually the response object will be a string or an XML format.
Can we have 2 kinds of response objects.
I mean, based on flag, XML or JSON as response output?
Is there any Objectwrapper kind of solution?
Am new to JAX-WS ,So am totally clueless. Thanks
According to Wikipedia here, you don't need XML to represent the SOAP message. But it looks like you will need SOAP bindings that support JSON. Reading the description in that article makes it sound like you can't just set a flag and have the response format change based on that.
If you want something where you set a flag to generate a different response format, consider a REST architecture instead. In REST, you would send a different Accept header to specify the format of the response you want. There wouldn't need to be a flag in your application specific data to handle the data format since that's more of metadata concern anyways.

Blank value in web service for Int64 type

I consume a web service that has a numeric element. The Delphi wsdl importer sets it up as Int64.
The web service allows this element to be blank. However, because it is defined as Int64, when I consume the web service in Delphi without setting a value for it, it defaults to 0 because it's an Int64. But I need it to be blank and the web service will not accept a value of 0 (0 is defined as invalid and returns an error by the web service).
How can I pass a blank value if the type is Int64?
Empty age (example)
<E06_14></E06_14>
could have a special meaning, for example be "unknown" age.
In this case, the real question is how to make the field nillable on the Delphi side.
From this post of J.M. Babet:
Support for 'nil' has been an ongoing issue. Several built-in types of
Delphi are not nullable. So we opted to use a class for these cases
(not elegant but it works). So with the latest update for Delphi 2007
I have added several TXSxxxx types to help with this. Basically:
TXSBoolean, TXSInteger, TXSLong, etc. TXSString was already there but
it was not registered. Now it is. When importing a WSDL you must
enable the Use 'TXSString for simple nillable types' option to make
the importer switch to TXSxxxx types. On the command line it is the
"-0z+" option.
The DocWiki for the Import WSDL Wizard also shows two options related to nillable elements:
Process nillable and optional elements - Check this option to make the WSDL importer generate relevant information about optional
and nillable properties. This information is used by the SOAP runtime
to allow certain properties be nil.
Use TXSString for simple nillable types - The WSDL standard allows simple types to be nil, in Delphi or NULL, in C++, while Delphi
and C++ do not allow that. Check this option to make the WSDL importer
overcome this limitation by using instances of wrapper classes.

How to pass enumerated values to a web service

My dilemma is, basically, how to share an enumeration between two applications.
The users upload documents through a front-end application that is on the web. This application calls a web service of the back-end application and passes the document to it. The back-end app saves the document and inserts a row in the Document table.
The document type (7 possible document types: Invoice, Contract etc.) is passed as a parameter to the web service's UploadDocument method. The question is, what should the type (and possible values) of this parameter be?
Since you need to hardcode these values in both applications, I think it is O.K. to use a descriptive string (Invoice, Contract, WorkOrder, SignedWorkOrder).
Is it maybe a better approach to create a DocumentTypes enumeration in the first application, and to reproduce it also in the second application, and then pass the corresponding integer value to the web service between them?
I'd suggest against passing an integer between them, simply for purposes of readability and debugging. Say you're going through your logs and you see a bunch of 500 errors for DocumentType=4. Now you've got to go look up which DocumentType is 4. Or if one of the applications refers to a number that doesn't exist in the other, perhaps due to mismatched versions.
It's a bit more code, and it rubs the static typing part of the brain a bit raw, but in protocols on top of HTTP the received wisdom is to side with legible strings over opaque enumerations.
I would still use enumeration internally but would expect consumers to pass me only the name, not the numeric value itself.
just some silly example to illustrate:
public enum DocumentType
{
Invoice,
Contract,
WorkOrder,
SignedWorkOrder
}
[WebMethod]
public void UploadDocument(string type, byte[] data)
{
DocumentType docType = (DocumentType)Enum.Parse(typeof(DocumentType), type);
}
I can only speak about .net, but if you have an ASP.net Webservice, you should be able to add an enumeration directly to it.
When you then use the "Add Web Reference" in your Client Application, the resulting Class should include that enum
But this is from the top of my head, i'm pretty sure i've done it in the past, but I can't say for sure.
In .NET, enumeration values are (by default) serialized into xml with the name. For instances where you can have multiple values (flags), then it puts a space between the values. This works because the enumeration doesn't contain spaces, so you can get the value again by splitting the string (ie. "Invoice Contract SignedWorkOrder", using lubos's example).
You can control the serialization of values of in asp.net web services using the XmlEnumAttribute, or using the EnumMember attribute when using WCF.
If you are consuming your Web service from a .NET page/application, you should be able to access the enumeration after you add your Web reference to the project that is consuming the service.
If you are not working with .NET to .NET SOAP, you can still define an enumerator provided both endpoints are using WSDL.
<s:simpleType name="MyEnum">
<s:restriction base="s:string">
<s:enumeration value="Wow"/>
<s:enumeration value="This"/>
<s:enumeration value="Is"/>
<s:enumeration value="Really"/>
<s:enumeration value="Simple"/>
</s:restriction>
</s:simpleType>
Its up to the WSDL -> Proxy generator tool to parse that into a enum equivalent in the client language.
There are some fairly good reasons for not using enums on an interface boundary like that. Consider Dare's post on the subject.
I've noticed that when using "Add Service Reference" as opposed to "Add Web Reference" from VS.net, the actual enum values come across as well as the enum names. This is really annoying as I need to support both 2.0 and 3.5 clients. I end up having to go into the 2.0 generated web service proxy code and manually adding the enum values every time I make a change!