Anonymous
Как правильно использовать XmlAdapter?
Сообщение
Anonymous » 04 мар 2026, 06:15
Недавно мне нужно было преобразовать объекты Java в формат файлов XML, но прямое использование JAXB для преобразования объектов Java не соответствует моим потребностям. В ходе исследований я обнаружил, что XmlAdapter можно использовать для настройки XML, но я не знаю, как правильно использовать XmlAdapter для достижения моих требований. Эффект, который я ожидаю
Но эффект после такой работы
Я использую JDK 8, вот мой исходный код.
Вот мой целевой класс.
Код: Выделить всё
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "root")
public class MiddleRoot {
private Head head;
private Body body;
public MiddleRoot() {
}
public MiddleRoot(Head head, Body body) {
this.head = head;
this.body = body;
}
public Head getHead() {
return head;
}
public void setHead(Head head) {
this.head = head;
}
public Body getBody() {
return body;
}
public void setBody(Body body) {
this.body = body;
}
static class Head{
private String a;
private String b;
private String c;
public Head() {
}
public Head(String a, String b, String c) {
this.a = a;
this.b = b;
this.c = c;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
static class Body{
private String d;
private String e;
public Body() {
}
public Body(String d, String e) {
this.d = d;
this.e = e;
}
public String getD() {
return d;
}
public void setD(String d) {
this.d = d;
}
public String getE() {
return e;
}
public void setE(String e) {
this.e = e;
}
}
}
Вот мой исходный класс.
Код: Выделить всё
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement(name = "root")
@XmlJavaTypeAdapter(RootAdapter.class)
public class Root {
private String a;
private String b;
private String c;
private String d;
private String e;
public Root() {
}
public Root(String a, String b, String c, String d, String e) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
public String getD() {
return d;
}
public void setD(String d) {
this.d = d;
}
public String getE() {
return e;
}
public void setE(String e) {
this.e = e;
}
}
Вот мой класс адаптера
Код: Выделить всё
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class RootAdapter extends XmlAdapter {
@Override
public Root unmarshal(MiddleRoot v) throws Exception {
MiddleRoot.Head head = v.getHead();
MiddleRoot.Body body = v.getBody();
Root r = new Root();
if(head!=null){
r.setA(head.getA());
r.setB(head.getB());
r.setC(head.getC());
}
if(body!=null){
r.setD(body.getD());
r.setE(body.getE());
}
return r;
}
@Override
public MiddleRoot marshal(Root v) throws Exception {
MiddleRoot.Head head = new MiddleRoot.Head(v.getA(), v.getB(), v.getC());
MiddleRoot.Body body = new MiddleRoot.Body(v.getD(), v.getE());
return new MiddleRoot(head,body);
}
}
Вот мой тестовый класс
Код: Выделить всё
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Test {
public static void main(String[] args) {
try {
JAXBContext context = JAXBContext.newInstance(Root.class);
Root r = new Root("a","b","c","d","e");
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(r,System.out);
} catch (JAXBException e) {
System.out.println(e.getMessage());
}
}
}
Все эти четыре класса находятся в одном пакете. Если я удалю XmlRootElement в корневом классе, он вернет
null при запуске.
Подробнее здесь:
https://stackoverflow.com/questions/799 ... -correctly
1772594121
Anonymous
[b]Недавно мне нужно было преобразовать объекты Java в формат файлов XML, но прямое использование JAXB для преобразования объектов Java не соответствует моим потребностям. В ходе исследований я обнаружил, что XmlAdapter можно использовать для настройки XML, но я не знаю, как правильно использовать XmlAdapter для достижения моих требований.[/b][b][b]Эффект, который я ожидаю[/b] [code] a b[/b][b] c d e [/code] [b]Но эффект после такой работы[/b] [code] a b[/b] c d e [/code] [b]Я использую JDK 8, вот мой исходный код.[/b] [b]Вот мой целевой класс.[/b] [code]import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "root") public class MiddleRoot { private Head head; private Body body; public MiddleRoot() { } public MiddleRoot(Head head, Body body) { this.head = head; this.body = body; } public Head getHead() { return head; } public void setHead(Head head) { this.head = head; } public Body getBody() { return body; } public void setBody(Body body) { this.body = body; } static class Head{ private String a; private String b; private String c; public Head() { } public Head(String a, String b, String c) { this.a = a; this.b = b; this.c = c; } public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } public String getC() { return c; } public void setC(String c) { this.c = c; } } static class Body{ private String d; private String e; public Body() { } public Body(String d, String e) { this.d = d; this.e = e; } public String getD() { return d; } public void setD(String d) { this.d = d; } public String getE() { return e; } public void setE(String e) { this.e = e; } } } [/code] [b]Вот мой исходный класс.[/b] [code]import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement(name = "root") @XmlJavaTypeAdapter(RootAdapter.class) public class Root { private String a; private String b; private String c; private String d; private String e; public Root() { } public Root(String a, String b, String c, String d, String e) { this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; } public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } public String getC() { return c; } public void setC(String c) { this.c = c; } public String getD() { return d; } public void setD(String d) { this.d = d; } public String getE() { return e; } public void setE(String e) { this.e = e; } } [/code] [b]Вот мой класс адаптера[/b] [code]import javax.xml.bind.annotation.adapters.XmlAdapter; public class RootAdapter extends XmlAdapter { @Override public Root unmarshal(MiddleRoot v) throws Exception { MiddleRoot.Head head = v.getHead(); MiddleRoot.Body body = v.getBody(); Root r = new Root(); if(head!=null){ r.setA(head.getA()); r.setB(head.getB()); r.setC(head.getC()); } if(body!=null){ r.setD(body.getD()); r.setE(body.getE()); } return r; } @Override public MiddleRoot marshal(Root v) throws Exception { MiddleRoot.Head head = new MiddleRoot.Head(v.getA(), v.getB(), v.getC()); MiddleRoot.Body body = new MiddleRoot.Body(v.getD(), v.getE()); return new MiddleRoot(head,body); } } [/code] [b]Вот мой тестовый класс[/b] [code]import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; public class Test { public static void main(String[] args) { try { JAXBContext context = JAXBContext.newInstance(Root.class); Root r = new Root("a","b","c","d","e"); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(r,System.out); } catch (JAXBException e) { System.out.println(e.getMessage()); } } } [/code] Все эти четыре класса находятся в одном пакете. Если я удалю XmlRootElement в корневом классе, он вернет [b]null[/b] при запуске. Подробнее здесь: [url]https://stackoverflow.com/questions/79900574/how-to-use-xmladapter-correctly[/url]