programing

중첩된 Grails 도메인 개체에 대한 JSON 바인딩

lastcode 2023. 4. 2. 10:36
반응형

중첩된 Grails 도메인 개체에 대한 JSON 바인딩

JavaScript 어플리케이션에 JSON 데이터를 제공하기 위해 사용되는 RESTful 인터페이스를 개발 중입니다.

서버 측에서는 Grails 1.3.7을 사용하고 지속성을 위해 GORM 도메인 개체를 사용합니다.중첩된 도메인 개체의 마샬링을 지원하기 위해 커스텀 JSON Marshaller를 구현했습니다.

다음은 도메인 개체의 예입니다.

class SampleDomain {
    static mapping = { nest2 cascade: 'all' }
    String someString
    SampleDomainNested nest2
}

그리고.

class SampleDomainNested {
    String someField
}

SampleDomain 리소스는 URL /rs/sample/로 게시되므로 ID가 1인 SampleDomain 개체를 가리킵니다.

커스텀 json 마샬러(GET on /rs/sample/1)를 사용하여 리소스를 렌더링하면 다음 데이터가 표시됩니다.

{
    "someString" : "somevalue1",
    "nest2" : {
        "someField" : "someothervalue"
    }
}

그게 바로 내가 원하는 거야

문제는 다음과 같습니다.동일한 데이터를 PUT을 통해 리소스 /rs/sample/1로 보내려고 합니다.

Object에 는 json을 합니다.def domain = SampleDomain.get(id) ★★★★★★★★★★★★★★★★★」domain.properties = data자료

"someString" 필드의 바인딩은 정상적으로 작동하지만 중첩된 개체는 중첩된 데이터를 사용하여 채워지지 않으므로 속성 "nest2"가 null이라는 오류가 나타납니다. 이는 허용되지 않습니다.

는 이미 관습을 .PropertyEditorSupport뿐만 아니라StructuredPropertyEditor편집자를 등록합니다.

이상하게도 네스트되지 않은 값을 제공할 때만 에디터가 호출됩니다.그래서 PUT을 통해 다음 내용을 서버로 보낼 때(이러한 내용은 전혀 의미가 없습니다.

{
    "someString" : "somevalue1",
    "nest2" : "test"
}

적어도 속성 에디터는 호출됩니다.

.GrailsDataBinder맵을 제공하는 것이 아니라 어소시에이션의 패스를 지정하는 것으로, 어소시에이션의 설정 속성이 기능하는 것을 알 수 있기 때문에, 이하도 기능합니다.

{
    "someString" : "somevalue1",
    "nest2.somefield" : "someothervalue"
}

JSON 오브젝트시리얼라이저에 커스텀 JavaScript를 구현하고 싶지 않기 때문에 도움이 되지 않습니다.

중첩된 맵을 사용하여 Grails 데이터 바인딩을 사용할 수 있습니까?아니면 각 도메인 클래스에 대해 직접 구현해야 합니까?

정말 감사해요.

마틴

이 질문이 여러 번 제기됐기 때문에 마지막으로 제가 한 일에 대해 말씀드리겠습니다.

보안 등 실시해야 할 요건이 몇 가지 더 있었기 때문입니다.컨트롤러에서 도메인 개체를 숨기는 서비스 계층을 구현했습니다.도메인 객체를 Groovy Maps로 변환하여 표준 시리얼라이저를 사용하여 쉽게 시리얼화할 수 있고 업데이트를 수동으로 구현하는 "Dynamic DTO 레이어"를 도입했습니다.구현하려고 했던 모든 반자동/메타 프로그래밍/명령어 패턴/... 기반 솔루션이 어느 시점에서 실패하여 대부분 이상한 GORM 오류 또는 많은 구성 코드(그리고 많은 불만)가 발생했습니다.DTO의 업데이트 및 시리얼화 방법은 매우 간단하며 매우 신속하게 구현할 수 있습니다.내부 도메인 개체 구조를 게시하지 않으려면 도메인 개체의 일련화 방법을 지정해야 하므로 중복 코드가 많이 발생하지 않습니다.가장 우아한 해결책은 아닐지 몰라도 나에게 정말 효과가 있는 유일한 해결책이었다.또한 업데이트 로직이 http 요구에 더 이상 연결되어 있지 않기 때문에 배치 업데이트를 구현할 수도 있습니다.

단, 그레이스 스택은 어플리케이션의 무게와 유연성이 매우 높아지기 때문에 이러한 어플리케이션에 가장 적합한 테크놀로지 스택이라고는 생각하지 않습니다.제 경험으로는 기본적으로는 프레임워크에서 지원되지 않는 일을 하기 시작하면 혼란스러워지기 시작합니다.또한 Graphy의 "Repository" 계층이 기본적으로 도메인 객체의 일부로만 존재하며, 이로 인해 많은 문제가 발생하여 저장소 계층을 에뮬레이트하는 여러 "proxy 서비스"가 발생한다는 사실은 마음에 들지 않습니다.json rest 인터페이스를 사용하여 어플리케이션을 구축하기 시작할 경우 node.js와 같은 매우 가벼운 테크놀로지를 사용하거나 Java 기반 스택을 고수하고 싶다면 표준 스프링 프레임워크 + 스프링 MVC + 스프링 데이터 (이것이 내가 이행한 것이며, 이것이 매력적으로 기능하는 것입니다)를 사용하는 것을 추천합니다.보일러 플레이트 코드를 많이 쓸 필요는 없고 실제로 무슨 일이 일어나고 있는지 완벽하게 제어할 수 있습니다.게다가 강력한 타이핑으로 개발자의 생산성과 유지보수성이 향상되어 추가 LOC가 정당화됩니다.그리고 물론 타이핑이 강하다는 것은 툴링이 강하다는 것을 의미합니다!

제가 생각한 아키텍처에 대한 블로그 엔트리를 작성하기 시작했는데(물론 샘플프로젝트로) 지금은 완성할 시간이 많지 않습니다.작업이 완료되면 여기에 링크하여 참조하도록 하겠습니다.

이것이 비슷한 문제를 겪고 있는 사람들에게 영감을 줄 수 있기를 바랍니다.

건배!

클래스 이름을 입력해야 합니다.

{ class:"SampleDomain", someString: "abc", 
nest2: { class: "SampleDomainNested", someField:"def" }
} 

네, 출력과 다른 입력이 필요합니다.

아까 코멘트에서도 언급했듯이 gson 라이브러리를 사용하는 것이 좋을지도 모릅니다.

xstream이 주변에 있는데 왜 직접 json mashaller를 썼는지 모르겠네요.

http://x-stream.github.io/json-tutorial.html 를 참조해 주세요.

xstream은 백엔드(그래프 기반) 서비스에 매우 만족하고 있습니다.이렇게 하면 xml 또는 json으로 마샬을 렌더링하거나 필요에 따라 특정 객체의 기본 마샬링을 덮어쓸 수 있습니다.

Jettison은 사람이 읽을 수 없는 보다 콤팩트한 JSON을 생성하는 것처럼 보이며 라이브러리 충돌에 직면할 수도 있지만 기본 내부 json 스트림 렌더러(renderer)는 적절합니다.

서비스를 일반에 게시할 경우 오류 등에 대한 적절한 HTTP 프로토콜 응답을 반환할 수 있습니다.($.02)

언급URL : https://stackoverflow.com/questions/7527331/binding-json-to-nested-grails-domain-objects

반응형