I have built a simple flex application (using BlazeDS) which displays "Person" details by invoking a java service using flex remoting.
So, my Person class looks something like this:
class Person {
public int age;
public String name;
}
As a java developer, here is my understanding:
When I run the front flex app in my webapp, an RPC call is executed and BlazeDS does the hard work of invoking the right method, obtaining the result as an object, converting the object to AMF format (serialization). And, then the web/app server sends back this response to the requesting app over http. The flex app now does the task of deserializing the object received in AMF format and somehow make use of it.
Here is my question:
I would like to modify the response before it reaches the Flex application by modifying the attributes of the person object. I have a Filter in place to do this. However, I am not sure as to how I would deserialize the AMF stream, modfiy the object, serialize the object back into the stream / reconstruct the stream somehow.
Is there a way to doing this? Where should I start?
PS
If the question was too confusing, here is a shorter version:
How do I modify the response stream of content type AMF-X, before it reaches a flex app using a java filter?
Serializing and deserializing AMF on your own is not going to be easy so definitely avoid that. A better approach is to convert the data to the right format in your back-end code. From Flex, call a service method on the back-end that then fetches the data and transforms it into the correct object structure before sending it back to Flex.
To further James' answer, use something like spring to interecpt the return of the call and interfere with it there (again, before it gets serialized).
You would basically have to reimplement the (de) serialization process, and that's not simple.
Well, It's not exactly what you want, but if you only need to change something occasionally while testing there's a solution. Charles Proxy (http://www.charlesproxy.com/) does let you modify the return data 'by hand'. It's a tool I use daily for monitoring AMF traffic, as it does a great job deserializing it, and showing it human readable format. There's a free version you can try.
Short instruction on how to edit the data:
0) Install Charles (including the firefox plugin if you use it
1) Choose Proxy->Breakpoints from the main menu.
2) Fill in the host (you can do it using wildcards - eg. mydomain.com* )
3) Check the "Response" box
4) Call the server
5) The breakpoint should fire when data comes back. Now just find the "Edit Response" tab, choose "AMF" on the bottom, and you can edit anything you want.
Hope this helps
Related
We are trying to automate some tasks in the chatbot/conversation creation process.
A step in this automation is to take an existing conversation (intents, entities en dialogs) and this to a newly created Conversation.
While working with the API, I see that getting a workspace (https://www.ibm.com/watson/developercloud/conversation/api/v1/java#get_workspace )
returns different types EntityExport, IntentExport etc...
(http://watson-developer-cloud.github.io/java-sdk/docs/java-sdk-4.2.0/com/ibm/watson/developer_cloud/conversation/v1/model/EntityExport.html )
than what the UpdateWorkspace expects:
CreateEntity, CreateIntent etc...
(http://watson-developer-cloud.github.io/java-sdk/docs/java-sdk-4.2.0/com/ibm/watson/developer_cloud/conversation/v1/model/CreateEntity.html)
Before I start writing a copyTo function, I thought I would ask for any pitfalls ? There must be a reason why the objects retrieved via GET are different from the objects you need provide for an update/create ?
These classes are generated to match parameters of REST API endpoints.
It would be much simpler to use HTTP client to fetch JSON of the workspace, remove a few unnecessary attributes (workspace_id, status, created, updated, etc) and send it to create or update endpoint.
I have a basic SOAP based web service. I am able to invoke methods and add information to it. But, while retrieving , the data a single class object seems to be perfectly displayed in the WSE browser. But If I have a list of objects, then I am not able to get any response in the body. Not sure, whats going wrong. Even the logs in console don't throw any error.
IS there a better way to view list of objects in WSE ?
Try clicking the Source link (to the right of the body) to check if the SOAP Response Envelope indeed has multiple objects in it. If it has, you may have encountered a bug in the viewer, if it doesn't - either the service doesn't work as expected, or your Request is not proper.
I tested locally with the following public service (operation getAll):
http://www.predic8.com:8080/crm/CustomerService?wsdl
It returns a list of many customers (judging from the raw response), but for me WSE only listed a few of the them (and the indentation depicting the hierarchy is wrong), so I guess this view of WSE is not very reliable.
So I'd suggest sticking to the raw XML view in WSE. In my everyday work I prefer using SOAP UI for service exploring/testing. It is free and gets regularly updated - you might want to check it out.
Good luck!
I have a situation where the client (.js) initiates a REST request and it is processed on the server side (.java). After processing, I would like to return a count to the client, which will be shown in a popup box if it is positive. How can such a construction be done? The idea I had was to set a named parameter on the HttpServletResponse object, but even this object is no where in scope in the .js code. Any ideas? I should also clarify that the primary purpose of the REST call is to download a file to the client. Thanks!
Do you want to send two things to your client - sending a file and also additional data? You haven't mentioned what framework (if any) you are using in backend to do this. You can use response header.
From your question, it seems like you don't have a good general-purpose way of responding to client requests on your server. I'd recommend you decide on a data format you'd like to use for all calls (e.g., JSON, XML, etc.) and stick with that across the board.
Once you've made that decision, you can encode your integer using whatever makes sense in your chosen format. For example, in JSON you might return: {"count":6}.
I am writing a server client application, best performance is a must; I am using RMI for server-client communication, the server uses mySQL database.
Now in the client side I have a method called
getLinks()
which invokes the same method on the server, the problem is that this method returns about 700Mb of data, which takes some time to get, and some more time to analyse.
And then I'm setting some values for each Link:
for (Link l : myService.getLinks()) l.setSelected(false);
What I have in mind right now is just getting the Link Ids first (since this would be a smaller data) and then using Asynchronous method to get each Link by Id (each link need one service call); and then setting the Link values.
Is this the best approach, is there another way of getting RMI data one by one (one method call and more than one return)?
Is there something like (yield return) in C#?
you can also make a pagination method, which receive the initial id (or position if the id's are not a consecutive) and the length, in this way you will not send all the id's twice
Are the Link objects remote objects? If not I don't really see the point of the code, as it only sets something locally in the client object which is immediately thrown away.
Assuming they are remote objects, it would be better to ship the entire update to the server and tell it to update the whole collection, something like setLinksSelected(boolean), where the server does the iteration.
But I would also be wary of updating, or even transporting, 700Mb of data via RMI whichever way you do it. That's a lot of data.
Scroll towards the end for the solution to the topic's problem. The original question was asking for a somewhat different thing.
As a part of a larger process, I need to fetch and link two related sets of data together. The way that the data is retrieved(dynamics crm, n:n relationships..) forces us retrieve the second set of the data again so that it will have all the necessary information. During a part of larger transformation of this data, I would like to access the http endpoint that is used to fetch the data from the crm, retrieve the second set of data and process it. I can get the endpoint through DefaultEndPointFactory like so:
DefaultEndpointFactory def = new DefaultEndpointFactory();
def.getInboundEndpoint("uri").getConnector;
But there is no method to actually send the mulemessage.
Solved:
The problem is that you can not set inbound properties on the MuleMessage, and the flow is depending on some of those to function(path, query params etc).
It seems you are able to inbound scoped properties with this:
m.setProperty("test", (Object)"test", PropertyScope.INBOUND);
Is there a way to make this approach work, or an alternative way to access the flow? I tried using mulecontext to get the flow:
muleContext.getRegistry().lookupFlowConstruct("myflow");
But it did not contain anything that looked useful.
Solution:
As David Dossot suggested in a comment of his answer, I was able to solve this with muleClients request method.
muleContext.getClient().request(url, timeout);
Then constructing the url as usual with GET parameters etc.
I'm not 100% sure about what you're trying to achieve but anyway, the correct way of using Mule transports from Java code is to use the MuleClient, which you can access with muleContext.getClient().
For example, the send method allow you to pass a properties map that are automatically added to the inbound scope. Behind the scene, Mule takes care of creating the endpoint needed for the operation.
Regarding the flow: what are you trying to do with it? Invoke it?