Mule abstractMessageTransformer returning new object - java

I have a custom transformer that extends AbstractMessageTransformer. I use the mule message to get some data from a flowVar, and then create a JSON POJO using that data. From there I simply return the JSON POJO object.
My question is, is it okay to just return the new object or should I be setting it to payload of the mule message using message.setPayload and returning message? If so why?
The flow works fine by returning just the POJO object, however is this correct? Could there be some unforeseen outcomes down the line?

You are doing it correctly. That returned object ideally becomes the result of transformation, the new payload.

Related

Returning an object, when it is empty GAE Endpoint

Is there any way that GAE parses a null object when using Endpoints.
For example, if i return an array a = [1,2,3].
It will return
{a:[1,2,3]}
But if i return an array a = []
{}
That's what i get, there is no response in JSON.
If you wrap your data into the Bean, you can define ApiTransformer, that will transform your entity into the desired output. So you can check in your transformer whether the array is empty and if so then you can transform it into the null or whatever you want. See documentation for ApiTransformer.

Is there a dynamic data structure that can be automatically serialized to XML or JSON?

I'm developing a restful web-service that should be able to return JSON or XML responses upon request. Of course, the JSON response should be identical to the XML response when the data is compared.
The thing is that I can't use a Java pojo because the returned data fields are dynamic, they are unpredictable.
For example, a specific user may have the following response:
{
"propertyA": "propertyA-Value",
"propertyB": "propertyB-Value",
}
...another user may have:
{
"propertyA": "propertyA-Value",
"propertyB": "propertyB-Value",
"propertyC": "propertyC-Value",
}
...or the XML representation would be
<results>
<propertyA>propertyA-Value</propertyA>
<propertyB>propertyB-Value</propertyB>
<propertyC>propertyC-Value</propertyC>
</results>
Is there a way to automatically serialize the structure holding the previously mentioned data, to JSON or XML. By "automatically", I mean using an API that would work with whatever fields provided.
I can't use an array\list of feature-name\feature-value structures as the service consumer needs to receive the response as mentioned.
use codehaus fasterxml object mapper. A sample app can be seen from below link
https://github.com/abhishek24509/JsonMapper
ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
the above code will help to hold dyamic response. Your pojo can have all possible field. But during mapping it will ignore unknown

BadRequestException while putting POJO containing ByteBuffer in Invocation.Builder.post in jax-rs?

I'm trying to post a POJO entity like below in Arquillian test class.
MyPojo pojo = new MyPojo();
pojo.setBuffer(ByteBuffer.wrap("Happy new year".getBytes()); //this is the problem
pojo.setOtherFiled(someotherfield)
Client client = ClientBuilder.newClient();
Invocation.Builder builder = client.target(url).request(
MediaType.APPLICATION_JSON_TYPE);
MyPojo response = builder.post(Entity.json(pojo), MyPojo.class);
My rest resource end point looks like this
MyPojo myEndPoint(MyPojo pojoParam){
//the body is immaterial since it's not going inside the body.
}
I'm getting javax.ws.rs.BadRequestException:HTTP 400 Bad Request.
If I comment out pojo.setBuffer(ByteBuffer.wrap("Happy new year".getBytes());, it's not giving that error.
What is the problem with the above code how to correct it?
Finally I figured out why it's happening. The Jackson cannot serialize ByteBuffer as it is an abstract class. It's not straight forward it might need additional type information.
At the client end we send the json(jackson serializes the POJO) but when reconstructing the POJO class before passing to the rest end point, it fails to reconstruct the object of the POJO class from json as it doesn't know how to create a ByteBuffer instance.
I figured it by trying to use jackson to serialize and de-serialize ByteBuffer in a stand alone class. It will throw
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.nio.ByteBuffer, problem: abstract types can only be instantiated with additional type information
Jackson lies in pre-processing phase of the request processing in Resteasy. So, Resteasy is giving 400 bad request as it could not process the request.
As a work around I'm using byte[] instead of ByteBuffer and converting it to ByteBuffer instance in the end point.
Upgrading the JSON Mapper to fasterxml will fix this issue. I have upgraded and the issue is fixed for me.
https://github.com/FasterXML/jackson

Sending objects as JSON vs Objects of defined class

I have multiple web services running on Tomcat servers with Java backend. When one of the services queries for something from one of the other services, it returns the payload as a JSON string. Now i need to parse this and get the info that i need. I use the JSON library provided by json.org
What I wanted to ask is that, will be faster (wrt to processing) if i have a template class (i class with just attributes and their get/setters) as a library class in both the services and then pass the payload as an object of that class, and then accept it as by type casting to that object.
WebResource localWebResource = localClient.resource(url);
ClientResponse localClientResponse = (ClientResponse) localWebResource
.accept(new String[] { "application/json" }).get(ClientResponse.class);
//Scenario 1 - accept it as String
String jsonString = (String) localClientResponse.getEntity(String.class);
MyObject myObj = parseJson(jsonString);
//Scenario 2 - accept it as object of 'MyObject'
MyObject myObj = (MyObject) localClientResponse.getEntity(MyObject.class);
Using scenario 2, will it be any faster compared to scenario 1. Converting to 'MyObject' in scenario 2, will the compiler take the same amount of time as for manual parsing like in scenario 1?.
Note that the payload is transferred over the network. Will either of this approach have any effect on the network transfer time?
In theory, both methods would take the same amount of time. They both have to transform the JSON string into an object graph. However, my experience is that getting the object from the framework is much faster than trying to do it myself. (using Jersey 1.17, no Jackson, Jaxb/Json conversion)

Returning an int whenusing webServiceTemplate.marshalSendAndReceive

I'm using Spring WebServiceTemplate class to to create and instantiate a request object of a JAXB generated class, call the marshallSendAndReceive method with it and then to cast the response object to an object of the JAXB generated response class.
This is working fine when returning the XML Objects of the JAXB generated response class (with Select Query) but now I want to execute a Delete query and just want to return the number of rows deleted. But I'm not sure how to achieve this!!
Do I need to convert that int return value into an XML object by using the following in the schema.xsd:
<xs:element name="DelResponse" type="xs:integer"/>
OR
Is there another way of achieving the same.
Thanks
Do I need to convert that int return value into an XML object
Yes. All web service messages are encoded as XML, so you need to find a way of representing everything in XML, even if it's just a plain integer.
If you want something simpler, then SOAP/Spring-WS/JAXB isn't really the tool for the job.

Categories

Resources