I am working on an Apache Camel project. Basically the Jetty endpoint takes a Http Post request and the message goes through a few steps of transformation in the route. The last step of transformation is through JAXB, which converts Java object into XML. The Java DSL is below
final DataFormat jaxb = new JaxbDataFormat("sample");
from("jetty:http://localhost:8888/foo")
.unmarshal(format).split(body()).marshal(jaxb)
My problem is that when I send a POST request to the localhost URL, the HTTP response is string
[sample.Claims#b68e0e], not the XML I expected. This is the JAXB object ID. When I changed the DSL to
from("jetty:http://localhost:8888/foo")
.unmarshal(format).split(body()).marshal(jaxb).to("stream:out")
I can see the XML print out correctly in the stdout. I don't know how to make the HTTP Response to contain XML instead of the Object ID. Any help is appreciated.
Update:
I want to clarify what I try to accomplish. I need to convert a delimited string to an xml document. The post message to Jetty endpoint is a delimited string. The route first uses BeanIO to convert the string into a POJO and the POJO into XML using JAXB. Even though the post message is a single line string, I have to use split() because BeanIO by default dealing with multi-line flat file. I followed #Peter's suggestion by adding aggegate after the jaxb marshaling as below
from("jetty:http://localhost:8888/transformProxy/ECSProxy")
.unmarshal(format).split(body()).marshal(jaxb)
.aggregate(constant("1"),new MyAggregationStrategy())
.completionSize(1).to("stream:out");
but it does not seem to make any difference. I still get [sample.Claims#1a631c2] as the Http response body, while the stdout prints out the correct xml document. I am not sure how/when the response body of the jetty endpoint is set.
I made it work by moving the aggregate strategy as the second parameters of the split. For details, please see https://camel.apache.org/splitter.html. Search for the "Split aggregate request/reply sample"
Related
I am getting timestamp (2021-10-12T00:00:30.0+05:00) as a field in XML request body, which I need to validate whether it adheres to a specific format (yyyy-MM-ddTHH:mm:ss.fzzz) or not and return error if it does not pass the validation.
I tried using APIM expressions, but it does not allow using DateTime.TryParseExact(), a C# method. If anyone has any pointers, please let me know how can we achieve this?
After further reading the documentation , found out that there is no direct way to check if the timestamp matches the given the format. So went ahead with the regex matching to achieve it.
I used the below mentioned regex
^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)(([+-]\d\d:\d\d)|Z)$
I am able to send image/file and normal key value which is being served as normal json later. I am using the form-data type of body in postman and a node server.
To handle image i am using multer on my node server.
But what makes issue is when i try to send the nested json and image together.
I am not able to do this thing.
Everything is fine but this is how the nested json is logging in the terminal :-
Please! Any help would be great to get the nested data object also in actual json format but not like this string as shown in terminal photo.
JSON can't contain binary data. What you're asking isn't directly possible.
The ideal thing to do is a multipart request, which is what you're getting in your first example. Note that one of those parts could be JSON, and you can just reference the other part by name, or with some other identifier.
The wrong way to do this is to base64 encode the data and put it in your JSON. If you do this, you'll get what you're asking for at the expense of 33% overhead in file size, wasted CPU and memory on each end for encoding/decoding, and significant waste in memory for your JSON parser which now has to chew through all of this extra data.
An alternative is to use a format that supports binary data, like CBOR. CBOR works in browsers, is streamable, supports all of the types of JSON and then some, is extensible, and standardized.
One solution is to split image upload and record upload into two separate services and call in UI one after the other.
It may be late but I faced the same issue, what I did was,
1: send data through form-data body and had 2 parameters.
file (the file which we want to send on backend using file field)
data (a string in json format using the text field in form-data).
example:
data : {
"words":500,
"model":0,
"video":true,
"user_id":"user1"
}
I sent this in the request. Remember that when we send using form-data we have 2 separate choices file/text. Since this is text so the whole string is considered a text. So, essentially the data parameter is a string. When I receive this request on backend in django I do the following to get the actual json in json format.
attributes = json.loads(request.data['data'])
This converts the data parameter which was first a string, into a json just as we wanted.
Hope it helps others.
I want to define a JSON API response using JSON Schema.
Embedded in part of the API response is a complete, well-formed, schema valid XML string. The XSD of this XML string is a given.
Two part question:
How do I include the XSD in the JSON Schema such that the JSON Schema will also require the XML string to be schema valid in order for the whole API response to be valid?
If this is not possible, does anyone have another suggestion how to include the XSD at least in the specification? I'm working in RAML 0.8.
How do I include the XSD in the JSON Schema such that the JSON Schema
will also require the XML string to be schema valid in order for the
whole API response to be valid?
You cannot. The only thing you can do is validate the JSON and then at a later point extract the XML and validate it separately.
If this is not possible, does anyone have another suggestion how to
include the XSD at least in the specification? I'm working in RAML
0.8.
I've only used Swagger, not RAML. Swagger is also based on JsonSchema.
The only thing you can do here is to include a detailed specification that the contained XML should be compliant against such-and-such an XSD. You can do this by using the "description" functionality in swagger (or equivalent if it exists in RAML). This allows you to create a description (which supports markdown) and attach it to any element in the definition
Why we use json and xml for web api rather then othen platform like jquery and array.
Its interview based question and I was enable to response .
JSON and XML are ways to format and data-interchange.
JQuery is a library was built on top of javascript. so it has nothing to do in data-interchange.
Array by its definition: its a method for storing information. in other words you can use arrays in any format you want to store data.
In Conclusion, Web API is a service that provides or gathers data. and in general you can exchange data between client and server by JSON, XML, or you can use whatever data format you want such as HTML. JQuery can be use to call the Web API that can return an array of data in any data format.
This is not compulsory that you have to return the result in JSON or XML, but most of the time we are returning values in these format because there are media type formatter for JSON and XML, the capability of media type formatter is to read the CLR object from HTTP message and to write the CLR object into HTTP message. This is the main reason that we return values in JSON and XML format.
I am using SOAPUI for web service testing. I would like to do xml parsing via groovy script Test Step. For one test case, I have to insert xml tag [like <Email>xyz#gmail.com</Email>] in SOAP Request.
I can set value to xml tag using holder.setNodeValue(Xpath, Value), Using the same function I try to insert xml tag in SOAP request like holder.setNodeValue(Xpath, "<Email>xyz#gmail.com</Email>"). But in SOAP request xml tag set as
"<Email>xyz#gmail.com</Email>"
Because of this problem SOAP request not recognize that xml tag, Hence the value not get reflect /update in response.
Please correct me If I am using this function wrongly. Awaiting response from anyone..
Well that is happening because you are calling setNodeValue method. This method will set the value of the node (which can be of the XML node format).
Ideally, what you should have done is if node already exists () then just grab that node using holder and set the value.
Or
xpath = "//level1/level2/email"
holder.setNodeValue(xpath, "xyz#gmail.com")
Or the simplest, add a empty property value in between the nodes.
<Name>Test</Name>
${Property#TestValue}
<Phone>123123</Phone>
Now say if you want to add email between name & phone, assign some value to that property variable.
And if not, then leave it empty.