직렬화를 위해 Jersey의 JSON/JAXB를 재사용하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1071749

  •  21-08-2019
  •  | 
  •  

문제

저지를 사용하여 구현 된 JAX-RS REST 서비스가 있습니다. Jax -Rs/Jersey의 멋진 특징 중 하나는 Pojo가 JaxB 주석을 사용하여 Pojos를 JSON으로 변환하는 사소한 쉬운 메커니즘을 포함하여 몇 가지 Java 주석을 뿌려 휴식 서비스로 쉽게 바꿀 수 있다는 것입니다.

이제는이 멋진 JSON- 이용 기능을 비 레스트 목적으로 활용할 수 있기를 원합니다. JSON 텍스트와 같이 이러한 객체 중 일부를 디스크로 직렬화 할 수 있기를 바랍니다. 다음은 직렬화하고 싶은 예제 jaxb 객체입니다.

@XmlRootElement(name = "user")
public class UserInfoImpl implements UserInfo {

    public UserInfoImpl() {} 

    public UserInfoImpl(String user, String details) {
        this.user = user;
        this.details = details;
    }

    public String getUser() { return user; }
    public void setUser(String user) { this.user = user; }

    public String getDetails() { return details; }
    public void setDetails(String details) { this.details = details; }

    private String user;
    private String details;
}

저지는 추가 정보없이 이들 중 하나를 JSON으로 바꿀 수 있습니다. 저지가 API 에서이 기능을 내 필요에 대해 노출했는지 궁금합니다. 지금까지 그것을 찾는 운이 없었습니다 ...

감사!

2009-07-09 업데이트: 나는 제공자 객체를 거의 내가 원하는 것을 정확히하십시오 :

  @Context Providers ps;
  MessageBodyWriter uw = ps.getMessageBodyWriter(UserInfoImpl.class, UserInfoImpl.class, new Annotation[0], MediaType.APPLICATION_JSON_TYPE);

  uw.writeTo(....)

... 이것은 객체를 모든 출력 스트림에 JSON으로 씁니다. 이는 나에게 완벽 할 것이지만 @Component 객체에서 @Context를 사용하여 제공자 객체 만 얻을 수 있습니다. 정기적으로 주석이없는 Pojo에서 액세스하는 방법을 아는 사람이 있습니까? 감사!

도움이 되었습니까?

해결책

Jersey는 Mapped (), Badgerfish () 또는 Natural () 표기법을 사용하는지 여부에 따라 몇 가지 다른 프레임 워크를 사용합니다. 자연은 일반적으로 사람들이 원하는 사람입니다. 그리고 그것은 객체-> jaxb-> json에서 나오는 매우 우수한 (그리고 매우 빠른) 독립형 Jackson Json 프로세서를 사용하여 구현되었습니다. 그러나 Jackson은 또한 자체 JAX-RS 제공 업체를 제공하여 직접 개체-> JSON을 제공합니다.

실제로 그들은 심지어 JAXB 주석에 대한 지원을 추가했습니다. 살펴보십시오

http://wiki.fasterxml.com/jacksonjaxbannotations

나는 그것이 궁극적으로 당신이 찾고있는 것이라고 생각합니다. Jackson은 Object <-> JSON 처리 ... Jersey는 당신을 위해 전화를합니다.

다른 팁

JaxB를 사용하여 객체를 JSON (Jackson 사용)에 매핑하는 간단한 간단한 예는 다음과 같습니다.

http://ondra.zizka.cz/stranky/programovani/java/jaxb-json-jackson-howto.texy

ObjectMapper mapper = new ObjectMapper();
String str = mapper.writeValueAsString(pojoObject);

JAXB 주석은 XML로 직렬화 할 때 정상적으로 작동합니다. 주요 문제는 JAXB가 빈 배열을 지원하지 않는다는 것입니다. 그래서 이와 같은 것을 직렬화 할 때 ...

List myArray = new ArrayList();

... JaxB anottations를 통해 JSON에게 모든 빈 배열은 [] 대신 무효가됩니다.

이를 해결하려면 Pojos를 Jackson을 통해 JSON으로 직접 직렬화 할 수 있습니다.

Jersey의 사용자 안내서에서 이것을 살펴보십시오.http://jersey.java.net/nonav/documentation/latest/user-guide.html#d0e1959

이것은 JAXB없이 Jackson 제공 업체를 사용하는 가장 좋은 방법입니다. 또한 웹에서 Jackson-All-Xyz-Jar를 다운로드하여 항상 최신 버전의 Jackson을 사용할 수 있습니다.

이 방법은 JAXB 주석을 방해하지 않으므로 시도해 볼 것을 제안합니다!

Jersey는 JAX-RS의 참조 구현이며 JAX-RS는 REST 서비스의 엔드 포인트를 구현하는 표준 방법을 제공하는 데 전적으로 중점을두고 있습니다.

JAX-RS 표준에 객체 직렬화를 포함하면 빠르게 중점을두고 풀기 어려운 큰 다중 머리 짐승이 될 것이라고 생각합니다.

깨끗하고 간단한 휴식 엔드 포인트를 전달하는 데 집중된 저지가 얼마나 감사하는지 감사합니다. 제 경우에는 모든 JAXB 배관이있는 부모를 서브 클래스하여 바이너리와 XML 사이의 마샬링 객체가 매우 깨끗합니다.

작은 저지 특정 부트 스트랩을 사용하면 필요한 JSON 객체를 만들 수 있습니다. 다음 종속성을 포함해야합니다 (번들을 사용할 수 있지만 테스트를 위해 용접을 사용하는 경우 문제가 발생합니다) :

    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.12</version>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-client</artifactId>
        <version>1.12</version>
    </dependency>

거기에서 JaxB 주석이 달린 클래스를 만들 수 있습니다. 다음은 예입니다.

@XmlRootElement
public class TextMessage {
private String text;
    public String getText() { return text; }
    public void setText(String s) { this.text = text; }
}

그런 다음 다음 단위 테스트를 만들 수 있습니다.

    TextMessage textMessage = new TextMessage();
    textMessage.setText("hello");
    textMessage.setUuid(UUID.randomUUID());

    // Jersey specific start
    final Providers ps = new Client().getProviders();
    // Jersey specific end
    final MultivaluedMap<String, Object> responseHeaders = new MultivaluedMap<String, Object>() {

        @Override
        public void add(final String key, final Object value) {
        }

        @Override
        public void clear() {
        }

        @Override
        public boolean containsKey(final Object key) {
            return false;
        }

        @Override
        public boolean containsValue(final Object value) {
            return false;
        }

        @Override
        public Set<java.util.Map.Entry<String, List<Object>>> entrySet() {
            return null;
        }

        @Override
        public List<Object> get(final Object key) {
            return null;
        }

        @Override
        public Object getFirst(final String key) {
            return null;
        }

        @Override
        public boolean isEmpty() {
            return false;
        }

        @Override
        public Set<String> keySet() {
            return null;
        }

        @Override
        public List<Object> put(final String key, final List<Object> value) {
            return null;
        }

        @Override
        public void putAll(
                final Map<? extends String, ? extends List<Object>> m) {
        }

        @Override
        public void putSingle(final String key, final Object value) {
        }

        @Override
        public List<Object> remove(final Object key) {
            return null;
        }

        @Override
        public int size() {
            return 0;
        }

        @Override
        public Collection<List<Object>> values() {
            return null;
        }
    };

    final MessageBodyWriter<TextMessage> messageBodyWriter = ps
            .getMessageBodyWriter(TextMessage.class, TextMessage.class,
                    new Annotation[0], MediaType.APPLICATION_JSON_TYPE);
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Assert.assertNotNull(messageBodyWriter);

    messageBodyWriter.writeTo(textMessage, TextMessage.class,
            TextMessage.class, new Annotation[0],
            MediaType.APPLICATION_JSON_TYPE, responseHeaders, baos);
    final String jsonString = new String(baos.toByteArray());
    Assert.assertTrue(jsonString.contains("\"text\":\"hello\""));

이 접근법의 장점은 JEE6 API 내의 모든 것을 유지하는 것입니다. 테스트 및 제공자를 얻는 것 외에는 외부 라이브러리가 명시 적으로 필요하지 않습니다. 그러나 표준에 제공되지 않으므로 실제로 사용하지 않기 때문에 MultivaluedMap의 구현을 만들어야합니다. 그것 5월 또한 GSON보다 느리고 필요보다 훨씬 더 복잡합니다.

XML 뷰를 이해하지만 표준 장비로 Pojos에 대한 JSON 지원을 요구하는 것이 일부 예측을 보여 주었을 것입니다. 구현이 JSON이고 클라이언트가 JavaScript RIA 인 경우 특수 캐릭터를 가진 JSON 식별자를 닥터 해야하는 것은 의미가 없습니다.

또한 자바 콩이 Pojos가 아닙니다. 웹 계층의 외부 표면에서 이와 같은 것을 사용하고 싶습니다.

public class Model
{
   @Property height;
   @Property weight;
   @Property age;
}

기본 생성자, getter/setter 노이즈, 내 자신의 주석이있는 포조.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top