2013-05-17 2 views
2

Jackson이 직렬화 할 수 있도록 ByteBuffer에 있어야하는 데이터의 최소 크기에는 제한이 있습니까? 그렇게하는 동안 BufferUnderflowException이 발생합니다. 그러나 현재 데이터 크기가 클 때 잘 작동합니다.Jackson Json, ByteBuffer를 마샬링

public class MyTest { 
    private static class Wrapper { 
     private ByteBuffer buffer; 
     public void setBuffer(ByteBuffer buffer) { 
      this.buffer = buffer; 
     } 
     public ByteBuffer getBuffer() { 
      return buffer; 
     } 
    } 

    @Test 
    public void fails() throws Exception { 
     // Fails 
     ByteBuffer smallBuffer = ByteBuffer.wrap("small".getBytes()); 
     Wrapper wrapper1 = new Wrapper(); 
     wrapper1.setBuffer(smallBuffer); 
     System.out.println(new ObjectMapper().writeValueAsBytes(wrapper1)); 
    } 

    @Test 
    public void works() throws Exception { 
     // Works 
     ByteBuffer smallBuffer = ByteBuffer.wrap("larger string works, wonder why".getBytes()); 
     Wrapper wrapper1 = new Wrapper(); 
     wrapper1.setBuffer(smallBuffer); 
     System.out.println(new ObjectMapper().writeValueAsBytes(wrapper1)); 
    } 

} 

예외 스택 추적 : 내부 상태 및/또는 비 표준 게터/세터 메소드의 많은 복잡한 객체를 직렬화 할 때

org.codehaus.jackson.map.JsonMappingException: (was java.nio.BufferUnderflowException) (through reference chain: com.test.Wrapper["buffer"]->java.nio.HeapByteBuffer["int"]) 
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218) 
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183) 
    at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158) 

답변

5

잭슨은 일반적으로 문제가 실행됩니다. 일반적으로 직렬화 할 객체 계층 구조의 순수 POJO를 고수해야합니다.

이 경우, ByteBuffer가 포함 된 래퍼를 만들었습니다. 음, 잭슨은 실제로 전체 바이트 버퍼 오브젝트 (뿐만이 아니라 바이트 내용을) 직렬화하려고, 당신은 내부적으로 보면 그 사실 밖으로 쓰기를 시도하는 모든 '속성'

[ 
    property 'short' (via method java.nio.HeapByteBuffer#getShort), 
    property 'char' (via method java.nio.HeapByteBuffer#getChar), 
    property 'int' (via method java.nio.HeapByteBuffer#getInt), 
    property 'long' (via method java.nio.HeapByteBuffer#getLong), 
    property 'float' (via method java.nio.HeapByteBuffer#getFloat), 
    property 'double' (via method java.nio.HeapByteBuffer#getDouble), 
    property 'direct' (via method java.nio.HeapByteBuffer#isDirect), 
    property 'readOnly' (via method java.nio.HeapByteBuffer#isReadOnly) 
] 

그것의 단지 두 번째 경우는 작동합니다. (버퍼가 언더 플로우없이 위의 모든 메서드를 호출 할 수있을만큼 길기 때문에). 당신이 다음 바이트로 버퍼를 직렬화하려면 다음 중 하나를

  • 변화 byte[]
  • 에 래퍼 속성은 ByteBuffer로 속성을 유지하지만, @JsonIgnore 수로 표시하고 주위 변환하는 것이 다른 접근 방법을 제공

    class Wrapper { 
        final byte[] buffer; 
    
        public Wrapper(final ByteBuffer buffer) { 
         super(); 
         this.buffer = buffer != null ? buffer.array() : new byte[0]; 
        } 
    } 
    
    : 제의 byte[]