i am work on an online credit topup application. now i want to fetch the denomination available to a particular type of voucher which is select by.this is the scenario
a user selects a type of voucher(tigo,mtn,vodafon,airtel etc) from a combo box.after the selection the voucher denomination combobox should be populated with all denominations available. for now am out putting with json .av tried with this code but it returns this:
#RequestMapping(value = "/rest/getdenominations")
public #ResponseBody
String getDenominationByType(ModelMap model) throws JSONException {
Long vouchertypeId = 1L;
JSONArray typeDenominationsArray = new JSONArray();
for (Voucher voucher : voucherController.getTypDenominationAvailable(vouchertypeId)) {
JSONObject voucherJSON = new JSONObject();
voucherJSON.put(" ", voucher.getDenomination());
typeDenominationsArray.put(voucherJSON);
}
return typeDenominationsArray.toString();
}
but it returns this
[{" ":10},{" ":2},{" ":1},{" ":10},{" ":2}]
what i want is that the 2 and 10 should be displayed just once.
need help to this..tanx in advance
I don't think that the JSONArray object has a contains(JSONObject obj) function but you can make one yourself (See this link for an example). With this, inside of the for loop after you create each JSONObject check if your JSONArray contains the object. If not, add it, otherwise dont add it. This is not the most elegant solution but it should work.
Related
I'm trying to sort through ParseObjects created by different users (clubadmins) and presenting the results based on "clubAdmin" in a recyclerview. For some reason I can't put my finger on, the query is not yielding any results to populate my view.
The line that seems to be the problem is where I query to sort using whereEqualTo().
Any help with what might be the problem is much appreciated.
The .toString() was the latest addition which also did not resolve the issue.
ParseQuery<Club> query = ParseQuery.getQuery(Club.class);
query.whereEqualTo("clubAdmin",ParseUser.getCurrentUser().toString());
query.orderByAscending("createdAt");
query.setLimit(MAX_CLUBS_TO_SHOW);
query.findInBackground(new FindCallback<Group>() {
#Override
public void done(List<Club> objects, ParseException e) {
if(e == null) {
for (Club c : objects) {
Club createdClub = new Club();
createdClub.setClubName(c.getClubName());
createdClub.setObjectId(c.getObjectId());
listItems.add(createdClub);
I was aiming for a list with the clubs created by the logged in user barring all others. Now I do not see anything in my view. If I comment out the line containing whereEqualTo(), I get all the clubs created within the app populating my view set to the limit.
What is the type of clubAdmin field? Is it a pointer to user class or a String holding the objectId of a user? If it is the second case, you have to get the objectId of the user like ParseUser.getCurrentUser().getObjectId();
So I have an Object that comes in that can be any of 100 different specific objects, with different elements inside it, from other objects, lists, sequences, primitives etc.
I want to strip the values in a depth first fashion to make a string of simple values with a delimiter between them. I have mapped the fields and stored them elsewhere using recursion/reflection that only happens once a new Object type comes in for the first time.
An example of how I'm storing the data in the database for a few simple example objects:
Object A layout table: Timestamp = 12345 Fields = Length|Width|Depth
Object B layout table: Timestamp = 12345 Fields = Height|Weight|Name
Object A layout table: Timestamp = 12350 Fields = Length|Width|Depth|Label
Object A sample: Timestamp = 12348 Values = 5|7|2
Object A sample: Timestamp = 12349 Values = 4|3|1
Object B sample: Timestamp = 12346 Values = 75|185|Steve Irwin
Object A sample: Timestamp = 12352 Values = 7|2|8|HelloWorld
Below is my current solution. I'm seeking improvements or alternatives to the design to accomplish the goal stated above.
Currently I get the object in and translate it to JSON using gson.toJson(); From that, I cycle through the JSON to get values using the code below. Issue is, this code is very CPU intensive on the low end CPU I am developing for due to the fact that there are many samples coming in per second. Overall purpose of the application is a data recorder that records real time samples into a SQLite database. I have also attempted to store the unmodified JSON into a SQLite BLOB column, but this is terribly inefficient with regards to DB size. Is there a better/more efficient method for getting values out of an object?
I don't have an issue storing the field mapping since it only needs to be done once, but the value stripping needs to be done for every sample. I know you can do it via reflection as well, but that is also processing heavy. Anyone have a better method?
public static List<String> stripValuesFromJson(JsonElement json)
{
// Static array list that will have the values added to it. This will
// be the return object
List<String> dataList = new ArrayList<String>();
// Iterate through the JSONElement and start parsing out values
for (Entry<String, JsonElement> entry : ((JsonObject) json).entrySet())
{
// Call the recursive processor that will parse out items based on their individual type: primitive, array, seq etc
dataList.addAll(dataParser(entry.getValue()));
}
return dataList;
}
/**
* The actual data processor that parses out individual values and deals with every possible type of data that can come in.
*
* #param json - The json object being recursed through
* #return - return the list of values
*/
public static List<String> dataParser(JsonElement json)
{
List<String> dataList = new ArrayList<String>();
// Deal with primitives
if (json instanceof JsonPrimitive)
{
// Deal with items that come up as true/false.
if (json.getAsString().equals("false"))
{
dataList.add("0");
} else if (json.getAsString().equals("true"))
{
dataList.add("1");
} else
{
dataList.add(json.getAsString());
}
// Send through recursion to get the primitives or objects out of this object
} else if (json instanceof JsonObject)
{
dataList.addAll(stripValuesFromJson(json));
} else if (json instanceof JsonArray)
{
// Send through recursion for each element in this array/sequence
for (JsonElement a : (JsonArray) json)
{
dataList.addAll(dataParser(a));
}
} else if (json instanceof JsonNull)
{
dataList.add(null);
} else
{
errorLog.error("Unknown JSON type: " + json.getClass());
}
return dataList;
}
One thing you could try out is writing your own JSON parser which simply emits values. I have more experience in JavaCC so I'd take one of existing JSON grammars and modify it so that it only outputs values. This should not be too complicated.
Take for example the booleanValue production from the mentioned grammar:
Boolean booleanValue(): {
Boolean b;
}{
(
(
<TRUE>
{ b = Boolean.TRUE; }
) | (
<FALSE>
{ b = Boolean.FALSE; }
)
)
{ return b; }
}
Basically you will need to replace returning the boolean value with appending "1" or "0" to the target list.
ANTLR is another option.
I am a real newbie so go easy on me and my terminology, I am still learning!
I have a Backendless database I would like to show in my app.
I have successfully connected it to my Android Studio app, queried it and returned the data in the following method:
Backendless.Data.of( "database" ).find( queryBuilder, new AsyncCallback>(){public void handleResponse(List'<'Map'>'response ){
The narrative on the Backendless SDK says "the "response" object is a collection of java.util.Map objects"
I then used an iterator:
Iterator itr = response.iterator();
And a while loop to 'get' the object:
Object element = itr.next();
I am happy up until this point, the next step is to extract the useful data from element.
I have tried many options of but the only one I have working is element.toString() and use various methods to pick out what I want. This seems so inefficient I thought I would ask the experts for a better option!?
Your question is rather about working with Java Map interface. So I'd advice you to look into its documentation and maybe some tutorials on this topic.
As to your Backendless question, it looks like you got the request part right. Here is the extended example from the docs, which shows you how to retrieve the object fields:
Backendless.Persistence.of( "Contact" ).find( new AsyncCallback<List<Map<String, Object>>>(){
#Override
public void handleResponse( List<Map<String, Object>> foundContacts )
{
Iterator<Map<String, Object>> contactsIterator = foundContacts.iterator();
while( contactsIterator.hasNext() )
{
Map<String, Object> contact = contactsIterator.next();
String name = (String) contact.get( "name" ); // in case you have STRING field 'name' in Backendless database
Integer age = (Integer) contact.get( "age" ); // in case you have INT field 'age' in Backendless database
// etc.
}
}
#Override
public void handleFault( BackendlessFault fault )
{
System.out.err( "Failed find: " + fault );
}
});
As you may see, the main concern is to retrieve a Map instead of Object from the response List.
And also your question would be more useful with code samples of what you tried and maybe direct link to the docs you used as an example.
I have a struts action receiving following JSON:
{
"commandId":"tC",
"id":"123",
"def":""
}
Following code works just fine:
JSONObject command = null;
String commandId = null;
String deviceId = null;
try {
command = new JSONObject(json);
commandId = command.getString("commandId");
}
Since "def" can be empty, non declared or can contain another array of elements I tried doing this:
JSONObject def = command.getJSONObject("def");
in order to get this JSON object defined in the element def
This only works if def isn't empty like in this example:
{
"commandId":"tC",
"id":"123",
"def":{"1":"aaa", "2":"bbb"}
}
When def is empty or not defined my program stops working on the line JSONObject def = command.getJSONObject("def"); and noticed that it doesn't continue the execution?!
If I put JSONObject def = command.getJSONObject("def"); try / catch block I get _JSONObject["def"] is not a JSONObject _ exception, but execution doesn't continue
How does JSONObject.getJsonObject(String) behave?
I would expect it to return an empty JSONObject and continue the execution.
What I want is to check if there is anything defined in def and then in a if, else decide what to do in my program according to the value found there... I can't find a way to make my program work if a client's json comes with def empty or not defined.
my suggestion is to define "def" either be defined as null or {}:
"def":null or "def":{} to align with its usage agreement
quotes is really just used to indicate the value is a string. following the standard might save you and others from confusion in the future.
Likely it is because it is trying to get a Object and finding a string. In your JSON (if you control it), for an empty object I would do {}. This should allow Java to think it is retrieving an object.
If def is intended to be an object is it not suppose to look like this when empty?
{
"commandId":"tC",
"id":"123",
"def":{}
}
I think having "def":"" will cause the value to be attempted to be parsed as a string value and not an object value.
Maybe this will help someone. I had to solve the same problem. In my case the web service was returning empty JSON objects if it couldn't find the requested record.
Note: the data names have been changed to protect the innocent...
Note 2: this example uses javax.json
import javax.json.*;
JsonObject _jObj = _myRootObj.getJsonObject("someDataNode");
// at this point in execution _jObj could equal {"DataReturn":""}
// or {"DataReturn":"<some valid data>"}
// we want to test the existence of DataReturn before trying to
// use it
JsonValue jv = _jObj.getOrDefault("DataReturn", null);
String js = jv.toString();
// cover all the bases. test the value
if (js == null || js.isEmpty() || js.compareTo("\"\"") == 0)
{
throw new Exception("Error: DataReturn object null. Cannot proceed.");
}
// the object exists, so it's ok to get it
JsonObject jObjDate = _jObj.getJsonObject("DataReturn");
If you're using org.json.JSONObject you can use .isNull(String key) to do this, something like:
if (command.isNull("def") {
// Handle 'def' not being there
} else {
JSONObject def = command.getJSONObject("def");
}
I wrote a functional test to check adding items to a shopping cart.For a user to be able to add items to cart,he needs to login.So,I created a method to login the user and another method to add the item.Before and after the addtocart method in test,I am checking the size of content of cart.The addtocart functionality works without any problem when I run the app in dev mode(I can check the db too-which is postgres and not an in memory db).The addtocart fails in test.
the controller method which adds item to cart
public static void addItemToCart(Long productId,Long cartId,String quantity) {
Product product = Product.findById(productId);
ShopCart cart = ShopCart.findById(cartId);
int qty = Integer.parseInt(quantity);
CartItem cartItem = new CartItem(product,qty);
cart.addItem(cartItem);
cart.save();
System.out.println("Controller::addItemToCart()::cart id="+cart.id+" has="+cart.cartItems.size()+" items);
}
my test method is
#Test
public void testUserCanAddItemsToCart() {
Fixtures.loadModels("data.yml");
User user = User.find("byEmail","user#shop.com").first();
loginAsCustomer("user#shop.com","userpass");
ShopCart usercart = new ShopCart(user);
usercart.save();
System.out.println("BEFORE ADD::usercart="+usercart.id+" has :"+usercart.cartItems.size()+" items");
assertTrue(usercart.cartItems.size()==0);
addItemsToCart(usercart);
System.out.println("AFTER ADD::usercart="+usercart.id+" has :"+usercart.cartItems.size()+" items");
assertFalse(usercart.cartItems.size()==0);//why does this fail?
}
private Response addItemsToCart(ShopCart cart) {
Product pdt = Product.find("byIsbn","654-0451160522").first();
assertNotNull(pdt);
System.out.println("addItemsToCart():BEFORE ADD cart="+cart.id+" has="+cart.cartItems.size());
Map<String,String> addtocartParams = new HashMap<String,String>();
addtocartParams.put("cartId", cart.id.toString());
addtocartParams.put("quantity", "2");
String addtocarturl = "/items/addtocart/"+pdt.id.toString();
Response response = POST(addtocarturl,addtocartParams);
System.out.println("addItemsToCart():AFTER ADD cart="+cart.id+" has="+cart.cartItems.size());
return response;
}
The console output I get is
BEFORE ADD::usercart=48 has :0 items
addItemsToCart():BEFORE ADD cart=48 has=0
Controller::addItemToCart()::cart id=48 has=1 items
addItemsToCart():AFTER ADD cart=48 has=0
AFTER ADD::usercart=48 has :0 items
Here, in the controller method, the cart instance (of id=48) has 1 item after it is saved to db.But in the test method ,the cart instance of same id has 0 content.
I commented out the assertFalse method and retrieved the cart from db using the cartId.Even then the cart of same id has 0 content.I can't understand why this is happening..can anyone shed some light?
//test method body ..modified
ShopCart cart = ShopCart.findById(usercart.id);
System.out.println("AFTER ADD::cart="+cart.id+" has :"+cart.cartItems.size()+" items");
assertFalse(cart.cartItems.size()==0);//why does this fail?
It fails because the cart instance used by your test method and the cart instance used by the addItemToCart method are different. Each transaction has its own instance of the entity. And JPA doesn't automagically refresh an entity when some other transaction updates the row mapped by this entity.
You should reload the cart from the database after addItemsToCart has been called to check if something has been added to the cart in database.
I am a slave to object-oriented thinking, so what I'm wondering is, have you thought about making addItemsToCart() a method of your ShopCart class? I'm envisioning something like:
...
ShopCart usercart = new ShopCart(user);
usercart.addItemsToCart(pdt);
usercart.save();
String addtocarturl = "/items/addtocart/"+pdt.id.toString();
Response response = POST(addtocarturl,addtocartParams);
return response;
It's just easier for me to think about making (or retrieving) a ShopCart object, modifying it, and putting it in the database. That's how I would avoid this.
I had the same issue and adding JPA.em().clear() in my test before I get the model from the database solved this issue for me.