Retrofit2/Android - call multiple webservices in a chain - java

I'm new with Retrofit. My current solution is to call first webservice and in OnResponse override, call second one, providing result from first call as parameter to second call.
Finally, I need an object containing data loaded from both webservices called. My solution actually works. However, I'm not satisfied with it. Code is not clean and terrible to maintain (I will also need 3 webservices chain).
I've heard something about RxJava and flatMap method. Can anybody point me right direction? Complete code sample/turorial (including Retrofit intrerfaces definition) would be very helpful. Partial code samples I have already found is not something easy to understand, so I'm stuck now.
Thanks and sorry for possible duplicate.

Related

How to get a Hazelcast map inside a Camel route?

I'm really fresh to Camel (and hazelcast, at that), and I've been playing around with it a bit recently. A seemingly simple operation is causing me a lot of trouble, and I'm struggling to find any waypointers anywhere.
I have a listener watching for changes on a hazelcast map. If said changes match a certain criteria, I want to grab the entire map and send it to a processor. Something like this:
from(hazelcast:map:someMap?hazelcastInstance=#hazelcastInstance)
.filter().method(SomeFilter.class, filterMethod)
.???
// If the filter cafeterias are met, get the entire map and send it to a processor
But I am really not sure how to, well, get entire map itself, especially using Java DSL. The closest thing I've found is to get the map's keySet and then call getAll(keySet) on it, which seems needlessly contrived for such a simple thing? If this is really the preferred method, there is another issue - how do you pass said keySet as the parameter to the getAll operation? I.e.:
<snip>
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_KEYS_OPERATION))
.to(hazelcast:map:someMap?hazelcastInstance=#hazelcastInstance) // Gets the keySet just fine.
.setHeader(HazelcastConstants.OPERATION, constants(HazelcastConstants.GET_ALL_OPERATION))
.????
// I've tried .setHeader(HazelcastConstants.OPERATION_PARAM, new
// SimpleExpression("${body}")> here,
// amongst many other things, but, I just get an empty object back, so it's
// pretty clear I'm messing up
// the format or parameter choice here.
.to(hazelcast:map:someMap?hazelcastInstance=#hazelcastInstance)
Using camel 2.18.0 here, by the way.
Well after bit more trial and error, I got it working. I swear it was one of the first things I tried, but I must've bungled it up on the first attempt and got stumped. All you really do is get the keySet and then put into OBJECT_ID. So something like this:
.setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_KEYS_OPERATION))
.to(hazelcast:map:someMap?hazelcastInstance=#hazelcastInstance)
.setHeader(HazelcastConstants.OPERATION, constants(HazelcastConstants.GET_ALL_OPERATION))
.setHeader(HazelcastConstants.OBJECT_ID, new SimpleExpression("${body}"))
.to(hazelcast:map:someMap?hazelcastInstance=#hazelcastInstance)
(Note: it's hazelcast-map in newer versions.)
And ta-dah, you've got a Hashmap to work with. The alternative seems to use QUERY, but I couldn't figure out the proper syntax for, well, the query. I'd love to hear if anyone has a working example with a QUERY header...

Is it a good idea to call PUT from POST method

I have to automate certain operations of PUT/POST operation in my case, I have those endpoints already-in-place which will do their part.
My planning is to have another method which will drive this whole automation, consider this method as new POST endpoint which would gonna call each either POST and PUT endpoint from the same service which I already mentioned.
I will gonna call those existing PUT and POST based on input, if consider the input is new I will call existing POST and if given input exists in database I will going to call PUT.
Till I am good, But I have a question in my mind, Which is bugging me a lot that my new endpoint which is of POST is calling PUT as well as POST, I each method type has to do its type of operations only but here I am calling PUT as well as POST whereas my parent calling method type is POST.
I am not sure if I am working in right direction to achieve my use-case.
Please correct me in a different way.
Note - I am having Spring Boot application which would always need some endpoint to trigger any logic which I am talking about.
Update my question for better understanding.
I dont really know what you mean exactly. The HTTP methods are considered to do a specific task, but yet again its ok to use POST to update something - might be not best practice, but works. If you want to seperate the concerns (adding, updating), then just implement two different endpoints, one handling the creation the other one the update. The client (whether its a web-app or desktop app or whatever) has to handle this issue.

Re-Route Requests without sending Redirect to client

I have a pretty simple purpose
URIs of form ->/random/* go to /*. For example /random/users goes to /users.
I don't wish to use redirect() to solve the problem.
I have a tried a few ways but not sure about implementation -
Intercept the request before it reaches the router. And change the URI somehow. I am trying to Override the onRequest method, but unable to proceed as I don't know the implementation. (possible issue with: should routing really be here?)
Have an entry in routes which is like /random/*, make it point to a controller method. From inside the controller call the router method again with the modified URI. Again here unable to proceed as stuck with implementation.
Double the routes file or put a regex in routes file. For each entry, copy it and append /random to it. I dont want to do this, since it makes the file difficult to manage. Last resort really.
Please help regarding how to implementation Point 1 or Point 2.
If there is any other much simpler way please help..
Add a new Random-controller and create an action which forwards the calls to the proper controllers.
Use the following route:
GET /random/:controller controllers.Random.handleRandom(controller:String)
Let the handleRandom-action forward the calls accordingly (with or without redirect). You can either do some reflection-magic to forward the call to other controllers, or use a if-then-else- or switch-clause.

Understanding Android's webview addjavascriptinterface

I know that to interact from Javascript to Java you have to inject a Java object using the addjavascriptInterface method in webview.
Here is the problem I am facing.
I register a java object using addJavascriptInterface method to be available in my JS.
I inject few JS in the webview using webview.loadURL("javascript:XXX");
I send a JS event when I am done with injecting the JS.
The problem is that if immediately after step 1, if I execute the following Javascript:
mWebView.loadUrl("javascript:if(window.myobject) console.log('myobject found---------'); else {console.log('myobject not found----');}");
I get "myobject not found" in my console's log.
I want to know that if there is some time before I can access my object and if so, how do I get to know how much time should I wait to call my object?
I want to know that if there is some time before i can access my object
Yes, I think there is a delay, because WebView.addJavascriptInterface will run in the WebView's internal worker thread. Perhaps you've thought about this, and realized that WebView has to maintain at least one worker thread to do asynchronous network IO. Maybe you also noticed these threads in DDMS while using a WebView.
It turns out that it also uses a thread to do work for a number of other public methods. I really wish the docs from Google made this clearer! But I hope I can help and show you how I tried to confirm this for myself.
Follow me as I take a look at the source for WebView. It's reasonably readable, even if you can't follow exactly what's going on, it's possible to trace through answer some questions with respect to threads.
You can download the Android framework source through the SDK manager tool, but it's also mirrored on Github, so that's what I've linked to here. I guessed and picked a tag that's close to some version of ICS. It's not hard to find WebView.addJavascriptInterface. I just Googled "WebView.java site:github.com/android".
The method WebView.addJavascriptInterface sends a message to an instance of WebViewCore:
mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);
In WebViewCore.java there are a bunch of overloaded methods called sendMessage, but we don't really need to know which exactly is being called, since they do pretty much the same thing. There's even a nice comment to give us a hint that we're in the right place! All of them are delegating to an instance of EventHub which is some inner class. This method turns out to be synchronized, and is sending a message to an instance of Handler, which is a good indication that this is probably running in another thread, but for completeness sake, let's find out!
That Handler is instantiated in EventHub.transferMessages which is called from WebViewCore.initialize. There are a few more hops here, but eventually I found out that this is called from run in WebCoreThread (subclass of Runnable), which is instantiated along with a new Thread right here.
What an adventure! So, even though I really can't say for sure what's going on with all these moving parts, I am pretty confident to say that this method is not synchronous, and sends a message to the WebView's worker thread. I hope that makes sense!
if so, how do i get to know how much time should i wait to call my object?
Unfortunately, I don't know the answer to this. I was researching this exact issue and found this question on StackOverflow in the course of my Googling. I think you have the following options, some of which are nicer or easier than others:
1) Just Thread.sleep for 100 ms or something between addJavascriptInterface and loadUrl("javascript:..."). Blech, I don't like this, but it is potentially the easiest.
2) Another possibility is that you could call WebView.loadUrl with a snippet of JavaScript that specifically tests if the interface is set, and catches the ReferenceError that is thrown if it's not set yet. However, as you might have guessed, this kind of involves adding a JavaScript interface to the WebView!
3) Call WebView.setWebChromeClient instead, and catch JavaScript's alert() or console.log instead. From my experiments, this method is synchronous, so there is no delay. (I have confirmed this in source, but I'll leave details as an exercise for the reader) You should probably come up with some special string to call alert with and check for it inside onJsAlert, so you aren't just catching all alert()s.
Sorry for the length of this answer, I hope that helps. Good luck!
Ensure your Javascript objects declared in your HTML / Javascript that you need to access from Java are declared global otherwise they will most likely be collected. I have code that does this (where Android is my interface added with addJavascriptInterface):
<script>
var cb = function(location) {
alert('location is ' + location);
}
Android.getLocation('cb');
</script>
The getLocation method invokes Android's LocationManager.requestSingleUpdate which then invokes the callback when the LocationListener fires.
Without the "var" I find that by the time the location lookup invokes the callback the callback function has been garbage collected.
(copied from my response on a similar question)
I've taken Jason Shah's and Mr S's implementation as the building block for my fix and improved upon it greatly.
There's just far too much code to put into this comment I'll just link to it.
Details: http://twigstechtips.blogspot.com/2013/09/android-webviewaddjavascriptinterface.html
Source: https://github.com/twig/twigstechtips-snippets/blob/master/GingerbreadJSFixExample.java
Key points are:
Applies to all versions of Gingerbread (2.3.x)
Calls from JS to Android are now synchronous
No longer have to map out interface methods manually
Fixed possibility of string separators breaking code
Much easier to change JS signature and interface names

Sequence Diagrams and Java

I'm reading about Sequence Diagrams and I've found an exercise (multiple choice) which envolves Java code and it got me kind of confused... Can you help me to choose the right option, in order to get it clearer for me? I think it'd be simple for you. Many thanks in advance.
Here's the direct link to the image (hosted in ImageShack):
Sequence Diagrams and Java
What answer would you choose?
The diagram shows a process calling a.s() which calls c.w(), which calls d.u(), which calls a.t().
So functions() on a must include c.w().
Can you apply that logic to the rest of the arrows?
One hint: the class diagram provided on the right is not really relevant to finding the answer.
Another hint: the call from d to a.t() is different from the other calls in that it just returns instead of calling another method.
A remark: in Java, all method calls ultimately return or throw an exception unless the system exits prematurely. This makes this sequence diagram a bit odd - only one of the method calls (the one I mention above) is shown to return. The rest of the diagram shows a chaining of method calls to-and-fro between classes. This is not a common way classes collaborate in Java and seems to be constructed purely to as an excercise to test your understanding of UML.

Categories