How to refresh jsp page? - java

I'm new to Google App Engine and I'm having a little problem that I can't seem to be able to find the solution to.
Whenever I create/delete/update something from the Datastore, in the end I do this:
resp.sendRedirect("/view_list.jsp");
And the page doesn't get updated.
For instance, if I have a page with a list of 2 items, then I create another item and I redirect to that page with the list, and instead of showing 3 items, it shows 2 items, until I change page and come back.
So how can I make sure that the page refreshes after my changes to the Datastore?

A couple of points that are relevant:
The Data store is HRD (High Replication Database) and as per the documentation, the delay from the time a write is committed until it becomes visible in all datacenters means that queries across multiple entity groups (non-ancestor queries) can only guarantee eventually consistent results. Consequently, the results of such queries may sometimes fail to reflect recent changes to the underlying data. Please refer to the documentation for more details.
In short, to get consistent reads, use get as much as you can. If you use a query, there could be a delay due to the indexing.
Hope this helps. I also suggest to frame the question title better. The question is a good one but could get lost when it says "refresh the jsp page".

Related

How can I load more items when scrolling down in listview?

First I want to say: This question is no duplicate!
I already read a lot of questions about loading more items when scrolling down.
This was most helpful for me.
But all questions I read aren't explaining the basic principle.
So, what I mean is:
My app gets data from json and displays it in a ListView, but it's not possible to load all items from database with one request. The app crashes…
The solution is to load only 10 items and on scrolling down 10 items again.
But what is the basic principle to do this?
I thought about these 2 different options:
Set a LIMIT in my PHP file and send for each 10 items a new request from android and set LIMIT +10.
Send one request from android and getting all data from json, but only displaying 10 items.
Code isn't necessary, because I want to know the principle of doing this.
The approach I use in my apps is:
Step # 1: I load first set of data with limit from server and then store the last record data id in a variable.
Step # 2: Implement the on scroll end listener to your listView or RecyclerView.
Step # 3: Start another request inside on scroll end listener and load new records.(Here I set again data id in a variable)
For Example:
Start the request when the activity starts and do what I explained earlier.
GetBusinesses("&isOpen=2&cat="+Prefrences.getSelectedCategoryId());
Then inside your on Scroll End Listener
GetBusinesses("&isOpen=2&cat="+Prefrences.getSelectedCategoryId()+"&limit=10&lastDataId="+BusinessItems[index].mBusinessId)
Edit To avoid duplicate api call inside GetBusinesses() check if the request was started previously, well the idea is create a boolean initially false and then in your GetBusinesses() function make it true before starting the request and once the data is loaded and request is finish make it false again.
I hope this help.
Usually you would load 10 new items from the server each time. Use a page-parameter to identify which 10 items you need and where to place them.
loading all items at once could be way too expensive: The delay could be long and the user's data-plan won't be happy either. Obviously depending on how many items there are and what contents they have.
You will have to find the trade-off. Based on your data size, sometimes it makes sense to parse and save it all in local database.
Just for 200-300 records, you don't want to make another api call after every 50 records in list. Remember with mobile app user scrolls up and down very often. You might be unnecessarily sending multiple requests to your server, which might be an overload(depending on user count).
If you go with option 2, you can make use of something like JobIntentService to silently fetch data and save locally.
This approach will also let your user interact with no internet(offline mode) scenarios.

Realm for Java/Android - preserving the state of query/result

In the project currently under development, we are integrating the Realm Database into the customer's app to improve responsiveness while working on a huge data set of ~20.000 records. For on-screen presentation, we are incorporating Realm's Android Recyclerview. Majority of the use cases are read operations, followed up by the possibility of advanced search and/or filtering of the records.
Where the shoe pinches are that on some of our views, from all the data of given type only a subset of records is supposed to be displayed, selected by the back-end. Using the information passed by the API, we perform the initial filtering and set up the view.
Now, using the aforementioned technologies, is there a readable and maintainable way to store either this pre-filtered subset or the query fetching it for further reference, so that the initial state of the view can always be restored once the searchview and/or filters are cleared? Or should storing the API response re-applying the conditions given through it be the only way to do it? Applying any new conditions to the query seems to alter it for good, the same goes for applying new queries to the results. Shouldn't there be a way to create ourselves a fresh result set based on an old one but without disturbing the latter?
Edit: Our app being 'bilingual', both Java- and Kotlin-based solutions are welcomed, should they differ.
As we came to realise after a while earlier this week, and just as #EpicPandaForce have mentioned in the comments, while the RealmQuery object cannot be "snapshoot" by assigning it to a spare variable before extending it, the same is not true for RealmResults objects. And so:
RealmResults<Obj> widerResults = realmInstance.where(Obj.class).in("id", idArray).findAll;
RealmResults<Obj> narrowerResults = widerResults.where().equalTo("flag", true).findAll;
Will provide two independent result sets. The wider one can be used as per the use case I highlighted - to treat it as a starting point for further subqueries. The changes to objects found in the sets themselves will still be reflected in both sets.
Providing an answer for all the lost souls out there, should they get stuck like we did.

Google Places API - saving place_id and violation of terms and conditions

I want to build an app which shows places around user using Google Places based on user interests. As mentioned here:
Place IDs are exempt from the caching restrictions stated in Section
10.5.d of the Google Maps APIs Terms of Service. You can therefore store place ID values indefinitely.
So, can I save place_id in cloud database and perform any analytics operation over it? For example; if I gather place_ids added in each user's favorite places table and from analytics; I can know which place_id are the most ones added to favorites? or can I show something like 'Trending Places' in app from gathered place_ids in responses?
Will it violate the terms and conditions? I read the whole page of terms but couldn't find the answer.
can anyone help me out? Thanks.
Yes you can 100% store the place_id indefinitely and reuse it.
See Referencing a Place with a Place ID.
Please note one thing that
A single place ID refers to only one place, but a place can have
multiple place IDs
These terms and conditions are kind of self explanatory. Except your requirement which will be clarified after the below link is read carefully. As per your requirement , inorder to prevent calling services next time with same query which user had done with an intention of saving network calls is acceptable.
No caching or storage: You will not pre-fetch, cache, index, or store any Content to be used outside the Service, except that you may store limited amounts of Content solely for the purpose of improving the performance of your Maps API Implementation due to network latency (and not for the purpose of preventing Google from accurately tracking usage), and only if such storage
1) is temporary (and in no event more than 30 calendar days)
2) is secure 3)
does not manipulate or aggregate any part of the Content or Service 4) and
does not modify attribution in any way. Go through this Section 10.5 Intellectual Property Restrictions. Subsection (B)
You'll need to contact Google to get a 100% answer.
That being said, from my experience it looks like the clause you included is intended exactly for the kind of thing you want to do.
Again, I want to reiterate that contacting Google directly is something you should do if you still have concerns.
You can store place ID values indefinitely.
Just What part of
You can therefore store place ID Values indefinitely.
Don't you understand?
Indefinitely requires a server.

Deciding on a strategy for paginating Book listings without SQL

I have an ArrayList of Books pulled from different Merchants and sorted in Java, depending on user preferences, according to price or customer reviews:
List<Book> books = new ArrayList<Book>();
This requires me to keep a large chunk of data in memory stored as Java objects at all times. Now that I need to paginate this data into listings that span multiple web pages and allow a user to click on a numbered page link to hop to that segment of the data, what's the best way to do this?
My idea was to have maybe 25 book listings per page and rather than use hyperlinks that submit the form data as a GET request of URL parameters, the page number hyperlinks would simply resubmit the form, passing the requested page number as an additional form POST parameter.
<input type="hidden" id="pageNumber" value="0">
Page 5
In that case page 5 would simply be a set of 25 records starting at the 125th (5 * 25) record in the ArrayList and ending at the 149th record in the ArrayList.
Is there a better way to do this?
Refactor your application to let e.g. Hibernate pull out data from the underlying database.
Hibernate can do all the sorting and pagination without you having to keep it all in memory at all times.
IMO the request being a GET or POST shouldn't make much difference, so I'd say do whatever floats your boat (shielding head from RESTful rebuttals). The big thing I'd still be concerned about is keeping that list in memory. Pulling it from separate merchants seems like a good argument for not re-retrieving it each time a page is requested, but personally I'd consider storing those results in a local database anyways, even temporarily. Keeping that much data in memory on your app server will have consequences when you have a lot of concurrent users.
How many results pages do users generally look at? How big is the data (total or per record)?
Is this big list always around (static), or created per-query ?
Instead of returning a page with 25 results, can you output (say) 200 in a JSON array, and use javascript to display n .. n+24 results. If you have all the results on the page, you can also do the sorting there as well. Request a 1x1.gif?user=u1&action=whatever if you want to do user tracking (update ads, etc.) when displaying another page.
Depending on your record size, traffic, user behavior, sending
JSON could be more compact than the html generated on the server, so you get
less bandwidth used
fewer queries made to the server
user sees better response because pages update quicker (and server is doing fewer queries)
but you will need to do some analysis to see if this will help you. For example, if more than half of people always look at the second page of results, you might as well ship with that first page results 26-50 as well.
On the other hand, you wouldn't want to send 500 results if no one looks past page 3. Unless you wanted to inflate your traffic numbers. Or you could do something dynamic, like send out smaller pages when there is less bandwidth available. God we live in primitive times.
I have a open source library to deal with pagination issue in Java Web application. Here is the link:
http://www.hdpagination.org
It may be an option for you to think about.
If you have any question, feel free to ask.

GWT: Populating a page from datastore using RPC is too slow

Is there a way to speed up the population of a page with GWT's UI elements which are generated from data loaded from the datastore? Can I avoid making the unnecessary RPC call when the page is loaded?
More details about the problem I am experiencing: There is a page on which I generate a table with names and buttons for a list of entities loaded from the datastore. There is an EntryPoint for the page and in its onModuleLoad() I do something like this:
final FlexTable table = new FlexTable();
rpcAsyncService.getAllCandidates(new AsyncCallback<List<Candidate>>() {
public void onSuccess(List<Candidate> candidates) {
int row = 0;
for (Candidate person : candidates) {
table.setText(row, 0, person.getName());
table.setWidget(row, 1, new ToggleButton("Yes"));
table.setWidget(row, 2, new ToggleButton("No"));
row++;
}
}
...
});
This works, but takes more than 30 seconds to load the page with buttons for 300 candidates. This is unacceptable.
The app is running on Google App Engine and using the app engine's datastore.
You could do a lot of things, I will just list them in order that will give you the best impact.
FlexTable is not meant for 300 rows. Since your table is so simple, you should consider generating the HTML by hand, and then using simple HTML widget. Also, 300 rows is a lot of information - consider using pagination. The DynaTable sample app shows you how to do this.
It looks like you are using one GWT module per page. That is the wrong approach to GWT. Loading a GWT module has some non-trivial cost. To understand what I mean, compare browser refresh on gmail v/s the refresh link that gmail provides. That is the same cost you pay when every page in your website has a distinct GWT module.
If the list of candidates is needed across views, you can send it along with the HTML as a JSON object, and then use the Dictionary class in GWT to read it. This saves you the RPC call that you are making. This approach is only recommended if the data is going to be useful across multiple views/screens (like logged in users info)
Check how long your RPC method call is taking. You can enable stats in GWT to figure out where your application is taking time.
You can also run Speed Tracer to identify where the bottleneck is. This is last only because it is obvious FlexTable is performing a lot of DOM manipulations. In general, if you don't know where to start, Speed Tracer is a great tool.
The significant thing here is how you're retrieving the list of candidates, which you haven't shown. 30 seconds is extremely high, and it's unlikely that it's due to the datastore alone.
Have you tried using appstats to profile your app?
Like sri suggested - pagination is easiest and (I think) best solution (along with switching to Grid or just <table>). But in case you wanted for some reason to show/render many rows at once, the GWT Incubator project has a nice wiki page about it - along with some benchmarks showing how FlexTable sucks at large row count. Check out their other tables too ;)
Your problem is that everytime you add something to the FlexTable it has to re-render the whole page and repaint. Try creating a new FlexTable, populating it, when it is fully populated, get rid of the old one and put the new one there.

Categories