Scala: Json representation of an ArrayBuffer/Array

2019-09-05 04:17发布

问题:

I have an ArrayBuffer in my Scala class (somewhat like a ArrayList if using Java). The following is my code:

class MyClass {

  val names: ArrayBuffer[Name] = new ArrayBuffer[Name]
  var phone: String = null;

  def toJsonString(): String = {
    return (new GsonBuilder().serializeNulls().create()).toJson(this);
  }

  override def toString(): String = {
    return toJsonString();
  }
}

Then when I try to print my MyClass object:

  var myObj = new MyClass

  val name = new Name()
  name.setFirstName("John")
  name.setLastName("Smith")

  myObj.names.append(name)

  println(myObj.toString())

Then my output looks like:

{"names":{"initialSize":16,"array":[{"firstName":"John","middleName":null,"lastName":"Smith"},null,null,null,null,null,n
ull,null,null,null,null,null,null,null,null,null],"size0":1},"phone":null}

Is there a way I can make the output JSON like below? Perhaps using a different collection other than ArrayBuffer? Thanks!

{"names":[{"firstName":"John","middleName":null,"lastName":"Smith"}],"phone":null}

回答1:

You have many good options (e.g. use another serialization library instead of Gson, use an immutable collection etc.), but here's a solution with minimal code changes:

Add a custom serializer for ArrayBuffer that converts it to an immutable Array, thus getting rid of the empty cells:

import com.google.gson._
import scala.reflect.ClassTag
import java.lang.reflect.Type

class ArrayBufferSerializer[T : ClassTag] extends JsonSerializer[ArrayBuffer[T]] {
    override def serialize(src: ArrayBuffer[T], typeOfSrc: Type, context: JsonSerializationContext): JsonElement = {
        context.serialize(src.toArray)
    }
}

Then register it in the GsonBuilder in MyClass.toJsonString:

def toJsonString(): String = {
  new GsonBuilder()
    .registerTypeAdapter(classOf[ArrayBuffer[Name]], new ArrayBufferSerializer[Name]())
    .serializeNulls()
    .create()
    .toJson(this)
}

This produces the result you're looking for:

{"names":[{"firstName":"John","middleName":null,"lastName":"Smith"}],"phone":null}


回答2:

try this code

package yourPackage

import play.api.Play.current
import play.api.libs.json._
import scala.language.postfixOps
import scala.collection.mutable.ArrayBuffer

case class MyUser(names:Array[MyUserData],phone:String)
case class MyUserData(firstName:String,middleName:String,lastName:String)

class test{
      implicit val dataMyUserData = new Writes[MyUserData] {
    def writes(q: MyUserData): JsValue = {
      Json.obj(
        "firstName" -> q.firstName,
        "middleName" -> q.middleName,
        "lastName"->q.lastName
      )
    }
  }
     implicit val datamyUser = new Writes[MyUser] {
    def writes(q: MyUser): JsValue = {
      Json.obj(
        "names" -> q.names,
        "phone" -> q.phone
      )
    }
  }

    //Call this class it will return json string as you want
    def converttoJson(users:Array[MyUser])={
        println(Json.toJson(users).toString)
    }
}

call converttoJson method

if you want to know how to add data to this object here it is.

 var ar = ArrayBuffer[MyUserData]()
     ar+=MyUserData("John","tt","fb")

 var arr = ArrayBuffer[MyUser]()
     arr+=MyUser(ar.toArray,"12345")

  test.converttoJson(arr)


标签: java json scala