2016-07-05 17 views
3

Ich habe eine Klasse mit @XmlAccessorType(XmlAccessType.FIELD) Annotation, und jedes private und protected Feld ist mit annotiert.Override @ XmlElement Annotation mit FIELD-Accessor-Typ

Die Herausforderung: Ich möchte einen der XML-Elementnamen in einer späteren Phase umbenennen. Dies führt mich zu der Frage. Gibt es eine Möglichkeit, diese Anmerkungen zu überschreiben/neu zu definieren, wenn ich eine Unterklasse erstelle?

+0

Ist meine Antwort, was Sie gesucht haben oder waren Sie verzweifelt auf der Suche nach einer Möglichkeit, ein Äquivalent der "Funktion @ override" zu tun? – Dan

+0

ja, suchte nach dem @override Weg. Ich denke, das Nächstbeste ist, was Alexander vorgeschlagen hat. Wenn sie nicht überschrieben werden können, müssen sie in xml definiert und bei Bedarf die XML-Datei ersetzt werden. – bvdb

Antwort

1

ich glaube, dass einige Implementierungen von jaxb für XML-Konfiguration ermöglichen die Anmerkungen zu überschreiben. In diesem Fall ist dies möglicherweise möglich. Hier ist ein Artikel von Eclipslink, der erklärt, wie das gemacht werden kann http://www.eclipse.org/eclipselink/documentation/2.4/solutions/jpatoxml004.htm

Meiner Meinung nach können Sie nur eine XML-Konfiguration für die JaxB-Datei erstellen, die Sie überschreiben möchten.

1

Während in Java, ist ein Überschreiben einer Anmerkung zum Ändern der name Eigenschaft meines Wissens nicht möglich; Sie können eine globale Variable in Ihrem Code erstellen und diese entweder durch Ihre Klassen oder Ihre Funktionen nach dem weiterleiten.

Im folgenden Code mir eine einzige Klasse erstellt, aber es enthält die Setter und Getter-Methoden erforderlich, wenn Sie es durch in einer anderen Klasse

@XMLAccessorType(XMLAccessType.FIELD) 
public class YourClass { 

    @XmlTransient 
    private String string = ""; //This can be replaced with whatever variable you are manipulating 
           //That could be an int or a file or anything really 

    @XmlElement(name = "your_name") 
    private void doSomething() { 
     String temp = getString(); //This variable is normally used to pass between different 
            //classes but may as well use it if you have one 
     //Your code which manipulates the String 
     setString(temp); //This variable is normally used to pass between different classes but 
         //may as well use it if you have one 
    } 


    @XmlElement(name = "your_other_name") 
    private void doSomethingElse() { 
     String temp = getString(); 
     //Your code which manipulates the String 
     setString(temp); 
    } 

    public void getString() { 
     return string; 
    } 


    public void setString(String string) { 
     this.string = string; 
    } 

} 

Ich würde empfehlen, Blick auf den Java Docs für @XmlTransient und diese weitergeben wollen zwei weitere relevante SO-Fragen.

How to override JAXB @XMLAccessorType(XMLAccessType.FIELD) specified at a Class level with @XMLElement on a getter method for a property?

Jaxb - Overriding the XMLElement name attribute

1

Ich versuchte zunächst, mit dem @XmlAccessorType(XmlAccessType.FIELD) und mit @XmlTransient zu verstecken. Dies funktioniert nur, wenn Sie das Feld in der Oberklasse und in der Kindklasse mit @XmlTransient markieren. Aber ich nehme an, das ist nicht was du willst.

Als zweiten Ansatz habe ich mit restriktiver @XmlAccessorType(XmlAccessType.PROPERTY) in der Oberklasse und @XmlAccessorType(XmlAccessType.NONE) in der Kindklasse versucht. Sehen Sie hier mein Beispiel:

package com.so.example; 

import java.util.ArrayList; 
import java.util.List; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 

@Path("/myresource") 
public class MyResource { 

    @GET 
    @Path("/car") 
    @Produces(MediaType.APPLICATION_XML) 
    public Car getCar() { 
     Car car = new Car(); 
     car.setWheels(4); 
     return car; 
    } 

    @GET 
    @Path("/suv") 
    @Produces(MediaType.APPLICATION_XML) 
    public Suv getSuv() { 
     Suv suv = new Suv(); 
     List<String> bigWheels = new ArrayList<>(); 
     bigWheels.add("left front wheel"); 
     bigWheels.add("right front wheel"); 
     bigWheels.add("left rear wheel"); 
     bigWheels.add("right rear wheel"); 
     suv.setBigWheels(bigWheels); 
     return suv; 
    } 
} 

Klasse Auto:

package com.so.example; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlAccessorType(XmlAccessType.PROPERTY) 
@XmlRootElement 
public class Car { 

    protected Integer wheels; 

    public Car() { 
    } 

    @XmlElement(name = "wheels", nillable = true) 
    public Integer getWheels() { 
     return wheels; 
    } 

    public void setWheels(Integer wheels) { 
     this.wheels = wheels; 
    } 
} 

Klasse Suv (Kind):

package com.so.example; 

import java.util.List; 

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlTransient; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.NONE) 
public class Suv extends Car { 

    @XmlTransient 
    private Integer wheels; 

    private List<String> bigWheels; 

    public Suv() { 
    } 

    @Override 
    @XmlTransient 
    public Integer getWheels() { 
     return wheels; 
    } 

    @Override 
    public void setWheels(Integer wheels) { 
     this.wheels = wheels; 
    } 

    @XmlElement 
    public List<String> getBigWheels() { 
     return bigWheels; 
    } 

    public void setBigWheels(List<String> bigWheels) { 
     this.bigWheels = bigWheels; 
    } 
} 

Eine Möglichkeit, zu "verstecken" die Elementrad der übergeordneten Klasse wären Markieren Sie es als "nillable = true" und verwenden Sie keine primitiven Typen. In diesem Fall wird die Feldräder <wheels xsi:nil="true"/>

rangieren Wenn es Ihnen möglich, nicht die übergeordnete Klasse für das Versammeln zu verwenden, und Sie verwenden nur Kind-Klassen, könnten Sie die hier beschriebenen Ansatz verwenden:

http://blog.bdoughan.com/2011/06/ignoring-inheritance-with-xmltransient.html

auch Sie könnten moxy verwenden und einen benutzerdefinierten angeben Bindung: http://www.eclipse.org/eclipselink/documentation/2.4/moxy/runtime003.htm