2010-02-16 2 views
4

아래 코드를 사용하여 아래 클래스를 직렬화하려고하면이 클래스의 모든 문자열이없는 xml 파일이 아래에 있습니다.Java XML Serializing, 파일에 누락 된 필드

클래스 (일부 정적 값은 변경되었지만 기본적으로 변경됨)는 생성 된 모든 get \ set을 생략했지만 모두 공개 액세스 한정자와 함께 있습니다.

public class NotificationConfiguration implements Serializable 
{ 
    public static final String PORT_KEY = "mail.smtp.port"; 
    public static final String DEFAULT_PORT_VALUE = "587"; 
    public static final String TTL_KEY = "mail.smtp.starttls.enable"; 
    public static final String DEFAULT_TTL_VALUE = "true"; 
    public static final String AUTH_KEY = "mail.smtp.auth"; 
    public static final String DEFAULT_AUTH_VALUE = "true"; 
    public static final String MAIL_SERVER_KEY = "mail.smtp.host"; 
    public static final String DEFAULT_MAIL_CLIENT_HOST = "smtp.gmail.com"; 
    public static final String DEFAULT_MAIL_CLIENT_USERNAME = "*********"; 
    public static final String DEFAULT_MAIL_CLIENT_PASSWORD = "*********"; 
    public static final String DEFAULT_MAIL_CLIENT_ADDRESS = "*********"; 
    public static final String DEFAULT_ADMIN_EMAIL = "*********"; 
    public static final long DEFAULT_MAIL_INTERVAL = 24*60*60*1000; //One time a day default 
    public static final String SAVED_FOLDER_NAME = "C:\\Library"; 
    public static final String SAVED_FILE_NAME = "C:\\Library\\NotificationCfg.xml"; 

    private String portValue = DEFAULT_PORT_VALUE; 
    private String ttlValue = DEFAULT_TTL_VALUE; 
    private String authValue = DEFAULT_AUTH_VALUE; 
    private String mailClientHost = DEFAULT_MAIL_CLIENT_HOST; 
    private String mailClientUserName = DEFAULT_MAIL_CLIENT_USERNAME; 
    private String mailClientPassword = DEFAULT_MAIL_CLIENT_PASSWORD; 
    private String mailClientAddress = DEFAULT_MAIL_CLIENT_ADDRESS; 
    private String adminEMail = DEFAULT_ADMIN_EMAIL; 
    private boolean overdueSubsNotificationEnabled = false; 
    private boolean adminReportNotificationEnabled = false; 
    private long mailInterval = 
} 

코드를 직렬화하는 데 사용되며 누락 된 경우 폴더를 만듭니다.

public void storeChanges() 
{ 
    try 
    { 
     try 
     { 
      File f = new File(NotificationConfiguration.SAVED_FOLDER_NAME); 
      f.mkdir(); 
     } 
     catch (Exception e){} 
     XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream(NotificationConfiguration.SAVED_FILE_NAME))); 
     encoder.writeObject(notificationConfig); 
     encoder.close(); 
     System.out.println(LOG_CONFIGURATION_STORED); 
    } 
    catch (Exception ex) 
    { 
     System.out.println(LOG_CONFIGURATION_NOT_STORED + ex.getMessage()); 
    } 
} 

XML 파일을 받았으며 직렬화 중에 예외가 발생하지 않았습니다. 기본적으로 긴 값만 있습니다.

답변

4

XMLEncoder를이 개체를 복원하는 방법에 대한 정보를 인코딩을 다시 보았다. 필드 값이 기본값에서 변경되지 않으면 XMLEncoder는 아무 것도 저장하지 않습니다.

혼란을 줄 수 있습니다.

XMLEncoder를 사용할 때 제 경험상의 규칙은 다음과 같습니다.
1. 필드를 초기화하지 마십시오. do not do private String foo = DEFAULT_FOO;
2. 기본 생성자에서 아무것도하지 마십시오.
3. 다른 방법이나 필요한 경우 "기본"설정을 제공하는 팩토리가 있어야합니다.

+0

팩토리 메서드에서 개체를 초기화하고 클래스에서 모든 기본값을 제거한 후에받은 xml에는 모든 필드가 포함되어있었습니다. 답장을 보내 주셔서 감사합니다. – DorD

+0

문제 없습니다. 신속하게 답변 해 주신 것에 대해 감사드립니다. – z5h

0

mailInterval에만 getter가있을 수 있습니까?

다만 문제는 분명히 모든 필드에 게터가 그래서 ...

+0

Xavier Combelle, 응답을 주셔서 감사합니다. 클래스 코드에 대해 지적 했으므로 게시물의 get \ set을 생략했지만 모든 필드에는 netbeans 도구로 생성 된 public get \ set이 있습니다. – DorD

0

SAVED_FOLDER_NAME은 무엇인가요? 그것은 팩토리 객체와 같습니까? 그리고 그 객체에서 setMailInterval을 호출했을까요?

+0

답장을 보내 주셔서 감사합니다. SAVED_FOLDER_NAME은 (는) XML이 저장 될 디렉토리를 가리키는 문자열입니다. – DorD

+0

죄송합니다. 나는 "notificationConfig"객체를 의미했습니다. 객체에서 setMailInterval을 호출 했습니까? –

1

XMLEncoder Javadoc 우리 모두 알고있는 바이너리 직렬화의 주된 차이점을 지적하겠다.

  1. 는 그것은 단지 데이터를 직렬화 JVM을
  2. 사용할 수있는 클래스 정의를 필요로하는 인스턴스를 복원합니다. 기본 데이터에서 수정되었습니다.
  3. 위의 2 가지 결과로 정적 최종 값을 직렬화 할 이유가 없다는 것입니다. 이는 클래스 정의의 일부입니다.

반면에 이진 직렬화는 클래스 정의를 직렬화하지 않으며 이전에 JVM에서 사용할 수 없었던 클래스를 바이트 스트림에서로드 할 수 있습니다.

그래서 결과가 표시됩니다. 좋아, 이것은 의도적으로 설계된 동작이며 올바른 사용법입니다. 당신이 필요로하는 것만은 아닌 것 같습니다. 그건 그렇고 Xstream가 제공하는 것을보아야합니다.