2016-04-01 12 views
1

Java 7 ile Java 8 arasındaki Jaxb işlemek arasında başka bir fark buldum. Sorunu basitleştirilmiş bir örneğe indirdim ve kod tek bir sınıf olarak çalıştırılmalıdır. Bir Listesi için ayarlayıcı unmarshaller tarafından çağrılan (dışı işle ilgili vb yüzden kategoriler değişti): Benim Soru gerçekten atlamak için Liste erişimcileri kodlama için tavsiye edilen uygulamaJAXB Java 7 arasındaki fark Java'ya karşı 8

  1. bir varyasyonu var mı JaxB'yi kodlarken Setter tamam mı? (Bu, Listesini Getter ile hallediyor gibi görünüyor)
  2. Önerilen alternatif yaklaşımlar var mı?

Java 7'de çalıştırıldığında, sette, listedeki verilerle çağrılır. Java 8'de çalıştırıldığında, ayarlayıcı, yalnızca, daha sonra unshashalling işleminde doldurulacak boş bir Liste nesnesiyle çağrılır. Deneyimdeki fark, ayarlayıcının Listede herhangi bir işlem yapmamasına, ancak yalnızca genel nesnenin birleştirilmesinden sonra çağrılan bir işleme sahip olmamam gerektiğidir. Veya özetlemek gerekirse, "setterde herhangi bir işlem yapmayın". Örnek aşağıda verilmiştir: (Üç sınıf) - Java 7 altında, döndürülen sonuç, listede bulunan ilk "albüm" başlığıdır. Java 8 altında bir null döndürülür. Kod, bağımlılık içermeyen tek bir sınıf olarak çalıştırılmalıdır. Java 7'de çalıştırılıyorsa, "İlk Albüm" başlığı görüntüleniyor "Abbey Road". Java 8 "First Album" içinde çalıştırırsanız başlık null

import java.io.ByteArrayInputStream; 
import java.io.InputStream; 
import java.util.List; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlType; 

public class MainJaxbCase { 
    public static void main(String[] args) { 
     new MainJaxbCase().testIt(); 
    } 
    private void testIt() { 
     try { 
     AlbumLib myLib = (AlbumLib) loadJaxbDocFromString(inXmlStr, AlbumLib.class); 
     System.out.println("category:"+ myLib.getCateg()); 
     List<AlbumItm> albumList = myLib.getAlbumList(); 
     System.out.println("AlbumList size is " + albumList.size()); 
     System.out.println("The first album is titled:" 
       + myLib.getFirstAlbumTitle() 
       + "- shows \"null\" if using Java 8, \"Abbey Road\" if using Java 7" 
      ); 
     } catch (Exception e) { 
      System.out.println(e.getClass().getSimpleName() + ", msg:" + e.getMessage()); 
      e.printStackTrace(); 
     } 
    } 
    private final String inXmlStr = 
      "<my_lib categ='albums'>" 
      + " <album title='Abbey Road'/> " 
      + " <album title='Revolver'/>" 
      + " <album title='Sgt.Pepper'/>" 
      + "</my_lib>";  


    private Object loadJaxbDocFromString (String inStr, Class<?> clazz) throws Exception { 
     Object result = null; 
     try { 
      InputStream is = new ByteArrayInputStream(inStr.getBytes()); 
      result = unmarshal(is, clazz ); 
     } catch (Exception e) { 
      String msg = this.getClass().getSimpleName() + ".loadJaxbDocFromResource() caught " + e.getClass().getSimpleName() + " msg:" + e.getMessage(); 
      throw new Exception(msg); 
     } 
     return result; 
    } 
    private Object unmarshal(InputStream prmIs, Class<?> clazz) throws Exception{ 
     Object obj = null; 
     try { 
      JAXBContext jaxbContext = JAXBContext.newInstance(clazz); 
      Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
      obj = jaxbUnmarshaller.unmarshal(prmIs); 
     } catch (Exception e) { 
      String msg = this.getClass().getSimpleName() + " caught " + 
        e.getClass().getSimpleName() + ", msg:" + e.getMessage(); 
      msg += " Trying to Unmarshall class " + clazz.getName(); 
      System.err.println(msg); 
      e.printStackTrace(); 
      throw new Exception(msg); 
     } 
     return obj; 
    } 
} 



@XmlRootElement (name= "my_lib") 
class AlbumLib { 
    private String  categ; 
    private List<AlbumItm> albumList; 
    private String firstAlbumTitle; 

    @XmlAttribute (name="categ") 
    public String getCateg() { 
     return this.categ; 
    } 
    public void setCateg(String val) { 
     this.categ=val; 
    } 

    @XmlElement (name="album") 
    public List<AlbumItm> getAlbumList() { 
     return this.albumList; 
    } 
    public void setAlbumList(List<AlbumItm> newList) { 
     if (newList != null && newList.size() > 0) { 
      firstAlbumTitle = newList.get(0).getTitle(); 
     } 
     this.albumList = newList; 
    } 
    public String getFirstAlbumTitle() { 
     return this.firstAlbumTitle; 
    } 
} 



@XmlType(name = "album") 
class AlbumItm { 
    private String title; 
    @XmlAttribute (name="title") 
    public String getTitle() { 
     return this.title; 
    } 
    public void setTitle(String val) { 
     this.title = val; 
    } 
} 

Bu soru biz Java 8 çevrildiği zamanki ince (ama önemli) farkları davrandığını başladı çünkü koda sahip çıktı, ancak herhangi bir belirgin istisnalar olmadan .

cevap

1

this blog post belirtildiği gibi sizinle aynı sorunu da karşıladık. JAXB kodlama yaparken tamamen Setter çıkarmanıza Liste erişimcileri kodlama için tavsiye edilen uygulama

  1. mi? (Listeyi Getter aracılığıyla ele aldığından beri)
  2. Önerilen alternatif yaklaşımlar var mı?

nokta 'Setter ihmal' değil ama setter daha fazla işlevsellik eklemek için değildir. Setter sadece ayarlayıcıdır, başka bir şey değildir. Daha fazla mantık eklemek, setter için 'tek sorumluluk kuralı'nı ihlal eder ve bu işlevin adı, aslında daha fazla hata ortaya çıkabileceğinden farklıdır.

Önerilen yollar söz konusu olduğunda, tüm vakaları kapsayan standart bir yanıt yoktur. Düşünüldüğünde orada (biraz sert JAXB yapmak için olan) hiçbir yapıcı init var ve biz setter sonra daha mantığa ihtiyacı, size alabilir iki yön vardır:

  • Kullanım XmlAdapter mantığı eklemek için inşaat özelleştirmek için: adapter examples ;
  • XML veri işlemek için başka bir sınıf oluşturarak, bu sınıftaki bir mantık ilave edilmedi -
(bu sınıf mantığı olmamalıdır ki sadece bazı DTO olduğu gibi, bu tercih edilir)