Может ли jaxb разрешить системные свойства?

Мы используем JAXB для настройки объекта с помощью XML. Мне было интересно, есть ли способ, которым JAXB может разрешить системное свойство. Например, если у меня есть bean-компонент со свойством color, я хотел бы иметь возможность сделать это:

<mybean color="${mycolor.in.data.property}" />

Но если я это сделаю, JAXB создаст объект mybean, цвет которого будет равен строке: mycolor.in.data.property

Есть ли эквивалент PropertyPlaceholderConfigurer весной для JAXB, чтобы можно было разрешить мое системное свойство?


person Melanie    schedule 22.01.2013    source источник


Ответы (1)


XmlAdapter – это JAXB (JSR-222). механизм, который позволяет вам преобразовывать объект в другой объект во время маршалинга/демаршаллера. Вы можете написать XmlAdapter, который преобразует имя системного свойства в реальное значение.

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

public class ColorAdapter extends XmlAdapter<String, String> {

    @Override
    public String unmarshal(String v) throws Exception {
        return System.getProperty(v);
    }

    @Override
    public String marshal(String v) throws Exception {
        return v;
    }

}

Затем вы используете аннотацию @XmlJavaTypeAdapter для настройки XmlAdapter для вашего ресурса.

@XmlJavaTypeAdapter(ColorAdapter.class)
public String getColor() {
    return color;
}

Для получения дополнительной информации


ОБНОВЛЕНИЕ

Хорошо спасибо. На самом деле у меня нет доступа к классу, так как он является частью импортированной библиотеки. Поэтому я больше искал способ настроить это непосредственно в файле xml, но это, вероятно, невозможно.

Если вы не можете изменить класс, вы можете использовать StreamReaderDelegate для изменения ввода XML. Существует несколько методов, которые работают с текстовыми/символьными данными, поэтому вам, возможно, придется поэкспериментировать, чтобы убедиться, что вы переопределяете тот, который лучше всего работает с используемой реализацией JAXB.

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {

        JAXBContext jc = JAXBContext.newInstance(MyBean.class);

        XMLInputFactory xif = XMLInputFactory.newFactory();
        StreamSource source = new StreamSource("input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(source);
        xsr = new StreamReaderDelegate(xsr) {

            @Override
            public String getText() {
                String text = super.getText();
                if(text.contains("${")) {
                    text = System.getProperty(text);
                }
                return text;
            }

        };

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.unmarshal(xsr);
    }

}
person bdoughan    schedule 22.01.2013
comment
Хорошо спасибо. На самом деле у меня нет доступа к классу, так как он является частью импортированной библиотеки. Поэтому я больше искал способ настроить это непосредственно в файле xml, но это, вероятно, невозможно. - person Melanie; 23.01.2013
comment
@Melanie - Если вы используете EclipseLink MOXy в качестве поставщика JAXB, вы можете представить метаданные в виде документа XML (см. blog.bdoughan.com/2010/12/). Или, в качестве альтернативы, я обновил свой ответ, указав, как вы можете использовать StAX StreamReaderDelegate для настройки ввода XML. - person bdoughan; 23.01.2013