re-stringify a string in Android - java

I have a string that i'd like to stringify in Kotlin (Android), but it seems that org.json.* doesn't support taking a string and re-stringifying it, instead it always tries to parse it first.
val str = "test=\"123\""
val stringified = JSONObject(str).toString() // JSONException: Value a of type java.lang.String cannot be converted to `JSONObject`
The use case for this ability is passing data to JS inside a Webview in a secure manner.
val json = "test=\"123\""
webview.evaluateJavascript("window.onData(${json})")
// on the JS side it will look like this: window.onData(test="123")
// this is both invalid and insecure since it opens the door for raw JS injection
Any attempt to do it manually will result in an insecure and possibly invalid JS string
This example should NOT be used:
val insecureJSON = "'${str.replace("\\", "\\\\").replace("\"", "\\\"").replace("'", "\'")}'"
The desired behavior:
val json = jsonStringifyString("test=\"123\"")
webview.evaluateJavascript("window.onData(${json})")
// rendered JS: window.onData("test=\"123\"")
Is there an easy method for stringifying a string in Android?

Ended up using the JSONArray class and removing the array wrapping to trick the class to stringify a plain string
fun jsonStringifyString(str: String): String {
val jsonStr = JSONArray().put(str).toString()
return jsonStr.substring(1, jsonStr.length - 1) // remove first and last char
}
val serializedData = jsonStringifyString("test=\"123\"");
webview.evaluateJavascript("window.onData(${serializedData})")
// rendered JS: window.onData("test=\"123\"")

Related

Why JsonParser gives double quotes in the return value, using com.google.gson API

I am currently using JsonObject and JsonParser of com.google.gson api (using gson-2.8.5 version) to parse and read the value form input JSON.
I have JSON filed like , smaple "resultCode":"SUCCESS", when I try to read the same value from json it gives the result as ""SUCCESS"" .
Every value I am reading, getting with double "" not sure why ? You can refer below screen of my debugging screen.
I am new to Json and parser, is that default behavior ?
I am expecting "SUCCESS", "S", "00000000" not like ""SUCCESS"" or ""S""
or ""00000000""
same I have highlighted in the below image .
Please share any idea how we can get apbsolute vlaue of string without """" double quote string it causing my string comparison fail.
String response_result = "{\"response\": {\"head\": {\"function\": \"acquiring.order.create\",\"version\": \"2.0\",\"clientId\": \"201810300000\",\"reqMsgId\": \"56805892035\",\"respTime\": \"2019-09-13T13:18:08+08:00\"},\"body\": {\"resultInfo\": {\"resultCode\": \"SUCCESS\",\"resultCodeId\": \"00000000\",\"resultStatus\": S,\"resultMsg\": \"SUCCESS\"},\"acquirementId\": \"2018080834569894848930\",\"merchantTransId\": \"5683668701112717398\",\"checkoutUrl\": \"http://localhost:8081/crm/operator/operator-search-init.action\"}},\"signature\":\"d+TUYLvt1a491R1e6aO8i9VwXWzVhfNgnhD0Du74f4RgBQ==\"}";
HttpInvoker.Result result = i.new Result(200, response_result);
JsonObject jo = new JsonParser().parse(response_result).getAsJsonObject();
String resultCode = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCode").toString();
String resultCodeId = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCodeId").toString();
String resultStatus = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultStatus").toString();
String checkoutUrl = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("checkoutUrl").toString();
if ( RESULT_CODE_GCASH_SUCCESS.equals(resultCode)
&& RESULT_STATUS_SUCCESS.equals(resultStatus)
&& StringUtils.isNotEmpty(checkoutUrl)) {
log.error("Testing ".concat(resultCode).concat(resultStatus).concat(checkoutUrl));
}
log.error("Testing ".concat(resultCode).concat(resultStatus).concat(checkoutUrl));
}
This is my input JSON
{
"response":{
"head":{
"function":"acquiring.order.create",
"version":"2.0",
"clientId":"201810300000",
"reqMsgId":"56805892035",
"respTime":"2019-09-13T13:18:08+08:00"
},
"body":{
"resultInfo":{
"resultCode":"SUCCESS",
"resultCodeId":"00000000",
"resultStatus":"S",
"resultMsg":"SUCCESS"
},
"acquirementId":"2018080834569894848930",
"merchantTransId":"5683668701112717398",
"checkoutUrl":"http://localhost:8081/crm/operator/operator-search-init.action"
}
},
"signature":"d+TUYLvtI38YL2hresd98Ixu1BXccvvh1IQMiHuMXUEeW/N5exUsW491R1e6aO8i9VwXWzVhfNgnhD0Du74f4RgBQ=="
}
JsonParser parses your json into JsonElement structure. The behaviour that you see is a normal since you are using toString method of JsonElement. To achieve your goal just use JsonElement::getAsString method :
String resultCode = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().get("resultCode").getAsString();
which gives SUCCESS instead of "SUCCESS"
Note that JsonElement is an abstract class and classes, that extend this class, will override those helper getAs... methods. In your case JsonPrimitive::getAsString will be invoked.
Also you could create a POJO class for your json and use Gson::fromJson to parse json into object of your POJO class.
With the input from #Michalk:
I understand that easy way to read JSON data is using Gson::fromJson and creating POJO class for out json.
I have generated POJO Classes supplying my sample input JSON using this link
and Now I have POJO Classes called : CreateOrderJSONResponse
Gson::fromJson
Sample :
Gson gson = new Gson();
CreateOrderJSONResponse responseJson = gson.fromJson(inputJSON, CreateOrderJSONResponse.class);
Accessubg data :
String resultCodeText = responseJson.getResponse().getBody().getResultInfo().getResultCode();
String resultCodeId = responseJson.getResponse().getBody().getResultInfo().getResultCodeId();
String resultStatus = responseJson.getResponse().getBody().getResultInfo().getResultStatus();
String checkoutUrl = responseJson.getResponse().getBody().getCheckoutUrl();
Above Gson::fromJson example works smooth and it looks neat compare to direct accessing the filed with below sample code :
JsonObject jo = parser.parse(inputJSON).getAsJsonObject();
String resultCodeText = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultCode").getAsString();
String resultCodeId = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultCodeId").getAsString();
String resultStatus = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().get("resultInfo").getAsJsonObject().getAsJsonPrimitive("resultStatus").getAsString();
String checkoutUrl = jo.get("response").getAsJsonObject().get("body").getAsJsonObject().getAsJsonPrimitive("checkoutUrl").getAsString();
Note :
I have found this link of JSON or JAVA, SCALA, POJO generator tools as GitHub access you can access here

Scala API response JSON parser from JSON object

I am new to Scala. I was trying to parse an API response in Scala. The API response is in the format:
{"items":[{"name":"john", "time":"2017-05-11T13:51:34.037232", "topic":"india", "reviewer":{"id":"12345","name":"jack"}},
{"name":"Mary", "time":"2017-05-11T13:20:26.001496", "topic":"math", "reviewer":{"id":"5678","name":"Tom"}}]}
My target is to populate a list of reviewer id's from the JSON response. I tried to create a JSON object from the response by
val jsonObject= parse(jsonResponse.getContentString()).getOrElse(Json.empty)
but couldn't get the reviewer ids from the json object. Even tried to iterate the JSON object, but didn't work.
I am not familiar with circe but here is how you would do it with spray-json
import spray.json._
import DefaultJsonProtocol._
val jsonResponse = """{"items":[{"name":"john", "time":"2017-05-11T13:51:34.037232", "topic":"india", "reviewer":{"id":"12345","name":"jack"}},{"name":"Mary", "time":"2017-05-11T13:20:26.001496", "topic":"math", "reviewer":{"id":"5678","name":"Tom"}}]}"""
Need to define the schema using case classes:
case class Reviewer(id: String, name: String)
case class Item(name: String, time: String, topic: String, reviewer: Reviewer)
case class Items(items: Array[Item])
And their implicit conversion:
implicit val reviewerImp: RootJsonFormat[Reviewer] = jsonFormat2(Reviewer)
implicit val itemConverted: RootJsonFormat[Item] = jsonFormat4(Item)
implicit val itemsConverted: RootJsonFormat[Items] = jsonFormat1(Items)
Then it's very simple, parsing is just this:
val obj = jsonResponse.parseJson.convertTo[Items]
At last, get the ids for the reviewers:
val reviewers = obj.items.map(it => it.reviewer.id)
You mentioned play, so here's how you could do it in Play
case class Reviewer(id:Long, name:String)
object Reviewer { implicit val format = Json.format[Reviewer] }
Once you have those set up you could either
val json:JsValue = Json.toJson(reviewerObject)
val json:JsObject = Json.toJson(reviewerObject).as[JsObject]
val json:String = Json.toJson(reviewerObject).toString // Valid json string
Or
val reviewer:Reviewer = Json.parse(reviewerJsonString).as[Reviewer]
val validates:Boolean = Json.parse(reviewerJsonString).validates[Reviewer]

How to send content from Freemarker to java by request?

I'm trying send information from a FreeMarker template to my Java model class.
I've tried this:
//my array of string casted in a string
var pais = selected.join();
request.setAttribute(pais, "paises");
Ok, now I'm trying collect this content in my Java class doing this:
String paises = MgnlContext.getAttribute("paises");
But it doenst work. I tried other methods like this:
Stirng paises = MgnlContext.getInstance().getAttribute("paises");
But it always returns null.
SOLUTION (sending info by ajax):
first get the values by javscript :
[#assign cpathx = ctx.contextPath]
[#assign url = model.getUrl() /]
var field = $('#key').val();
var calin = $('#calendarIni').val();
var calfin = $('#calendarFin').val();
var pais = selected.join();
var url = '${cpathx}${url}?paises='+pais+'&palabra='+field+'&calendarini='+calin+'&calendarfin='+calfin;
jQuery.post(url ,function(data) {
jQuery('#ajax').html(data);
});
Now we can collect the info in java:
String paises = MgnlContext.getWebContext().getAttribute("paises");
String queryString = MgnlContext.getWebContext().getAttribute("palabra");
String dateStart = MgnlContext.getWebContext().getAttribute("calendarini");
String dateEnd = MgnlContext.getWebContext().getAttribute("calendarfin");
That first piece doesn't look like freemarker but more as JavaScript, so maybe that is your problem. While freemarker directives are executed server side, html and Js produced by freemarker is executed client side so w/o Ajax call there's no way for Js to talk back to server (and thus to model class).
If you were really interested in passing something from freemarker to java model, model is exposed directly. You can simply add method in java model and call it from freemarker template like
${model.myMethod(someParam)}
HTH,
Jan

Pass an array collection in JSON

I am trying to pass an array collection from flex page to my backend java.Here is the code,
private function getItems():void{
myObj = new Object();
myObj['dId']= dId.value.toString();
myObj['itmList']=JSON.encode(itmList);// trying to pass like this..
var url:String = URLManager.baseURL;
url = url+"myController/ReportController?do=getItems";
url = url+"&parameter="+ escape(JSON.encode(myObj))
var urlRequest:URLRequest = new URLRequest(url);
navigateToURL(urlRequest,"_blank");
}
My itmList is an array collection, how can I pass it from JSon to Java controller? And how to get that in Java?
JSON.encode the itmList source array instead. (i.e. itmList.source is an array)
Then use HTTPService instead:
HTTPService AsyncToken and AsyncResponder example
Another option is to use JSON.stringify instead (Flash has had native JSON support since FP 11). Just make sure you remove the import com.adobe.serialization.json.JSON; from the top of your file.
myObj['itmList']=JSON.stringify(itmList);
Or, since you're encoding your whole data object,
myObj['itmList']=itmList.source;
var url:String = URLManager.baseURL;
url = url+"myController/ReportController?do=getItems";
url = url+"&parameter="+ escape(JSON.stringify(myObj))
var urlRequest:URLRequest = new URLRequest(url);
navigateToURL(urlRequest,"_blank");

how to return data in json format to javascript ajax call

I have the following method:
public String getUTResult() throws IOException {
BuildResultParser bp = new BuildResultParser();
BuildResultBean b = bp.getreadFile("C:\\bc.txt");
String str = b.getuTresult();
return str;
Now str variable contains the value as: [0,5,5]
Now I need to pass this value to ajax call in javascript in following format:
unittest
{
fail:0
pass:5
total:5
}
Actually in javascript, I need this data in array format so that I can access each value and do some processing.
Read this : http://hmkcode.com/java-servlet-send-receive-json-using-jquery-ajax/ or any example of converting data to json format.
If your requirement is limited to the example, u can have another function which takes str and creates json data out of it, in the format required by you.

Categories