javajaxb列表作为顶级XML
更新:最终,我尝试了这里建议的一切,似乎取得了一些进展,但我的API设计过度,无法达到预期目的,因此我在GET/student调用的字符串响应中切换到硬编码“student list”,这足以证明我需要它
我正在开发一个简单的REST服务,它使用XML处理学生记录
当我做一个“上车/学生”时,我得到:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<students>
<student>
<grade>B</grade>
<name>Jane</name>
</student>
...
</students>
但是,我希望输出为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<student-list>
<student>
<grade>B</grade>
<name>Jane</name>
</student>
...
</student-list>
这是我的学生。java代码片段:
@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 ...
}
我尝试将XmlRootElement更改为“student list”,但这会使列表的每个子元素都成为student list类型,并忽略顶级元素列表
该项目将JAX-RS与StudentsResource类一起使用,我已尝试在该资源类上设置XmlRootElement名称,但这并不影响任何输出
它似乎是根据StudentsResource类自动命名顶级列表,我不知道如何覆盖这个名称
我一直在梳理这方面的文档,但Java不是我这些天最强大的语言,所以我很难理解JAXB和JAX-RS的各个部分是如何组合在一起的
有什么想法,或是朝着正确的方向推进
编辑:添加学生资源。java代码片段:
@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();
}
...
}
根据Mateen Momin的反馈,我现在在GET/student上有REST服务的输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<studentDao_Students>
<student>
<name>Jane</name>
<grade>B</grade>
</student>
...
</studentDao_Students>
我有一个StudentDao,它由StudentService包装,最终由资源类调用,以使HTTP调用成为可能。我已经将我的学生类移到了StudentDao中,这使我意识到StudentService实际上是被编组的,下面是更新的片段:
学生道。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...
}
}
学生服务。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
}
学生资源。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
}
我创建了一个main函数,以查看如果指定JAXBContext会发生什么:
主要用于测试控制台输出:
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();
}
}
}
当我运行这个main函数来查看输出时,我实际上得到了这样的结果,当然,这与其余的输出不匹配:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<student-list>
<studentDao>instance</studentDao>
</student-list>
这似乎很有希望,但我无法在REST调用中覆盖顶级类名,这正是我最终需要的
还有其他关于我做错了什么的想法吗
# 1 楼答案
学生班
主要方法/marshaller使用:
生成的输出:
PS:由于您使用的是REST,上述主要方法可用于您的FYI。使用这个main方法来相应地构建
studentService.getStudentAsList()
方法。(我的假设是,它将给出几乎相同的xml。):)