2017-10-19 10 views
1

json4s/jackson을 사용하여 HTTP 페이로드를 직렬화 및 비 직렬화하는 스칼라로 작성된 HTTP 클라이언트가 있습니다. 지금은 스칼라 케이스 클래스 만 모델로 사용하고 있었지만 모든 것이 잘 작동했지만 이제는 제 3 자 서비스와 통신해야합니다. 그들은 저에게 자신의 모델을 제공했지만 자바로 작성되었으므로 이제 Java 클래스에도 jsons를 deserialize해야합니다. 간단한 클래스로도 잘 작동하지만 클래스에는 Lists 나 Maps와 같은 콜렉션이 포함되어있을 때 json4s에는 문제가 있으며 모든 필드가 null으로 설정됩니다.스칼라와 json4s로 자바 객체에 직렬화하기

그런 경우를 처리 할 수있는 방법이 있습니까? 어쩌면 나는 다른 형식을 사용해야한다. (나는 DefaultFormats와 몇몇 커스텀 것들을 사용하고있다.) 테스트와 문제의 예 :

import org.json4s.DefaultFormats 
import org.json4s.jackson.Serialization.read 
import org.scalatest.{FlatSpec, Matchers} 

class JavaListTest extends FlatSpec with Matchers{ 

    implicit val formats = DefaultFormats 

    "Java List" should "be deserialized properly" in { 
     val input = """{"list":["a", "b", "c"]}""" 
     val output = read[ObjectWithList](input) 
     output.list.size() shouldBe 3 
    } 
} 

그리고 샘플 Java 클래스 : 나는 또한 내가거야 필드의 java.util.List[String] 유형이 포함 스칼라 케이스 클래스에 역 직렬화 할 것이다 때 것으로 나타났습니다

import java.util.List; 

public class ObjectWithList { 
    List<String> list; 
} 

유형의 예외를 얻으십시오 : org.json4s.package$MappingException: Expected collection but got List[String]

답변

1

형식 해결 자의 구성입니다. 기본적으로 JList 포맷터를 toJList 함수로 구성된 목록 포맷터로 정의하려고합니다. 불행히도 json4s 포매터는 구성하기가 극히 어렵습니다. 따라서 Reader을 사용하여 아이디어를 얻었습니다. 당신은 Serializer[JList[_]] 같은 방법, 또는 미러를 구현해야 하나 내 지식

import DefaultReaders._ 
import scala.collection.JavaConverters._ 

implicit def javaListReader[A: Reader]: Reader[java.util.List[A]] = new Reader[util.List[A]] { 
     override def read(value: JValue) = DefaultReaders.traversableReader[List, A].read(value).asJava 
} 

val input = """["a", "b", "c"]""" 
val output = Formats.read[java.util.List[String]](parse(input)) 

독자가 상자 밖으로 자바 클래스와 함께 작동하지 않습니다 json4s : 그래서, 나는 또한 단지 자바 목록을 데, 예를 단순화 자바 클래스를 케이스 클래스와 함께 사용하고 도메인 내에서 사용하십시오.

P. circe 또는 argonaut로 전환하는 것이 좋습니다. 그러면 jsons의 가장 큰 문제점을 잊어 버릴 수 있습니다.

+1

너무 오랫동안 컴파일 문제로 인해 json4s로 바꾼 circe를 사용해 보았지만 스칼라에서 내 수준의 전문 지식을 이해하기가 너무 어려웠습니다. 나는'io.circe.generic.auto._'의 디코더를 사용하고 있었지만 자바 디코더는 포함하지 않았습니다. circe에 자바 클래스 용 디코더가 있는지 알고 계신가요? 아니면 circe로 돌아 가기로 결정하면 내 자신의 사용자 정의 디코더를 구현해야합니까? –

+1

'generic.auto._'는 shapeless에서'HList'와'Coproduct' 로의 변환을 사용합니다. 이것은 java 클래스에서는 작동하지 않습니다. 내가 circe에서 자바 클래스에 대한 자신의 디코더를 구현해야 할 것입니다 걱정됩니다. –