encode json object params in httpurlconnection - java

I want post some parameters to server with httpurlconnection in android,my data is an nested JsonObject , and i must encode it first but it's wrong because i receive status error from server, this is my encode function and Jsonobject:
private static String encodeParams(JSONObject params) throws Exception {
StringBuilder result = new StringBuilder();
boolean first = true;
Iterator<String> itr = params.keys();
while(itr.hasNext()){
String key= itr.next();
Object value = params.get(key);
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(key, "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(value.toString(), "UTF-8"));
}
return result.toString();
}
my nested json:
JSONObject postDataParams = new JSONObject();
postDataParams.put("name", "Manjeet");
postDataParams.put("email", "manjeet#gmail.com");
JSONObject par = new JSONObject();
par.put("class", "a");
par.put("family", "aray");
postDataParams.put("par", par);

Construct a URI from the output, only encoding the characters ?#/
which is a lot easier than your loop
You can use URI's, which produce a different output and result
The following sample
new URI("http", "host.com", "/path/", "key=| ?/#ä", "fragment").toURL();
produces the result http://host.com/path/?key=%7C%20?/%23ä#fragment. Note how characters such as ?&/ are not encoded to allow for the URI Query string
(Copied from the API)

I'am not sure about this code, since i've never worked with JSONObject, but i'll try to show you the idea :
Create a method which returns all the properties of an object (including the nested one) :
Map<String, String> jobjectToMap(JSONObject jo) {
Map<String, String> properties = new HashMap<String, String>;
Iterator<String> itr = jo.keys();
while(itr.hasNext()){
String key= itr.next();
Object value = jo.optJSONObject(key);//this will returns null if the value is not a JSONObject from https://docs.oracle.com/middleware/maf242/mobile/api-ref/oracle/adfmf/json/JSONObject.html#getJSONObject-java.lang.String-
if(value != null) { //nested object
properties.putAll(jobjectToMap(value));
} else {
properties.put(key, jo.get(key)); //primitive one
}
}
return properties;
}
Create another method which transforms the map to an url
public String queryParams(Map<String, String> params)
throws UnsupportedEncodingException
{
StringBuilder queryString = new StringBuilder();
if (params.size() > 0) {
queryString.append('&');
}
// Convert the params map into a query string.
for (Map.Entry<String, String> entry : params.entrySet())
{
String encodedKey = URLEncoder.encode(entry.getKey(), "UTF-8");
String encodedValue = URLEncoder.encode(entry.getValue(), "UTF-8");
queryString.append(encodedKey);
queryString.append('=');
queryString.append(encodedValue);
}
return queryString.toString();
}

Related

How to parse JSON with multiple return types

I need to parse a JSON, that can be of any type.
The data returned can be much complicated but i just need to fetch the value string used in that JSON object or array
The example of the JSON data is
https://finance.yahoo.com/webservice/v1/symbols/allcurrencies/quote?format=json
What I have done so far is :
public class UrlActions {
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONObject json = new JSONObject(jsonText);
return json;
} finally {
is.close();
}
}
}
but cannot be the same thing as i want
Kindly please help me
Thanks
Regards
you should have a class of the type of the objects in the json, then you can use libraries such as Jackson's ObjectMapper to read values, e.g.
List<Quote> quotes = objectMapper.readValue(yourjson, new TypeReference<List<Quote>>(){});
For a structure which have key and value both of type string, one can use the below code.
String json = "{\"name\":\"Shepherd\", \"age\":26}";
Map<String, Object> map = new HashMap<String, Object>();
// convert JSON string to Map
map = mapper.readValue(json, new TypeReference<Map<String, String>>(){});
Now you can do:
map.get(key) //Here map.get("name")
for whatever you want to retrieve.However in your case as pointed out in the previous answer you need to provide the suitable Type References.
NOTE: I am using jackson here.
If you have no idea what is in the JSON (so you can't parse it with a class), you can take Google GSON (Maven). With that you can iterate JSON file by using JsonToken to know what is next.
JsonReader reader = new JsonReader(new FileReader(inputfile));
while (reader.hasNext()) {
JsonToken currentToken = reader.peek();
switch (currentToken) {
case BEGIN_OBJECT:
// read "{"
reader.beginObject();
break;
case END_OBJECT:
// read "}"
reader.endObject();
break;
case BEGIN_ARRAY:
// read "["
reader.beginArray();
break;
case END_ARRAY:
// read "]"
reader.endArray();
break;
case END_DOCUMENT:
// end of document
break;
default:
reader.nextName(); // that gives "key"
// next gives "values"
reader.nextNull();
reader.nextString();
reader.nextBoolean();
// there others like nextLong(), nextInt() but i recommand you
// to check if JsonToken.NUMBER, take the value in string
// then parse it in the numeric class you want
}
}

Recover the value of a hashmap that is in another hashmap

I want to retrieve the value of key in a Hashmap that is in another Hashmap,
static HashMap<String , HashMap<String, Float>> terms = new HashMap();
static String date;
public static void main(String[] args) throws FileNotFoundException, ParseException, IOException {
InputStream ips=new FileInputStream(filePath);
InputStreamReader ipsr=new InputStreamReader(ips);
BufferedReader br=new BufferedReader(ipsr);
String ligne;
while ((ligne=br.readLine())!=null){
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(ligne);
date = (String) jsonObject.get("created_at");
String text = (String) jsonObject.get("text");
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
List<String> ss=TokenizewithAnalyzer.tokenizeString(analyzer, text);
for(String s : ss){
ajoutFrequence(s, date);}
System.out.print("==>"+ss+" \n");}
for(Entry <String, HashMap<String, Float>> entry : terms.entrySet()){
// float res=entry.getValue().get(date).floatValue();
System.out.println(entry.getValue().get(date).floatValue());
}
br.close();
}
static void ajoutFrequence(String token, String date){
if(terms.containsKey(token)){
HashMap<String, Float> freqdate = terms.get(token);
if(freqdate.containsKey(date)){
freqdate.put( date, freqdate.get(date)+1);
}else{
freqdate.put(date, Float.valueOf(1));
}
}else{
HashMap<String, Float> freqdate = new HashMap<>();
freqdate.put(date, Float.valueOf(1));
terms.put(token, freqdate);
} }}
in the output I get the frequence in a list for example:
null
null
1.0
null
null
null
I want to do something like this: float freq=entry.getValue().values(); but it is impossible.Thank you in advance.
You use the date as a key in your second map. So I assume you could do following:
for(Entry <String, HashMap<String, Float>> entry : terms.entrySet()){
System.out.println(entry.getValue().get(date));
}
To access a specific value in your second map, you need to provide a key for this value. In your case, this key is a date.
I solved the problem in fact I used two loop to traverse the hashmap and I recovered the value of the second hashmap like this:
for(Entry <String, HashMap<String, Float>> entry : terms.entrySet()){
HashMap<String, Float> d=entry.getValue();
for(Entry<String,Float>ent:d.entrySet()){
float dd=ent.getValue();
System.out.println(dd);}}
At the end I got the float. Thank you.

how to achieve string conversion of list of maps in java

How can i convert JSON string to format given below and back to JSON string.
List<Map<String, String>> variables =new ArrayList<>();
I tried searching for this. Only thing which i could find is converting list to array and then to string. But using
TypeA[] array = a.toArray(new TypeA[a.size()]);
does not seems feasible here.
Converting List<Map<String,String>> to JSON string :
public String listmap_to_json_string(List<Map<String, String>> list)
{
JSONArray json_arr=new JSONArray();
for (Map<String, String> map : list) {
JSONObject json_obj=new JSONObject();
for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
try {
json_obj.put(key,value);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
json_arr.put(json_obj);
}
return json_arr.toString();
}
Or simply using google gson library:
public String listmap_to_json_string(List<Map<String, String>> list){
// Use toJson method to serialize list to Json
return new GsonBuilder().setPrettyPrinting().create().toJson(list);
}
Converting JSON string to List<Map<String,String>>:
public List<Map<String, String>> json_string_to_listmap(String json){
Gson gson = new Gson();
Type type = new TypeToken<ArrayList<Map<String, String>>>() {}.getType();
// Use fromJson method to deserialize json into an ArrayList of Map
return gson.fromJson(json , type);
}
For more informations check this link.
Indeed you should update your question to give more details. Meanwhile, with the current understanding I have from your post I would suggest you to look at ObjectMapper class from org.codehaus.jackson.map.
You will easily get a JSON converted in the type you want by using
// string in json format
String json;
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(json, TypeA.class);
This code show how convert json string to type List<Map<String,String>>:
ObjectMapper objectMapper = new ObjectMapper();
try {
TypeReference < List < Map < String, String >>> typeReference = new TypeReference < List < Map < String, String >>> () {
};
List < Map < String, String >> res = objectMapper.readValue("[{\"size\":\"100x200\"}]", typeReference);
System.out.println("type: " + typeReference.getType());
for (Map < String, String > map: res) {
for (String key: map.keySet()) {
System.out.println(key + " : " + map.get(key));
}
}
} catch (IOException e) {
e.printStackTrace();
}

Parse HTTP JSONObject response in java

From the endpoint "test" I am returning a JSONObject:
#POST("/test")
#PermitAll
public JSONObject test(String name) {
JSONObject jsonval=new JSONObject();
json.put("key1",true);
json.put("key2","test");
return json;
}
in the method that checks the returned value I want to search for value of "key1".
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json = null;
String res = "";
while ((res = in.readLine()) != null) {
json += res + "\n";
}
in.close();
if (jsonData has key1 with value true){
//do sth
}
else{
//do sth else
}
How can I parse the returned JSONObject?
Have you tried constructing the JSONObject from its string representation (see http://www.json.org/javadoc/org/json/JSONObject.html):
JSONObject result = new JSONObject(json)
where json is the string you've read from the InputStream
Note: you might have to strip the last new line char or even omit new lines altogether

getting string on my browser output while testing servlet

I am running the following servlet and I am getting some weird output on my browser.The program is working fine without any errors but for some reason, the output of the line out.println(Add_To_Queue("abc","xyz","pqr")); is getting displayed
in the form of java string as shown below the code:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
out.println("<!DOCTYPE> html"); // HTML 5
out.println("<html><head>");
out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
out.println(Test_Servlet("abc","xyz","pqr"));
out.println("<head><title>TEST SERVLET API Call</title></head>");
out.println("<body>");
out.println("<h3>TEST SERVLET</h3>");
// Tabulate the request information
out.println("</body></html>");
}
finally {
out.close(); // Always close the output writer
}
}
public static Object Test_Servlet(String FirstString,String Secondstring,String ThirdString) throws IOException {
String accessKey = "myaccesskey";
String secretKey = "mysecretkey";
String uRLCppList = "http://myurl.com";
String method = "POST";
java.util.Date currentTime = new java.util.Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
// Give it to me in GMT time.
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString = sdf.format(currentTime);
String signature = generateSignature(method, secretKey, dateTimeString);
String authorization = accessKey + ":" + signature;
Map<String, String> params = new HashMap<String, String>();
params.put("Content of first String", FirstString);
params.put("Content of Second String", Secondstring);
params.put("Content of Third String", ThirdString);
String[] result = sendHttpRequest(uRLCppList, "POST", params, dateTimeString, authorization);
return result;
}
Here is the browser output:
html [Ljava.lang.String;#430bc84a
TEST SERVLET
I am using JDK 8, ApacheTomcat 6, Netbeans 7.4 for deployment. I suspect, the result which is getting returned in the variable result defined inside Test_Servlet method is not getting displayed properly on the web browser.
Additional Code for SendHttpRequest method:
public static String[] sendHttpRequest(String requestUrl, String method, Map<String, String> params, String dateTimeString, String authorization) throws IOException {
List<String> response = new ArrayList<String>();
StringBuffer requestParams = new StringBuffer();
if (params != null && params.size() > 0) {
Iterator<String> paramIterator = params.keySet().iterator();
while (paramIterator.hasNext()) {
String key = paramIterator.next();
String value = params.get(key);
requestParams.append(URLEncoder.encode(key, "UTF-8"));
requestParams.append("=").append(URLEncoder.encode(value, "UTF-8"));
requestParams.append("&");
}
}
URL url = new URL(requestUrl);
URLConnection urlConn = url.openConnection();
urlConn.setRequestProperty("accept", "application/json");
urlConn.setRequestProperty("datetime", dateTimeString);
urlConn.setRequestProperty("authorization", authorization);
urlConn.setUseCaches(false);
// the request will return a response
urlConn.setDoInput(true);
if ("POST".equals(method)) {
// set request method to POST
urlConn.setDoOutput(true);
} else {
// set request method to GET
urlConn.setDoOutput(false);
}
if ("POST".equals(method) && params != null && params.size() > 0) {
OutputStreamWriter writer = new OutputStreamWriter(urlConn.getOutputStream());
writer.write(requestParams.toString());
writer.flush();
}
// reads response, store line by line in an array of Strings
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
return (String[]) response.toArray(new String[0]);
}
Your Test_Servlet method is returning an array of String. The result of calling toString() on an array is the string you're getting which includes the type and the object Id.
Not sure exactly what you're trying to do but you could put the strings out by iterating through the returned array.
html [Ljava.lang.String;#430bc84a
html comes from the out.println("<!DOCTYPE> html"); where you need to close the tag.
The [Ljava.lang.String;#430bc84a is the default to toString for an array of strings, telling you where the reference exists. The [ - means array and what follows is the type which happens to be java.lang.String. This is JVM level output
Id do something like:
String resultStr = "";
for(String s: result){
//format however you wish, this separates each element by a space
resultStr += s + " ";
}
return resultStr
If you want to put the results in a table or something, you could return the array and use the same for loop to encapsulate each element in a tag. The choice is yours and either works fine

Categories

Resources