现在有一个实体类对象的集合,需要将它们转换为xml文档,xml文档就是标签集合的嵌套,例如一个学生类,有姓名、年龄等,需要转换成一下效果:
<student><age>14</age><name>张三</name></student><student><age>15</age><name>李四</name></student><student><age>16</age><name>王五</name></student>
首先定义student的实体类:
import lombok.Data;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;@Data
@XmlRootElement
public class Student {private String name;private int age;// 无参构造函数(必须有)public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}@XmlElementpublic String getName() {return name;}public void setName(String name) {this.name = name;}@XmlElementpublic int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
因为是student的集合,需要再构建一个StudentListWrapper类:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;@XmlRootElement
public class StudentListWrapper {private List<Student> students;public StudentListWrapper() {}public StudentListWrapper(List<Student> students) {this.students = students;}@XmlElement(name = "student")public List<Student> getStudents() {return students;}public void setStudents(List<Student> students) {this.students = students;}
}
两种下载方式:无返回值的:
@GetMapping("testXmlDownload")public void testXmlDownload(HttpServletResponse response) throws Exception {try {// 创建一个包含 Student 对象的集合List<Student> studentList = new ArrayList<>();studentList.add(new Student("张三", 14));studentList.add(new Student("李四", 15));studentList.add(new Student("王五", 16));// 创建 JAXB 上下文JAXBContext context = JAXBContext.newInstance(StudentListWrapper.class);// 创建 MarshallerMarshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 将集合序列化为 XMLStringWriter writer = new StringWriter();marshaller.marshal(new StudentListWrapper(studentList), writer);// 输出 XML 格式的文档String xmlDocument = writer.toString();byte[] bytes = xmlDocument.getBytes();// 使用 ByteArrayInputStream 将字节数组转换为 InputStreamInputStream inputStream = new ByteArrayInputStream(bytes);// 使用 BufferedInputStream 包装 InputStreamBufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);byte[] buffer = new byte[bufferedInputStream.available()];bufferedInputStream.read(buffer);bufferedInputStream.close();response.reset();response.setCharacterEncoding("UTF-8");response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("student".concat(".xml"), "UTF-8"));//response.addHeader("Content-Length", "" + file.length());OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());response.setContentType("application/octet-stream");outputStream.write(buffer);outputStream.flush();// System.out.println(xmlDocument);} catch (Exception e) {e.printStackTrace();}}
第二种:使用 ResponseEntity 对象来封装响应内容和响应头,并返回给客户端:
@GetMapping("/download")public ResponseEntity<byte[]> downloadFile() throws Exception {// 创建一个包含 Student 对象的集合List<Student> studentList = new ArrayList<>();studentList.add(new Student("张三", 14));studentList.add(new Student("李四", 15));studentList.add(new Student("王五", 16));// 创建 JAXB 上下文JAXBContext context = JAXBContext.newInstance(StudentListWrapper.class);// 创建 MarshallerMarshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// 将集合序列化为 XMLStringWriter writer = new StringWriter();marshaller.marshal(new StudentListWrapper(studentList), writer);// 输出 XML 格式的文档String xmlContent = writer.toString();// byte[] bytes = xmlDocument.getBytes();// 将 XML 内容转换为字节数组byte[] xmlBytes = xmlContent.getBytes(StandardCharsets.UTF_8);// 构造响应头HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_XML);headers.setContentDispositionFormData("attachment", "students.xml");// 构造 ResponseEntity 对象,设置响应内容和响应头ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(xmlBytes, headers, HttpStatus.OK);return responseEntity;}
使用postman测试:
复制到浏览器测试:
打开效果: