How to convert a map to Json string in kotlin? - java

I have a mutableMap,
val invoiceAdditionalAttribute = mutableMapOf<String, Any?>()
invoiceAdditionalAttribute.put("clinetId",12345)
invoiceAdditionalAttribute.put("clientName", "digital")
invoiceAdditionalAttribute.put("payload", "xyz")
I want to convert it into json string
the output should be,
"{\"clinetId\"=\"12345\", \"clientName\"=\"digital\", \"payload\"=\"xyz\"}"
Currently, I am using Gson library,
val json = gson.toJson(invoiceAdditionalAttribute)
and the output is
{"clinetId":12345,"clientName":"digital","payload":"xyz"}

The right json formatting string is:
{"clinetId":12345,"clientName":"digital","payload":"xyz"}
So this is the right method to get it:
val json = gson.toJson(invoiceAdditionalAttribute)
If you want a string formatted like this:
{"clinetId"=12345, "clientName"="digital", "payload"="xyz"}
just replace : with =:
val json = gson.toJson(invoiceAdditionalAttribute).replace(":", "=")
But if you truly want to have a string with backslashes and clinetId value to be inside quotes:
val invoiceAdditionalAttribute = mutableMapOf<String, Any?>()
invoiceAdditionalAttribute["clinetId"] = 12345.toString()
invoiceAdditionalAttribute["clientName"] = "digital"
invoiceAdditionalAttribute["payload"] = "xyz"
val json = gson.toJson(invoiceAdditionalAttribute)
.replace(":", "=")
.replace("\"", "\\\"")
EDIT:
As pointed int he comments .replace(":", "=") can be fragile if some string values contain a ":" character.
To avoid it I would write a custom extension function on Map<String, Any?>:
fun Map<String, Any?>.toCustomJson(): String = buildString {
append("{")
var isFirst = true
this#toCustomJson.forEach {
it.value?.let { value ->
if (!isFirst) {
append(",")
}
isFirst = false
append("\\\"${it.key}\\\"=\\\"$value\\\"")
}
}
append("}")
}
// Using extension function
val customJson = invoiceAdditionalAttribute.toCustomJson()

Related

How to parse a application/x-www-form-urlencoded with an associative array?

I'm trying to parse the following body:
event=invoice.created&data%5Bid%5D=1757E1D7FD5E410A9C563024250015BF&
data%5Bstatus%5D=pending&data%5Baccount_id%5D=70CA234077134ED0BF2E0E46B0EDC36F&
data%5Bsubscription_id%5D=F4115E5E28AE4CCA941FCCCCCABE9A0A
Which translates to:
event = invoice.created
data[id] = 1757E1D7FD5E410A9C563024250015BF
data[status] = pending
data[account_id] = 70CA234077134ED0BF2E0E46B0EDC36F
data[subscription_id] = F4115E5E28AE4CCA941FCCCCCABE9A0A
Code:
#PostMapping(consumes = [MediaType.APPLICATION_FORM_URLENCODED_VALUE])
fun cb(event: SubscriptionRenewed)
{
println(event)
}
data class SubscriptionRenewed(
val event: String,
val data: Data
)
data class Data(
val id: String,
val status: String,
val account_id: String,
val subscription_id: String
)
Normally you just create a POJO representation of the incoming body and spring a translates it to an object.
I learned that I could add all the parameters to the function declaration as #RequestParam("data[id]") id: String, but that would make things really verbose.
The issue is with parsing data[*], ideas of how to make it work?
Edit:
I discovered that if I change val data: Data to val data: Map<String, String> = HashMap(), the associative array will be correctly inserted into the map, ideas of how to map it to an object instead?
Note: IDs/Tokens are not real. They are from a documentation snippet.
Deserialize to Map and use json serialize/deserialize to object
Initially deserialize the input to Map<String, String>
Use Json processor(like ObjectMapper or Gson) to serialize the Map constructed in the previous step
Use the json processor to deserialize the json output of previous step to a custom object.
static class Data {
private String one;
private String a;
#Override
public String toString() {
return "Data{one=" + one + ", a=" + a + "}";
}
}
public static void main(String[] args) {
String input = "{\"one\":1, \"a\":\"B\"}";
Gson gson = new GsonBuilder().create();
Map<String, String> map = gson.fromJson(input, new TypeToken<Map<String, String>>(){}.getType());
Data data = gson.fromJson(gson.toJson(map), Data.class);
System.out.println(data);
}
This is surely a round about approach and i am not aware of any optimization

Why getting Gson MalFormatException

I have json string as below i want to convert to object
{"Init":{"MOP":[{"Id":"1","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXB","TerminalId":"P400Plus-275008565","IP":"10.0.0.0:900","Currency":"EUR"},{"Id":"2","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXF","TerminalId":"P400Plus-275008565","IP":"10.0.0.0:901","Currency":"EUR"}]}}
My json is valid , i tried on here also i created POJO class on here but i'm getting com.google.gson.stream.MalformedJsonException
Here my code
val receiveString = "{"Init":{"MOP":[{"Id":"1","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXB","TerminalId":"P400Plus-275008565","IP":"10.0.0.0:900","Currency":"EUR"},{"Id":"2","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXF","TerminalId":"P400Plus-275008565","IP":"10.0.0.0:901","Currency":"EUR"}]}}"
val root = gson.fromJson(receiveString,TestClass.Root::class.java) //getting error here
Here my POJO class
class Root {
#JsonProperty("Init")
var init: Init? = null
}
class MOP {
#JsonProperty("Id")
var id: String? = null
#JsonProperty("Type")
var type: String? = null
#JsonProperty("ProtocolVersion")
var protocolVersion: String? = null
#JsonProperty("MopCode")
var mopCode: String? = null
#JsonProperty("TerminalId")
var terminalId: String? = null
#JsonProperty("IP")
var ip: String? = null
#JsonProperty("Currency")
var currency: String? = null
}
class Init {
#JsonProperty("MOP")
var mop: List<MOP>? = null
}
What yu can suggest me?
doubleQuote (") in your string must be escaped like "
I solved my problem with adding extra quotes missing parts as below
{"Init":{"MOP":[{"Id":"1","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXB","TerminalId":"'P400Plus-275008565'","IP":"'192.168.1.15'","Currency":"EUR"},{"Id":"2","Type":"0","ProtocolVersion":"1.0","MopCode":"*NEXF","TerminalId":"'P400Plus-275008565'","IP":"'10.0.0.0:901'","Currency":"EUR"}]}}

Reading data from Android App using bluetooth

I have Java code to receive data in Android App via Bluetooth like the attached code
Java Code
so readMessage will equal = {\"Pin\":\"A4\",\"Value\":\"20\"},{\"Pin\":\"A5\",\"Value\":\"925\"},{\"Pin\":\"A0\",\"Value\":\"30\"}
So I want to take only the values after string \"Value\" from received data so
Can anyone suggest how to make do that?
Thanks
you can parse the readMessage with JSON format
example:
String[] pinValueArr = readMessage.split(",")
for (String pinValue : pinValueArr) {
try {
JSONObject pinValueJSON = new JSONObject(pinValue);
String pin = pinValueJSON.optString("pin", ""); // opt means if parse failed, return default value what is ""
int pin = pinValueJSON.optInt("Value", 0); // opt means if parse failed, return default value what is "0"
} catch (JSONParsedException e) {
// catch exception when parse to JSONObject failed
}
}
And if you want to manage them, you can make a List and add them all.
List<JSONObject> pinValueList = new ArrayList<JSONObject>();
for (String pinValue : pinValueArr) {
JSONObject pinValueJSON = new JSONObject(pinValue);
// ..
pinValueList.add(pinValueJSON);
}
You can use Gson to convert Json to Object.
(https://github.com/google/gson)
Create Model Class
data class PinItem(
#SerializedName("Pin")
val pin: String? = null,
#SerializedName("Value")
val value: String? = null
)
Convert your json.
val json = "[{"Pin":"A4","Value":"20"},{"Pin":"A5","Value":"925"},{"Pin":"A0","Value":"30"}]"
val result = Gson().fromJson(this, object : TypeToken<List<PinItem>>() {}.type)
So now you having list PinItem and you can get all info off it.

How to take specific value from key in JSON in Scala?

I want to return the value "stations" from the key "base" in the JSON below from the url https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22. How do I do that in Scala?
Here is what I attempted.
import scalaj.http._
import play.api.libs.json.{JsValue, Json}
object JSON {
def convertToJson(): String = {
val url: String = "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22"
val response: String = Http(url).asString.body
val parsed: JsValue = Json.parse(response)
parsed.get(base)
}
}
You can use \ method returning a property corresponding a field name
val result: JsLookupResult = parsed \ "base"
If you want the result as string you can use as[String] conversion
println(result.as[String])
It will print "station", but it can throw an exception if it isn't really String
In case if value is missing you can use pattern matching:
result match {
case JsDefined(v) => println(v.toString) // will print "stations"
case undefined: JsUndefined => println(undefined.validationError) // prints error in case missing value
}

Parsing in groovy between two tags?

I would like to parse this Gstring with groovy :
Format type : Key, Value.
def txt = """ <Lane_Attributes>
ID,1
FovCount,600
FovCounted,598
...
</Lane_Attributes> """
And get a map like :
Map = [ID:1, FovCount:600, FovCounted:598]
How can I :
- extract text between tag and ?,
- and convert to a map ?
Try this:
def map = [:]
txt.replaceAll('<.+>', '').trim().eachLine { line ->
def parts = line.split(',')
map[parts[0].trim()] = parts[1].trim().toInteger()
}
def txt = """ <Lane_Attributes>
ID,1
FovCount,600
FovCounted,598
</Lane_Attributes> """
def map = new HashMap()
def lane = new XmlParser().parseText(txt)
def content = lane.text()
content.eachLine {
line ->
def dual = line.split(',')
def key = dual[0].trim()
def val = dual[1].trim()
//println "key: ${key} value: ${val}"
map.put(key,val)
}
println "map contains " + map.inspect()
//Will print: map contains ["FovCounted":"598", "ID":"1", "FovCount":"600"]
your problem is the fact that the contents between the tags will need to keep the same format throughout or this code will break
Some nice groovy regexp examples:
http://gr8fanboy.wordpress.com/2010/05/06/groovy-regex-text-manipulation-example/
http://pleac.sourceforge.net/pleac_groovy/patternmatching.html

Categories

Resources