I do a Action on Middle ware and if its success i get the Value as
String result = ["RESULT","DELETE","OK"]
And in Case if the Operation is Failed i get the resposne as
String result = ["RESULT","DELETE","ERROR"]
I need to know if the Operation is success Or Fail so for this i have done this
public class Test {
public static void main(String args[]) {
String result = "[\"RESULT\",\"DELETE\",\"ERROR\"]";
if (!result.contains("ERROR")) {
System.out.println("success");
} else {
System.out.println("Failed");
}
}
This is working fine , but not sure if this has any negative impact / or in cases the code may Fail .
Please suggest if there is a better approach .
Your code can fail if, for instance, you get a success message containing ERROR (not likely, but can happen).
You should use a library to parse the result into a List/Array, look here on StackOverflow for a ton of solutions for parsing Json Strings to Objects in Java (Jackson is a library to do this, for instance).
You should also validate against a pre-set number of hypothesis, for instance, creating an enum for the possible result types, and checking if it's one of them.
I would suggest to use object presentation instead of array here:
{
"RESULT": {
"operation": "DELETE",
"status" : "ERROR"
}
}
There is you can find a lot of tools to parse JSON in Java objects:
http://www.json.org/
In other case it will be hard to extend set of codes. E.g.
String result = "[\"RESULT\",\"CREATE\",\"USER\", \"LOGIN\", \"ERROR\", \"SUCCESS\"]";
Was there error? or user with login ERROR was successfully created?
String[] result = {"RESULT","DELETE","OK"};
if(Arrays.asList(result).contains("OK"))
System.out.println("Ok");
Try Arrays.asList() method to check given arrays contains that element or not.
Related
I'm currently working on an application built in Scala with Spray routing.
So for dealing with a JSON document sent over POST, it's pretty easy to access the variables within the body, as follows;
respondWithMediaType(`application/json`) {
entity(as[String]) { body =>
val msg = (parse(body) \ "msg").extract[String]
val url = (parse(body) \ "url").extractOpt[String]
However, I'm now trying to write an additional query with GET, and am having some issues accessing the parameters sent through with the query.
So, I'm opening with;
get {
respondWithMediaType(`application/json`) {
parameterSeq { params =>
var paramsList = params.toList
So, this works well enough in that I can access the GET params in a sequential order (just by accessing the index) - the problem is, unfortunately I don't think we can expect GET params to always be sent in the correct order.
The list itself prints out in the following format;
List((msg,this is a link to google), (url,http://google.com), (userid,13))
Is there any simple way to access these params? For example, something along the lines of;
var message = paramsList['msg']
println(message) //returns "this is a link to google"
Or am I going about this completely wrong?
Apologies if this is a stupid question - I've only switched over to Scala very recently, and am still getting both acquainted with that, and re-acquainted with Java.
What I usually do is use the parameters directive to parse the data out to a case class which contains all the relevant data:
case class MyParams(msg: String, url: String, userId: Int)
parameters(
"msg".as[String],
"url".as[String],
"userId".as[Int]
).as[MyParams] {
myParams =>
// Here you have the case class containing all the data, already parsed.
}
To build your routes you could use the parameters directives. I'm not sure if this is what you're looking for, anyway you could use them as:
get {
parameters('msg) { (msg) =>
complete(s"The message is '$msg'")
}
}
Spray directives can be easily composed so you can use combine them in any way you want.
I hope that helps you.
I am currently creating a plugin for Minecraft using the SpigotAPI. Reason I'm posting this here is because this I believe is a Java error. I am creating a duels plugin where inside my code it'll loop through an enum, and see if it's a specific type. The first time using it around it properly works, no problems. But when I try it for a second time without restarting my plugin/program/code it'll return the enum as null. Here is the code, is there a fix to this?
public DuelArenas[] getArenasWithType(DuelTypes type) {
String suffix = "_NORMAL";
List<DuelArenas> arenasAsList = new ArrayList<>();
switch (type) {
case NORMAL:
suffix = "_NORMAL";
break;
}
for (DuelArenas arena : duelArenaStatus.keySet()) {
if (arena.toString().endsWith(suffix)) {
arenasAsList.add(arena);
}
}
DuelArenas[] arenas = new DuelArenas[arenasAsList.size()];
return arenasAsList.toArray(arenas);
}
Stacktrace:
Caused by: java.lang.NullPointerException
at me.nick.acore.duels.DuelsAPI.getArenasWithType(DuelsAPI.java:97) ~[?:?]
And yes I've checked to see if the enum was null, and it was in fact null. Also line 97 is
if (arena.toString().endsWith(suffix)) {
And finally here is the DuelArena class
public enum DuelArenas {
ARENA_1_NORMAL, ARENA_2_NORMAL, ARENA_3_NORMAL, ARENA_4_NORMAL, ARENA_5_NORMAL,
ARENA_6_NORMAL, ARENA_7_NORMAL, ARENA_8_NORMAL, ARENA_9_NORMAL, ARENA_10_NORMAL,
ARENA_11_NORMAL, ARENA_12_NORMAL }
Thanks!
Your problem is that you cannot directly convert your custom DuelArenas class to a string. However when you are comparing to see if a .toString() ends with suffix, I feel that something is also going wrong. You would only ever use .toString to convert things like numbers to strings, and if your are converting a number to a string there is no way it will end in _NORMAL.
So if you want me to troubleshoot further please post your DuelArenas class, but until then my best guess is that when you do arena.toString you are looking to pull some sort of value from that class that is stored in it, and to do this you would do arena.variableInsideArenaName and work with that.
EDIT:
After seeing the class scratch that, the error in going to be somewhere in this line DuelArenas arena : duelArenaStatus.keySet()
I am wondering what is the most effective form of data validation for android. So, when getting a value from an EditText how should the value given be validated before it is used? I currently check to make sure the string returned from getText().toString() is not null or empty using the guava library:
Strings.isNullOrEmpty(editText.getText().toString())
Then, depending on what type of data I am expecting, I create a method to see if the data can be parsed. So if I am expecting a double I will create a method like this:
private boolean isDouble(String string) {
try {
double stringDouble = Double.parseDouble(string);
return true;
} catch (Exception e)
{
return false;
}
}
Is there a simpler way to do this without the need to create a separate method for each type of data I am expecting to receive?
I've used the edittext-validator the last time I needed a quick validation. Works like charm :)
https://github.com/vekexasia/android-edittext-validator
If you are using EditText you should know what purposes it serves. Usually you are expecting to have just a plain string to, for example, send it to server or store in SharedPreferences.
But, if you want a particular data to be filled in, you can use Pattern class for validation. In case of number values you are using android:inputType="number" and when converting it using Integer.valueOf(text)
I am implementing REST through RESTlet. This is an amazing framework to build such a restful web service; it is easy to learn, its syntax is compact. However, usually, I found that when somebody/someprogram want to access some resource, it takes time to print/output the XML, I use JaxbRepresentation. Let's see my code:
#Override
#Get
public Representation toXml() throws IOException {
if (this.requireAuthentication) {
if (!this.app.authenticate(getRequest(), getResponse()))
{
return new EmptyRepresentation();
}
}
//check if the representation already tried to be requested before
//and therefore the data has been in cache
Object dataInCache = this.app.getCachedData().get(getURI);
if (dataInCache != null) {
System.out.println("Representing from Cache");
//this is warning. unless we can check that dataInCache is of type T, we can
//get rid of this warning
this.dataToBeRepresented = (T)dataInCache;
} else {
System.out.println("NOT IN CACHE");
this.dataToBeRepresented = whenDataIsNotInCache();
//automatically add data to cache
this.app.getCachedData().put(getURI, this.dataToBeRepresented, cached_duration);
}
//now represent it (if not previously execute the EmptyRepresentation)
JaxbRepresentation<T> jaxb = new JaxbRepresentation<T>(dataToBeRepresented);
jaxb.setFormattedOutput(true);
return jaxb;
}
AS you can see, and you might asked me; yes I am implementing Cache through Kitty-Cache. So, if some XML that is expensive to produce, and really looks like will never change for 7 decades, then I will use cache... I also use it for likely static data. Maximum time limit for a cache is an hour to remain in memory.
Even when I cache the output, sometimes, output are irresponsive, like hang, printed partially, and takes time before it prints the remaining document. The XML document is accessible through browser and also program, it used GET.
What are actually the problem? I humbly would like to know also the answer from RESTlet developer, if possible. Thanks
data: [
{
type: "earnings"
info: {
earnings: 45.6
dividends: 4052.94
gains: 0
expenses: 3935.24
shares_bought: 0
shares_bought_user_count: 0
shares_sold: 0
shares_sold_user_count: 0
}
created: "2011-07-04 11:46:17"
}
{
type: "mentions"
info: [
{
type_id: "twitter"
mentioner_ticker: "LOANS"
mentioner_full_name: "ERICK STROBEL"
}
]
created: "2011-06-10 23:03:02"
}
]
Here's my problem : like you can see the "info" is different in each of one, one is a json object, and one is a json array, i usually choose Gson to take the data, but with Gson we can't do this kind of thing . How can i make it work ?
If you want to use Gson, then to handle the issue where the same JSON element value is sometimes an array and sometimes an object, custom deserialization processing is necessary. I posted an example of this in the Parsing JSON with GSON, object sometimes contains list sometimes contains object post.
If the "info" element object has different elements based on type, and so you want polymorphic deserialization behavior to deserialize to the correct type of object, with Gson you'll also need to implement custom deserialization processing. How to do that has been covered in other StackOverflow.com posts. I posted a link to four different such questions and answers (some with code examples) in the Can I instantiate a superclass and have a particular subclass be instantiated based on the parameters supplied thread. In this thread, the particular structure of the JSON objects to deserialize varies from the examples I just linked, because the element to indicate the type is external of the object to be deserialized, but if you can understand the other examples, then handling the problem here should be easy.
Both key and value have to be within quotes, and you need to separate definitions with commas:
{
"key0": "value0",
"key1": "value1",
"key2": [ "value2_0", "value2_1" ]
}
That should do the trick!
The info object should be of the same type with every type.
So check the type first. Pseudocode:
if (data.get('type').equals("mentions") {
json_arr = data.get('info');
}
else if (data.get('type').equals("earnings") {
json_obj = data.get('info');
}
I'm not sure that helps, cause I'm not sure I understand the question.
Use simply org.json classes that are available in android: http://developer.android.com/reference/org/json/package-summary.html
You will get a dynamic structure that you will be able to traverse, without the limitations of strong typing.....
This is not a "usual" way of doing things in Java (where strong typing is default) but IMHO in many situations even in Java it is ok to do some dynamic processing. Flexibility is better but price to pay is lack of compile-time type verification... Which in many cases is ok.
If changing libraries is an option you could have a look at Jackson, its Simple Data Binding mode should allow you to deserialize an object like you describe about. A part of the doc that is probably quite important is this, your example would already need JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES to work...
Clarification for Bruce: true, in Jackson's Full Data Binding mode, but not in Simple Data Binding mode. This is simple data binding:
public static void main(String[] args) throws IOException {
File src = new File("test.json");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature. ALLOW_UNQUOTED_FIELD_NAMES, true);
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS,true);
Object root = mapper.readValue(src, Object.class);
Map<?,?> rootAsMap = mapper.readValue(src, Map.class);
System.out.println(rootAsMap);
}
which with OP's sightly corrected sample JSON data gives:
{data=[{type=earnings, info={earnings=45.6, dividends=4052.94, gains=0,
expenses=3935.24, shares_bought=0, shares_bought_user_count=0, shares_sold=0,
shares_sold_user_count=0}, created=2011-07-04 11:46:17}, {type=mentions,
info=[{type_id=twitter, mentioner_ticker=LOANS, mentioner_full_name=ERICK STROBEL}],
created=2011-06-10 23:03:02}]}
OK, some hand-coding needed to wire up this Map to the original data, but quite often less is more and such mapping code, being dead simple has the advantage of being very easy to read/maintain later on.