How to parse a deep URL using jQuery params()? - java

Building an Android app that needs to parse a URL built with deep parameters using jQuery params().
Sample URL:
http://webapp.example.com/#params%5Bid%5D=33330&type=detail&channel=ss&view=Detail
The result should be JSON, which I can feed into Gson. Manual parsing is not optimal; a generic solution is preferable.
How can this task be done?

at first glance I thought you need a js/jquery solution. But on closer inspection, probably java. Anywhoo, I had already dont the former so you get both!
Js/jquery
url="http://webapp.example.com/#params%5Bid%5D=33330&type=detail&channel=ss&view=Detail";
delimatedString = url.substring(url.indexOf("#")+1,url.length); //remove everything before the #
var jsonObject = new Object();
$.each(delimatedString.split("&"), function(index, item) {//for loop to spit at the *&
//item is now in the syntax key=value
var keyValPair = item.split("="); //split each item at the = to seperate
var key = keyValPair[0];
var value = keyValPair[1];
jsonObject[key]=value;
});
java
String delimatedStrings = url.substring("&"+1, url.length)
String[] keyValuePairs = delimatedString.split("&");
Map<String, String> map = new HashMap<String, String>();
for (String keyValuePair : keyValuePairs)
{
String key = delimatedString.split("=")[0];
String value = delimatedString.split("=")[1];
map.put(key, value);
}
ps. I didnt compile the java, and you will need an external lib to take care of the map to JSON conversion.

Related

How to convert from Json to Protobuf?

I'm new to using protobuf, and was wondering if there is a simple way to convert a json stream/string to a protobuf stream/string in Java?
For example,
protoString = convertToProto(jsonString)
I have a json string that I want to parse into a protobuf message. So, I want to first convert the json string to protobuf, and then call Message.parseFrom() on it.
With proto3 you can do this using JsonFormat. It parses directly from the JSON representation, so there is no need for separately calling MyMessage.parseFrom(...). Something like this should work:
JsonFormat.parser().merge(json_string, builder);
//You can use this for converting your input json to a Struct / any other Protobuf Class
import com.google.protobuf.Struct.Builder;
import com.google.protobuf.Struct;
import com.google.protobuf.util.JsonFormat;
import org.json.JSONObject;
JSONObject parameters = new JSONObject();
Builder structBuilder = Struct.newBuilder();
JsonFormat.parser().merge(parameters.toString(), structBuilder);
// Now use the structBuilder to pass below (I used it for Dialog Flow V2 Context Management)
Since someone asked about getting the exception "com.google.protobuf.InvalidProtocolBufferException: JsonObject" when following Adam's advice--I ran into the same issue. Turns out it was due to the google protobuf timestamps. They are being serialized as an object containing two fields "seconds" and "nanos", since this isn't production code, I just got around this by parsing the JSON using jackson, going through the JSON object recursively and changing every timestamp from an object to a string formatted as per RFC 3339, I then serialized it back out and used the protobuf JSON parser as Adam has shown. This fixed the issue. This is some throwaway code I wrote (in my case all timestamp fields contain the word "timestamp", this could be more robust, but I don't care):
public Map<String, Object> fixJsonTimestamps(Map<String, Object> inMap) {
Map<String, Object> outMap = new HashMap<>();
for(String key : inMap.keySet()) {
Object val = inMap.get(key);
if(val instanceof Map) {
Map<String, Object> valMap = (Map<String, Object>)val;
if(key.toLowerCase().contains("timestamp") &&
valMap.containsKey("seconds") && valMap.containsKey("nanos")) {
if(valMap.get("seconds") != null) {
ZonedDateTime d = ZonedDateTime.ofInstant(Instant.ofEpochSecond((int)valMap.get("seconds")).plusNanos((int)valMap.get("nanos")),
ZoneId.of("UTC"));
val = d.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"));
}
} else {
val = fixJsonTimestamps(valMap);
}
} else if(val instanceof List && ((List) val).size() > 0 &&
((List) val).get(0) instanceof Map) {
List<Map<String, Object>> outputList = new ArrayList<>();
for(Map item : (List<Map>)val) {
outputList.add(fixJsonTimestamps(item));
}
val = outputList;
}
outMap.put(key, val);
}
return outMap;
}
Not the most ideal solution but it works for what I am doing, I think I saw someone recommend using a different timestamp class.
You can convert json string to Proto using builder and json String
Example :
YourProto.Builder protoBuilder = YourProto.newBuilder();
JsonFormat.parser().merge(JsonString, protoBuilder);
If you want to ignore unknown json field then
YourProto.Builder protoBuilder = YourProto.newBuilder();
JsonFormat.parser()..ignoringUnknownFields().merge(JsonString, protoBuilder);
Another way is, to use mergeFrom method from ProtocolBuffer
Example :
YourProto.Builder protoBuilder = YourProto.newBuilder();
protoBuilder.mergeFrom(JsonString.getBytes());
Once it execute, you will get all the data in protoBuilder from json String
online service:
https://json-to-proto.github.io/
This tool instantly converts JSON into a Protobuf. Paste a JSON structure on the left and the equivalent Protobuf will be generated to the right, which you can paste into your program. The script has to make some assumptions, so double-check the output!

JSONObject not workign

I am building an app for android.
I fire and HTTP GET request and this request returns a JSONObject. I want to retrieve the value by key. But this is not working properly.
This is the JSONObject named obj that I receive:
{"id":1,"name":"math","description":"This is a math course."}
If I log Log.d("title", String.valueOf(obj.has("name"))); this will result into true.
This works for all keys in the JSONObject.
But if I want to receive the name and do this so:
Log.d("title", obj.getString("name"));
I will get an unhandled exception: org.json.JSONException.
Does anybody know how I can fix this problem?
Maybe you should try someting like this:
Log.d("title", obj.name);
var obj = $.parseJSON('{"id":1,"name":"math","description":"This is a math course."}');
alert(obj['name']);
Try this :) You can use JSON.parse insted of $.parseJSON if you are not using jquery. Following in Java
String s = "{menu:{\"1\":\"sql\", \"2\":\"android\", \"3\":\"mvc\"}}";
JSONObject jObject = new JSONObject(s);
JSONObject menu = jObject.getJSONObject("menu");
Map<String,String> map = new HashMap<String,String>();
Iterator iter = menu.keys();
while(iter.hasNext()){
String key = (String)iter.next();
String value = menu.getString(key);
map.put(key,value);
}
Everything between the { } makes part of an array, so you first need to get a JSONArray like this:
JSONArray myJSONArray = obj.getJSONArray();
And then you can access the field values with:
myJSONArray.getString("name") etc...
Search on google how to work with JSONArray.

Parse JSON with Unknown values

I have some function where I receive such JSON:
String sorting ->> {"state":"desc"}
String filter ->> {"clientID":"XML"}
All value within are always different. How can I get Key and Value for such JSON?
Lets say :
KEYsorting =state , Valuesorting = desc
KEYfilter =clientID, Valuefilter = XML
I have searched a lot - including this website - but couldn't dealt with it. I guess it is not very difficult I I wasn't able to do that. Please help
You need to get a list of all the keys, loop over them and add them to your map as shown in the example below:
String sorting = "{\"state\":\"desc\"}";
JSONObject filter = new JSONObject(sorting);
Map<String,String> map = new HashMap<String,String>();
Iterator iter = filter.keys();
while(iter.hasNext()){
String key = (String)iter.next();
String value = filter.getString(key);
map.put(key,value);
}
you can try above example.

Get parameter names collection from Java/Android url

It's absolutely strange, but I can't find any Java/Android URL parser that will be compatible to return full list of parameters.
I've found java.net.URL and android.net.Uri but they are can't return parameters collection.
I want to pass url string, e.g.
String url = "http://s3.amazonaws.com/?AWSAccessKeyId=123&Policy=456&Signature=789&key=asdasd&Content-Type=text/plain&acl=public-read&success_action_status=201";
SomeBestUrlParser parser = new SomeBestUrlParser(url);
String[] parameters = parser.getParameterNames();
// should prints array with following elements
// AWSAccessKeyId, Policy, Signature, key, Content-Type, acl, success_action_status
Does anyone know ready solution?
There is way to get collection of all parameter names.
String url = "http://domain.com/page?parameter1=value1&parameter2=value2";
List<NameValuePair> parameters = URLEncodedUtils.parse(new URI(url));
for (NameValuePair p : parameters) {
System.out.println(p.getName());
System.out.println(p.getValue());
}
This static method builds map of parameters from given URL
private Map<String, String> extractParamsFromURL(final String url) throws URISyntaxException {
return new HashMap<String, String>() {{
for(NameValuePair p : URLEncodedUtils.parse(new URI(url), "UTF-8"))
put(p.getName(), p.getValue());
}};
}
usage
extractParamsFromURL(url).get("key")
Have a look at URLEncodedUtils
UrlQuerySanitizer added in API level 1
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(url_string);
List<UrlQuerySanitizer.ParameterValuePair> list = sanitizer.getParameterList();
for (UrlQuerySanitizer.ParameterValuePair pair : list) {
System.out.println(pair.mParameter);
System.out.println(pair.mValue);
}
The urllib library will parse the query string parameters and allow you to access the params as either a list or a map. Use the list if there might be duplicate keys, otherwise the map is pretty handy.
Given this snippet:
String raw = "http://s3.amazonaws.com/?AWSAccessKeyId=123&Policy=456&Signature=789&key=asdasd&Content-Type=text/plain&acl=public-read&success_action_status=201";
Url url = Url.parse(raw);
System.out.println(url.query().asMap());
for (KeyValue param : url.query().params()) {
System.out.println(param.key() + "=" + param.value());
}
The output is:
{Policy=456, success_action_status=201, Signature=789, AWSAccessKeyId=123, acl=public-read, key=asdasd, Content-Type=text/plain}
AWSAccessKeyId=123
Policy=456
Signature=789
key=asdasd
Content-Type=text/plain
acl=public-read
success_action_status=201

Parse JSON object with string and value only

I have problem when trying to parse with minimum value to map in Android.
There some sample JSON format with more information ex:
[{id:"1", name:"sql"},{id:"2",name:"android"},{id:"3",name:"mvc"}]
This that example most common to use and easy to use just use getString("id") or getValue("name").
But how do I parse to map using this JSON format with just only string and value minimum format to java map collection using looping. And because the string json will always different one with another. ex:
{"1":"sql", "2":"android", "3":"mvc"}
Thank
You need to get a list of all the keys, loop over them and add them to your map as shown in the example below:
String s = "{menu:{\"1\":\"sql\", \"2\":\"android\", \"3\":\"mvc\"}}";
JSONObject jObject = new JSONObject(s);
JSONObject menu = jObject.getJSONObject("menu");
Map<String,String> map = new HashMap<String,String>();
Iterator iter = menu.keys();
while(iter.hasNext()){
String key = (String)iter.next();
String value = menu.getString(key);
map.put(key,value);
}
My pseudocode example will be as follows:
JSONArray jsonArray = "[{id:\"1\", name:\"sql\"},{id:\"2\",name:\"android\"},{id:\"3\",name:\"mvc\"}]";
JSON newJson = new JSON();
for (each json in jsonArray) {
String id = json.get("id");
String name = json.get("name");
newJson.put(id, name);
}
return newJson;

Categories

Resources