2016-09-08 2 views
0

RESTEasy 클라이언트를 사용하여 API에서 JSON 문자열을 검색하고 있습니다.RESTEasy 클라이언트에서 JSON 응답의 특정 노드 추출

{ 
    "foo1" : "", 
    "foo2" : "", 
    "_bar" : { 
    "items" : [ 
     { "id" : 1 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 2 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 3 , "name" : "foo", "foo" : "bar" }, 
     { "id" : 4 , "name" : "foo", "foo" : "bar" } 
    ] 
    } 
} 

가 지금은 객체 매핑만을 items 노드를 추출하고 싶습니다 다음 JSON 페이로드는 다음과 같이 보인다. JSON 응답 본문을 가로 채고 루트 노드로 items이되도록 수정하는 가장 좋은 방법은 무엇입니까?

내 API 메소드에 RESTEasy proxy framework을 사용하고 있습니다.

나머지 클라이언트 코드 :

ResteasyWebTarget target = client.target("https://"+server); 
target.request(MediaType.APPLICATION_JSON); 
client.register(new ClientAuthHeaderRequestFilter(getAccessToken())); 
MyProxyAPI api = target.proxy(MyProxyAPI.class); 
MyDevice[] result = api.getMyDevice(); 

RESTEasy가 프록시 인터페이스 :

public class CustomReaderInterceptor implements ReaderInterceptor { 

    private ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public Object aroundReadFrom(ReaderInterceptorContext context) 
         throws IOException, WebApplicationException { 

     JsonNode tree = mapper.readTree(context.getInputStream()); 
     JsonNode items = tree.get("_bar").get("items"); 
     context.setInputStream(new ByteArrayInputStream(mapper.writeValueAsBytes(items))); 
     return context.proceed(); 
    } 
} 

이 그 다음을 등록 : 당신은 당신의 JSON을 조작 ​​할 수 ReaderInterceptor을 만들고 잭슨을 사용할 수

public interface MyProxyAPI { 

    @GET 
    @Produces(MediaType.APPLICATION_JSON) 
    @Path("/device") 
    public MyDevice[] getMyDevices(); 

    ... 
} 
+0

는 자바 스크립트 객체로 변환하고 객체로 검색 할 수 있습니다. – SaviNuclear

+0

'items'가 루트가되는 것이 중요합니까 아니면 메시지의 다른 요소를 매핑하고 싶지 않은 것입니까? RestEasy 문서를 잠시 살펴보면 JAXB 공급자를 통해 Java Bean에 자동 정렬/비 정렬을 사용하고있는 것입니까? – dbreaux

+0

@ dbreaux 네, 다른 요소를 매핑하고 싶지는 않습니다. 간단한 구현 코드는 OP 편집을 참조하십시오. 물론 메시지 본문을 변경하는 공급자를 등록 할 수는 있지만 그런 공급자의 구현이 어떻게 생겼는지 궁금합니다. –

답변

1

위의 은 Client에 있습니다.

Client client = ClientBuilder.newClient(); 
client.register(CustomReaderInterceptor.class); 
+1

사실, 다른 질문에 대한 답변 중 하나가 이것에 대한 간단한 해결책 일 수도 있습니다. http://stackoverflow.com/a/38352932/796761 – dbreaux

+0

@dbreaux 저를 상기시켜 주셔서 감사합니다. –

+1

dbreaux로 연결된 이전 솔루션 (JSON을 얻고 잭슨 트리를 통해 원하는 노드에 액세스하는 것)은 지금까지 해결 방법으로하고있었습니다. 이것은 물론 프록시 프레임 워크에서 작동하지 않습니다. 요격기를 시험해 보겠습니다. 감사. –

1

내가 원하는 것보다 더 많은 필드를 포함하는 메시지에 대해 복잡한 Java 클래스를 정의하지 않아도되는 동일한 욕구가있었습니다. 내 JEE 서버 (WebSphere)에서 Jackson은 기본 JSON 구현이며 RESTEasy의 옵션 인 것으로 보입니다. 잭슨은 알 수없는 JSON 필드를 무시할 수 @JsonIgnoreProperties 주석이 있습니다

import javax.xml.bind.annotation.XmlType; 
import org.codehaus.jackson.annotate.JsonIgnoreProperties; 

@XmlType 
@JsonIgnoreProperties(ignoreUnknown = true) 
public class JsonBase {} 

다른 JSON 구현은 유사한 기능이있는 경우 나도 몰라,하지만 확실히 자연의 사용 사례를 보인다.

는 (나는 또한 나의 WebSphere 환경에 관련이있는 blog post 및 다른 JAX-RS 기술을 썼다.)

+0

그것은 좋은 해결책이다, 그러나 OP에 의해 기술 된 상황을 위해 작동하지 않을지도 모르다. 'items' 노드는 루트 노드의 자식이 아닌'_bar'의 자식입니다. –

+0

거의 아무것도없는 래퍼 클래스를 정의하여이 작업을 수행 할 수 있습니다. 제 경우에는 대안보다 낫습니다. – dbreaux

+0

의미가 있습니다. Upvoted. –