1

I have been trying to decrypt json data and then convert it to Scala case class using GSON.

Code:

import com.google.gson.Gson

object DecryptQRData extends App {

  val key = "klix8TW3SMGtHLVO0ZbhwO8ggW0p+npHfB71epkvmE0="
  val data = "c3NbCs3KQ6uC9d1kplSOg78opMs5+jKB/n5O3D4ttLQaNfWeU/s3RxYqDMazA09gOhhUWkRHZo3xrsgv/x2zoQ=="
  val bytesArray: Array[Byte] = AES.decodeBase64(data)
  val finalData: Array[Byte] = AES.decrypt(bytesArray, key)

  val jsonString: String = new String(finalData)
  println(s"result: $jsonString")
  //result: "{\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}"

  val gson: Gson = new Gson()
  val extractedJson: User = gson.fromJson(jsonString, classOf[User])
  println(s"user is: ${extractedJson}")
}

case class User(username: String, address: String)

Above code fails with below exception:

result: "{\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}"
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
    at com.google.gson.Gson.fromJson(Gson.java:927)
    at com.google.gson.Gson.fromJson(Gson.java:892)
    at com.google.gson.Gson.fromJson(Gson.java:841)
    at com.google.gson.Gson.fromJson(Gson.java:813)
    at DecryptQRData$.delayedEndpoint$DecryptQRData$1(DecryptQRData.scala:15)
    at DecryptQRData$delayedInit$body.apply(DecryptQRData.scala:3)
    at scala.Function0.apply$mcV$sp(Function0.scala:39)
    at scala.Function0.apply$mcV$sp$(Function0.scala:39)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
    at scala.App.$anonfun$main$1$adapted(App.scala:80)
    at scala.collection.immutable.List.foreach(List.scala:392)
    at scala.App.main(App.scala:80)
    at scala.App.main$(App.scala:78)
    at DecryptQRData$.main(DecryptQRData.scala:3)
    at DecryptQRData.main(DecryptQRData.scala)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 2 path $
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
    ... 15 more

Process finished with exit code 1

But when i replace

val jsonString: String = new String(finalData)
//jsonString contains "{\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}"

with
val jsonString: String = "{\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}", my program works and it prints User.

Question: Why replacing jsonString with actual data works when both contains same data.

Edit 1: I tried below code (removed quotes at beginning and end)

val jsonString: String = new String(finalData)
  println(s"jsonString: $jsonString")
  val removedQuotes = jsonString.replaceAll("^\"|\"$", "")
  println(s"removedQuotes: ${removedQuotes}")
  val gson: Gson = new Gson()
  val extractedJson: User = gson.fromJson(removedQuotes, classOf[User])
  println(s"user is: ${extractedJson}")

But, it too fails with below error:

jsonString: "{\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}"
removedQuotes: {\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}
Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 2 path $.
mukesh210
  • 2,522
  • 1
  • 13
  • 36

1 Answers1

2

This is because your JSON payload looks like:

"{"username": "abc@gmail.com","address": "!Earth"}

Notice " at the beginning. When you remove first " it will start working. Notice what below lines:

System.out.println("\"{}\"");
System.out.println("{}");

print:

"{}"
{}

EDIT

System.out.println("Start point: " + json);
json = json.substring(1, json.length() - 1);
System.out.println("Get without \": " + json);
json = json.replaceAll("\\\\\"", "\"");
System.out.println("Valid: " + json);

Gson gson = new Gson();
User user = gson.fromJson(json, User.class);

System.out.println(user);

Above code prints:

Start point: "{\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}"
Get without ": {\"username\": \"abc@gmail.com\",\"address\": \"!Earth\"}
Valid: {"username": "abc@gmail.com","address": "!Earth"}
User{username='abc@gmail.com', address='!Earth'}

See also:

Michał Ziober
  • 31,576
  • 17
  • 81
  • 124
  • I tried removing beginning and end quotes, but doesn't work. I have added sample code in question. – mukesh210 Mar 06 '19 at 02:04
  • @Mukeshprajapati, please take a look on my edit. It is an example in `Java` how to convert invalid `payload` to valid `JSON`. You could improve it but it shows what it must done to make it work. – Michał Ziober Mar 06 '19 at 22:33