JAXB编组结果在POSTMAN显示异常及Web服务解组XML问题咨询
问题解析与解决方案
我正在开发一个Web服务项目,把图书信息(bookInfo)存在本地XML文件里,需要提供接口查看所有图书信息。目前用JAXB把XML解组为POJO,写了部分代码如下:
AllItems items = null; try { JAXBContext jaxbContext = JAXBContext.newInstance(AllItems.class); Unmarshaller unMarshaller = jaxbContext.createUnmarshaller(); FileReader fileReader = new FileReader(new File("items.xml")); items = (AllItems) unMarshaller.unmarshal(fileReader); } catch (JAXBException | IOException e) { e.printStackTrace(); }
另外遇到一个问题:用JAXB Marshaller配合StringWriter生成的XML内容,在Postman里查看时,<被转义成了&lt;(也就是双重转义),想知道怎么解决这个问题。
1. 完善你的JAXB解组代码
首先把你没写完的解组逻辑补全,同时优化资源管理和异常处理,避免资源泄漏:
AllItems items = null; // 用try-with-resources语法自动关闭FileReader,不用手动写close() try (FileReader fileReader = new FileReader(new File("items.xml"))) { JAXBContext jaxbContext = JAXBContext.newInstance(AllItems.class); Unmarshaller unMarshaller = jaxbContext.createUnmarshaller(); items = (AllItems) unMarshaller.unmarshal(fileReader); // 这里可以添加获取图书列表的逻辑,比如: // List<BookInfo> bookList = items.getBookInfos(); } catch (JAXBException | IOException e) { // 建议不要只打印栈轨迹,根据业务场景处理异常,比如抛自定义服务异常 System.err.println("XML解组失败:" + e.getMessage()); e.printStackTrace(); }
2. 解决XML双重转义的问题
你看到的&lt;是双重转义的结果——原本的<被转义成<,然后&又被再次转义成&,所以最终变成了&lt;。常见原因和解决方法如下:
场景1:Web框架重复转义(比如Spring MVC)
如果是在Web接口中返回XML,不要手动生成字符串返回,直接返回你的POJO对象,让Web框架(比如Spring)帮你处理XML序列化,这样就能避免重复转义:
// 错误示例:手动生成字符串,框架会再次转义 @GetMapping("/books") @ResponseBody public String getAllBooks() throws JAXBException { AllItems items = getAllItemsFromXml(); JAXBContext jaxbContext = JAXBContext.newInstance(AllItems.class); Marshaller marshaller = jaxbContext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter writer = new StringWriter(); marshaller.marshal(items, writer); return writer.toString(); // 这里返回的字符串会被框架再次转义 } // 正确示例:直接返回POJO,框架自动处理XML序列化 @GetMapping("/books") @ResponseBody public AllItems getAllBooks() { return getAllItemsFromXml(); // 确保你的POJO类有正确的JAXB注解(@XmlRootElement等) }
场景2:手动使用Marshaller时的错误配置
如果必须手动生成XML字符串(非Web场景),检查是否错误设置了转义相关属性,JAXB默认会正确处理XML特殊字符,不需要额外配置强制转义:
// 正确的手动生成XML方式 JAXBContext jaxbContext = JAXBContext.newInstance(AllItems.class); Marshaller marshaller = jaxbContext.createMarshaller(); // 可选:开启格式化输出,让XML更易读 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); // 不要添加自定义的转义处理器,除非你明确知道需求 StringWriter writer = new StringWriter(); marshaller.marshal(items, writer); String xmlContent = writer.toString(); // 此时xmlContent中的<会被正确转义为<,不会出现双重转义
另外,你可以在Postman的Raw标签页查看真实的响应内容,有时候"Pretty"视图会显示转义后的格式,Raw视图才是服务器返回的原始内容。
内容的提问来源于stack exchange,提问作者Sid
相关产品推荐
相关产品推荐

