programing

JAXB 객체 목록을 JSON으로 커스터마이즈하려면 어떻게 해야 합니까?

testmans 2023. 3. 16. 21:14
반응형

JAXB 객체 목록을 JSON으로 커스터마이즈하려면 어떻게 해야 합니까?

서버 컴포넌트에 대한 REST 웹 서비스를 만들기 위해 저지를 사용하고 있습니다.

목록에서 직렬화하는 JAXB 주석 개체는 다음과 같습니다.

@XmlRootElement(name = "distribution")
@XmlType(name = "tDistribution", propOrder = {
    "id", "name"
})
public class XMLDistribution {
    private String id;
    private String name;
    // no-args constructor, getters, setters, etc
}

다음과 같은 배포 하나를 검색하기 위한 REST 리소스가 있습니다.

@Path("/distribution/{id: [1-9][0-9]*}")
public class RESTDistribution {
    @GET
    @Produces("application/json")
    public XMLDistribution retrieve(@PathParam("id") String id) {
        return retrieveDistribution(Long.parseLong(id));
    }
    // business logic (retrieveDistribution(long))
}

또한 다음과 같은 모든 배포 목록을 가져올 REST 리소스도 있습니다.

@Path("/distributions")
public class RESTDistributions {
    @GET
    @Produces("application/json")
    public List<XMLDistribution> retrieveAll() {
        return retrieveDistributions();
    }
    // business logic (retrieveDistributions())
}

ContextResolver를 사용하여 JAXB 시리얼화를 커스터마이즈합니다.현재 다음과 같이 설정되어 있습니다.

@Provider
@Produces("application/json")
public class JAXBJSONContextResolver implements ContextResolver<JAXBContext> {
    private JAXBContext context;
    public JAXBJSONContextResolver() throws Exception {
        JSONConfiguration.MappedBuilder b = JSONConfiguration.mapped();
        b.nonStrings("id");
        b.rootUnwrapping(true);
        b.arrays("distribution");
        context = new JSONJAXBContext(b.build(), XMLDistribution.class);
    }
    @Override
    public JAXBContext getContext(Class<?> objectType) {
        return context;
    }
}

REST 리소스와 컨텍스트리졸바 모두 동작합니다.다음으로 첫 번째 출력 예를 나타냅니다.

// path: /distribution/1
{
  "id": 1,
  "name": "Example Distribution"
}

그게 바로 내가 원하는 거야.다음 예에서는 목록 출력을 보여 줍니다.

// path: /distributions
{
  "distribution": [{
    "id": 1,
    "name": "Sample Distribution 1"
  }, {
    "id": 2,
    "name": "Sample Distribution 2"
  }]
}

그건 내가 원하는게 아니야.

왜 동봉되어 있는지 이해할 수 없습니다.distribution거기 태그 붙이세요.제거하려고 했는데.rootUnwrapping(true)콘텍스트 리졸바에 포함되지만, 그 결과 다른 둘러싸인 태그가 삭제될 뿐입니다.이 출력은 다음과 같습니다..rootUnwrapping(false):

// path: /distribution/1
{
  "distribution": {
    "id": 1,
    "name": "Example Distribution"
  }
} // not ok
// path: /distributions
{
  "xMLDistributions": {
    "distribution": [{
      "id": 1,
      "name": "Sample Distribution 1"
    }, {
      "id": 2,
      "name": "Sample Distribution 2"
    }]
  }
}

또, 이 설정을 실시할 필요가 있었습니다..arrays("distribution")JSON 어레이를 항상 취득할 수 있습니다.단, 1개의 요소라도 마찬가지입니다.

이상적으로는 다음과 같이 출력하고 싶습니다.

// path: /distribution/1
{
  "id": 1,
  "name": "Example Distribution"
} // currently works
// path: /distributions
[{
  "id": 1,
  "name": "Sample Distribution 1"
}, {
  "id": 2,
  "name": "Sample Distribution 2"
}]

반품하려고 했습니다.List<XMLDistribution>,aXMLDistributionList(목록에 표시), aXMLDistribution[]그러나 필요한 포맷의 단순한 JSON 배열을 얻을 수 있는 방법을 찾을 수 없었습니다.

에서 반환된 다른 알림도 시도했습니다.JSONConfiguration.natural(),JSONConfiguration.mappedJettison()필요한 것을 얻을 수 없었습니다.

JAXB를 설정할 수 있는지 알고 있는 사람이 있습니까?

해결책을 찾았습니다. JAXB JSON 시리얼라이저를 잭슨과 같은 동작 좋은 JSON 시리얼라이저로 교체합니다.간단한 방법은 잭슨잭스를 사용하는 것입니다.잭스는 이미 사용 중입니다.클래스는 JacksonJsonProvider 입니다.Jersey(또는 다른 JAX-RS 구현)에서 검색할 수 있도록 프로젝트의 web.xml을 편집하기만 하면 됩니다.추가할 내용은 다음과 같습니다.

<init-param>
  <param-name>com.sun.jersey.config.property.packages</param-name>
  <param-value>your.project.packages;org.codehaus.jackson.jaxrs</param-value>
</init-param>

그리고 그게 다입니다.Jackson은 JSON 시리얼라이제이션에 사용되며 목록 및 어레이에서 예상하는 대로 작동합니다.

더 긴 방법은 "application/json"을 생성하기 위해 등록된 사용자 지정 MessageBodyWriter를 작성하는 것입니다.다음은 예를 제시하겠습니다.

@프로바이더@Productions("어플리케이션/json")퍼블릭 클래스 Json Message Body Writer가 Message Body Writer {를 구현합니다.@오버라이드public long getSize(개체 obj, 클래스 유형, 유형 generic Type,주석 [] 주석, Media Type media Type)반환 -1;}
@오버라이드public boolean isWriteable(클래스 타입, 타입 generic Type,주석[], MediaType mediaType)true를 반환한다.}
@오버라이드public void writeTo(개체 대상, 클래스 유형, 유형 genericType,주석 [] 주석, Media Type media Type,멀티값 맵httpHeaders, OutputStream outputStream)IOException {을(를) 슬로우합니다.새로운 ObjectMapper().writeValue(outputStream, target);
}}

위의 기성 솔루션과 같이 web.xml에 패키지가 포함되어 있는지 확인해야 합니다.

어느 쪽이든: 흥!JSON이 제대로 형성되어 있는 것을 알 수 있습니다.

Jackson은 http://jackson.codehaus.org/ 에서 다운로드 할 수 있습니다.

Jonhatan의 답변은 훌륭하고 나에게 많은 도움이 되었습니다.

업그레이드만 하면 됩니다.

버전 2.x 의 잭슨(버전 2.1 등)을 사용하는 경우 클래스는 com.fasterxml.jackson.jaxrs.json 입니다.따라서 web.xml은 다음과 같습니다.

<init-param>
  <param-name>com.sun.jersey.config.property.packages</param-name>
  <param-value>your.project.packages;com.fasterxml.jackson.jaxrs.json</param-value>
</init-param>

언급URL : https://stackoverflow.com/questions/2199453/how-can-i-customize-serialization-of-a-list-of-jaxb-objects-to-json

반응형