UPDATE: Letztendlich versuchte ich alles hier vorgeschlagen und schien einige Fortschritte zu haben, aber meine API wurde für den beabsichtigten Zweck überentwickelt und ich lief die Zeit ab, so wechselte ich zu hart Codierung "Student -list "in der String-Antwort meines GET/Student Calls, die für den Proof of Concept mehr als genug war.JAXB Liste als oberste Ebene XML
Ich arbeite an einem einfachen REST-Service, der XML verwendet, um mit Studentenakten zu arbeiten.
, wenn ich ein GET auf/Student bekomme ich:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<students>
<student>
<grade>B</grade>
<name>Jane</name>
</student>
...
</students>
Allerdings würde ich die Ausgabe gerne sein:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<student-list>
<student>
<grade>B</grade>
<name>Jane</name>
</student>
...
</student-list>
Hier ist mein Student.java Schnipsel:
@XmlRootElement(name = "student")
public class Student {
private String name;
private String grade;
public Student() {
}
public Student(String name, String grade) {
super();
this.name = name;
this.grade = grade;
}
// getters/setters ...
}
Ich habe versucht, das XmlRootElement zu ändern "Student-lis t ", aber das macht jedes Unterelement der Liste zu einem Schülerlistentyp und ignoriert die Elementliste der obersten Ebene.
Das Projekt verwendet JAX-RS mit einer StudentSource-Klasse, die ich versucht habe, den XmlRootElement-Namen für diese Ressourcenklasse festzulegen, aber keine Auswirkungen auf die Ausgabe.
Es scheint automatisch die Top-Level-Liste basierend auf der StudentSource-Klasse zu benennen, und ich kann nicht herausfinden, wie diesen Namen zu überschreiben.
Ich habe die Dokumentation zu diesem Thema durchgekämmt, aber Java ist nicht meine stärkste Sprache in diesen Tagen, so habe ich Probleme zu verstehen, wie die Teile für JAXB und JAX-RS zusammenpassen.
Irgendwelche Ideen oder ein Schub in die richtige Richtung?
EDIT: hinzugefügt StudentsResource.java Snippet:
@Path("/student")
public class StudentsResource {
// this is a mapper class
@Context
UriInfo uriInfo;
@Context
Request request;
StudentService studentService;
public StudentsResource() {
studentService = new StudentService();
}
@GET
@Produces("text/xml;charset=utf-8")
public List<Student> getStudents() {
return studentService.getStudentAsList();
}
...
}
Basierend auf Mateen Momin das Feedback, habe ich jetzt diese Ausgabe haben durch den REST-Service auf GET/Schüler:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<studentDao_Students>
<student>
<name>Jane</name>
<grade>B</grade>
</student>
...
</studentDao_Students>
Ich habe ein StudentDao, das von einem StudentService umschlossen wird, der schließlich von Ressourcenklassen aufgerufen wird, um die HTTP-Aufrufe zu ermöglichen. Ich habe meine Schüler Klasse in StudentDao bewegt, was mich gemacht erkennen, dass die StudentService ist, was tatsächlich vermarshallten immer, hier aktualisiert Schnipsel:
StudentDao.java:
public enum StudentDao {
instance;
private Map<String, Student> students = new HashMap<String, Student>();
private StudentDao() {
//pre-populate for testing purposes
Student student = new Student("John", "A");
students.put("John", student);
student = new Student("Jane", "B");
students.put("Jane", student);
student = new Student("TESTUSER", "F");
students.put("TESTUSER", student);
}
public Map<String, Student> getStudents() {
return students;
}
@XmlRootElement(name="student")
@XmlAccessorType(XmlAccessType.FIELD)
public static class Student {
private String name;
private String grade;
public Student() {
}
public Student(String name, String grade) {
super();
this.name = name;
this.grade = grade;
}
// getters/setters here...
}
}
StudentService.java :
@XmlRootElement(name = "student-list")
@XmlAccessorType(XmlAccessType.FIELD)
public class StudentService {
StudentDao studentDao;
public StudentService() {
studentDao = StudentDao.instance;
}
// CRUD methods here which call the StudentDao HashMap
}
StudentenResource. java:
@Path("/student")
public class StudentsResource {
@Context
UriInfo uriInfo;
@Context
Request request;
StudentService studentService;
public StudentsResource() {
studentService = new StudentService();
}
@GET
@Produces("text/xml;charset=utf-8")
public List<Student> getStudents() {
return studentService.getStudentAsList();
}
// other HTTP calls, POST,PUT,etc. here
}
habe ich eine Hauptfunktion, um zu sehen, was passiert, wenn ich die JAXBContext angeben:
Haupt zum Testen Konsolausgabe:
public class Main {
public static void main(String[] args) {
StudentService studentDao = new StudentService();
StudentDao.Student stu1 = new StudentDao.Student();
stu1.setName("marc");
stu1.setGrade("A");
StudentDao.Student stu2 = new StudentDao.Student();
stu2.setName("jacob");
stu2.setGrade("B");
StudentDao.Student stu3 = new StudentDao.Student();
stu3.setName("anthony");
stu3.setGrade("A");
studentDao.createStudent(stu1);
studentDao.createStudent(stu2);
studentDao.createStudent(stu3);
try {
File file = new File("out.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(StudentService.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(studentDao, file);
jaxbMarshaller.marshal(studentDao, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Wenn ich ausführen, um diese Hauptfunktion um die Ausgabe zu sehen, bekomme ich tatsächlich das, was natürlich NICHT zur REST-Ausgabe passt:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<student-list>
<studentDao>instance</studentDao>
</student-list>
Das scheint vielversprechend, aber ich kann nicht bekommen, dass der Klassenname der obersten Ebene in den REST-Aufrufen überschrieben wird, was letztendlich das ist, was ich brauche.
Irgendwelche anderen Ideen, was ich hier falsch mache?
können Sie Ihre 'StudentsResource' oder vielleicht nur relevanten Teil zeigen – varren
Ohne irgendwelche benutzerdefinierten Serialisierungskomponenten zu schreiben, wird jede Unterstützung für diese Implementierung spezifisch sein . Ich weiß, dass RESTEasy dafür Unterstützung bietet. Soweit ich mich erinnern kann, habe Jersey diese Fähigkeit nicht. Welche JAX-RS-Implementierung verwenden Sie? –
Haben Sie '@XmlElementWrapper (name =" student-list ")' 'verwendet? – mattymanme