2009-09-23 12 views
5

Pracuję nad projektem z JAXB, ale napotkam mały problem z JAXB i char typem danych.Java: JAXB i używanie char

char gender = 'M'; 

Tłumaczy po etapowy na:

<gender>77</gender> 

Więc myślę, że char jest odwzorowany do liczby całkowitej, ale ja po prostu chcesz mapować go na ciąg. Jak mogę to zrobić? Czy to możliwe?

+1

Nie przechowuj płci jako char i zamiast niej użyj "wyliczenia". Jest nie tylko bardziej bezpieczny w użyciu, ale można go również mapować, jak chcesz ;-) –

+0

@Joachim Sauer: Masz rację, mówiąc, że enum byłoby lepszym rozwiązaniem do przechowywania płci. Ale badam możliwości JAXB. I jestem uparty, więc pomyślałem, że musi istnieć rozwiązanie użycia char :-p – Korenaga

+0

To jest błąd w jednej konkretnej implementacji JAXB (Metro), inne implementacje JAXB (EclipseLink MOXy) marszałek poprawnie. –

Odpowiedz

5

Po kilku eksperymentach, nie wydaje się być w żaden sposób skonfigurować JAXB obsłużyć prymitywne znaki poprawnie. Jednak ciężko mi to zaakceptować.

Próbowałem zdefiniować XmlAdaptor, aby wypróbować i przymusić go do łańcucha, ale środowisko wykonawcze wydaje się akceptować tylko adaptery przypisane do typów obiektów, a nie do prymitywów.

Jedyne obejście można myślę o to, aby zaznaczyć pole char z @XmlTransient, a następnie napisać pobierające i ustawiające, które pobrać i ustawić wartość jako ciąg znaków:

@XmlTransient 
    char gender = 'M'; 

    @XmlElement(name="gender") 
    public void setGenderAsString(String gender) { 
     this.gender = gender.charAt(0); 
    } 

    public String getGenderAsString() { 
     return String.valueOf(gender); 
    } 

nie bardzo miły, będę przyznaję, ale bez zmiany twojego char pola na String, to wszystko, co mam.

+0

Ten problem dotyczy konkretnie implementacji Metro JAXB, inne implementacje JAXB (EclipseLink MOXy) obsługują ten przypadek poprawnie. –

1

Pierwszą rzeczą, mam w głowie :)

String gender = "M"; 
1

To nadal wydaje się być problemem w Metro JAXB (RI), co najmniej wersja Metro dostarczana z JDK 1.6.0_20.

EclipseLink JAXB (Moxy) marszałkowie char prawidłowo:

Aby korzystać EclipseLink JAXB prostu dodać eclipselink.jar na ścieżce klas i dodać jaxb.properties złożyć w swoim klasach modelowych z następującego wpisu:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 
0

utworzenia wyspecjalizowanej XmlAdapter:

package br.com.maritima.util; 

import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class CharAdapter extends XmlAdapter<String,Character>{ 

@Override 
public String marshal(Character v) throws Exception { 
    return new String(new char[]{v}); 
} 

@Override 
public Character unmarshal(String v) throws Exception { 
    if(v.length()>0) 
    return v.charAt(0); 
    else return ' '; 
} 

} 

następnie można zarejestrować go do całego pakietu z package-info.java (unikaj zapomnienia w innej klasie) lub użyj go specjalnie dla określonego pola.

Aby uzyskać więcej informacji, zobacz http://blogs.oracle.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and .

+1

Jestem ciekawy, dlaczego 'nowy ciąg (nowy char [] {v})' zamiast 'v.toString()'? –

2
@XmlJavaTypeAdapter(value=MyAdapter.class, type=int.class) 

Ów trick typ, aby pracować z prymitywów

W adaptera

stosując takie same w opakowaniu-info będzie oznaczać to zrobić globalnie dla tego pakietu

Found to po eksperymentach.

public class MyAdapter extends XmlAdapter<String, Integer> {