2012-04-12 2 views
4

TreeMap을 사용하여 직렬화 가능 객체를 가졌습니다.GWT TreeMap의 Ordering/Comparator Serialize

Map<String, Dogs> dogsByNames = Maps.newTreeMap(); // guava style 

지금까지 모든 것이 정상입니다. 지금은 키의 경우 무시 nessassary입니다 :

Map<String, Dogs> dogsByNames = Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER); 

String.CASE_INSENSITIVE_ORDER이 serialzable하지 않기 때문에이 작동하지 않습니다

com.google.gwt.user.client.rpc합니다. SerializationException : Type 이 SerializationPolicy 또는 클래스 객체를 직렬화 할 수없는 유형 집합 유형에 'java.lang.String $ CaseInsensitiveComparator'유형이 포함되어 있지 않습니다. 보안을 위해이 유형 직렬화되지 않습니다 :

그래서 내가 만들 예 = [email protected] 내 자신의 하나

private static abstract class MyComparator<T> 
    implements 
     Comparator<T>, // extends Ordering<T> do not work 
     IsSerializable { // Serializable do not work 
} 

public static final MyComparator<String> CASE_INSENSITIVE_ORDER = new MyComparator<String>() { 
    @Override 
    public int compare(final String left, final String right) { 
     if (null == left) { 
      return (null == right) ? 0 : -1; 
     } else if (null == right) { 
      return 1; 
     } 
     return left.compareToIgnoreCase(right); 
    } 
}; 

하지만 여전히하지 작업.

뭐가 잘못 되었나요?

해결 방법 :

protected static class MyOrdering // no-private!!! 
    extends 
     Ordering<String> 
    implements 
     IsSerializable { 
    @Override 
    public int compare(final String left, final String right) { 
     if (null == left) { 
      return (null == right) ? 0 : -1; 
     } else if (null == right) { 
      return 1; 
     } 
     return left.compareToIgnoreCase(right); 
    } 
} 

public static final Ordering<String> CASE_INSENSITIVE_ORDER = new MyOrdering(); 
+1

docs'CASE_INSENSITIVE_ORDER' ** 에의 액세스는 ** serializable입니다. _A compareToIgnoreCase에 의해 String 객체를 정렬하는 Comparator. 이 비교기는 직렬화 가능합니다. _ 그러면 어떤 오류가 발생합니까? – Xaerxess

+0

실제로 사실이 아닙니다. (@see 편집) –

+0

@ eneveu의 답변이 도움이 될 것 같습니다. – Xaerxess

답변

5

만든 CASE_INSENSITIVE_ORDER는 GWT에서 직렬화 할 수없는 익명의 클래스입니다.이 GWT 직렬화하려면, 당신은 당신처럼 (같은

CaseInsensitiveOrder implements Comparator<..>, Serializable { 
    ... 
} 
  • 는 상수 CASE_INSENSITIVE_ORDER 만들기 사용자 정의 최상위 클래스를 작성

    1. 해야합니다.

    2. 사용자 정의 필드 시리얼 만들기 해당 클래스 (CaseInsensitiveOrder_CustomFieldSerializer)의 경우 deserialize()CASE_INSENSITIVE_ORDER 인스턴스를 반환합니다.
  • +0

    이것은 올바른 힌트였습니다. Comparator를 상자의 클래스로서 구현 한 후에 나는 그것을 비공개로 만들 필요가 있었다. 그래서 당신의 3은 정말로 필요하지 않습니다. –

    +0

    3은 비 직렬화 된 순서가 원본과 동일한 인스턴스인지 확인하는 데 필요합니다. MyOrdering을 여러 개 사용하여 살면 건너 뛸 수 있습니다. –

    0

    오류의 스택 트레이스 도움이 될 것입니다.하지만 난 당신 같은 예외가 얻을 수 있다는 추측의 위험을 무릅 있습니다 :

    이 com.google.gwt.user.client.rpc.SerializationException : 유형 'com.foo.Bar.MyComparator이'에 포함되지 않았습니다를 이 SerializationPolicy 또는 그 Class 오브젝트에 의해 직렬화 된 일 수있는 형태 세트는, 로드 할 수 없었다. 보안을 위해이 형식은 serialize되지 않습니다.

    이는 GWT가 컴파일 할 때 직렬화해야 할 모든 유형의 목록을 만들기 때문에 발생합니다. 이것은 "직렬화 정책"입니다. 이렇게하기 위해 GWT는 모든 RPC 메소드를 인수 및 반환 유형으로 검사하고 모든 "도달 가능한"유형을 검색합니다.

    컴파일러는 Comparator가 serialize되고 직렬화 정책에 추가되지 않는다는 것을 인식하지 못할 수 있습니다.

    임시 해결책은 this other SO answer에 설명 된대로 직렬화해야 할 수도있는 모든 유형을 매개 변수로 취하는 더미 메소드를 선언하는 것입니다. 같은 뭔가 :

    // in your RPC interface 
    SerializationWhitelist dummyMethodForSerializationPolicy(SerializationWhitelist serializationWhiteList); 
    
    // the SerializableWhiteList class 
    public class SerializationWhitelist { 
        public Bar.MyComparator<String> myComparator; 
    }