diff --git a/CHANGELOG.md b/CHANGELOG.md index 471f7ab77..d35a456f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,13 @@ ### 🐣新特性 * 【core 】 增加Convert.toSet方法(issue#I3XFG2@Gitee) * 【core 】 CsvWriter增加writeBeans方法(pr#345@Gitee) +* 【core 】 新增JAXBUtil(pr#346@Gitee) ### 🐞Bug修复 * 【json 】 修复XML转义字符的问题(issue#I3XH09@Gitee) * 【core 】 修复FormatCache中循环引用异常(pr#1673@Github) * 【core 】 修复IdcardUtil.getIdcardInfo.getProvinceCode获取为汉字的问题(issue#I3XP4Q@Gitee) +* 【core 】 修复CollUtil.subtract使用非标准Set等空指针问题(issue#I3XN1Z@Gitee) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java new file mode 100644 index 000000000..19101cd0e --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/util/JAXBUtil.java @@ -0,0 +1,106 @@ +package cn.hutool.core.util; + +import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import java.io.File; +import java.io.Reader; +import java.io.StringWriter; +import java.nio.charset.Charset; + +/** + * JAXB(Java Architecture for XML Binding),根据XML Schema产生Java对象,即实现xml和Bean互转。 + *

+ * 相关介绍: + *

+ * + * @author dazer + * @since 5.7.3 + */ +public class JAXBUtil { + + /** + * JavaBean转换成xml + * + * @param bean Bean对象 + * @return 输出的XML字符串 + */ + public static String beanToXml(Object bean) { + return beanToXml(bean, CharsetUtil.CHARSET_UTF_8, true); + } + + /** + * JavaBean转换成xml + * + * @param bean Bean对象 + * @param charset 编码 eg: utf-8 + * @param format 是否格式化输出eg: true + * @return 输出的XML字符串 + */ + public static String beanToXml(Object bean, Charset charset, boolean format) { + StringWriter writer; + try { + JAXBContext context = JAXBContext.newInstance(bean.getClass()); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, format); + marshaller.setProperty(Marshaller.JAXB_ENCODING, charset.name()); + writer = new StringWriter(); + marshaller.marshal(bean, writer); + } catch (Exception e) { + throw new UtilException("convertToXml 错误:" + e.getMessage(), e); + } + return writer.toString(); + } + + /** + * xml转换成JavaBean + * + * @param xml XML字符串 + * @param c Bean类型 + * @return bean + */ + public static T xmlToBean(String xml, Class c) { + return xmlToBean(StrUtil.getReader(xml), c); + } + + /** + * XML文件转Bean + * + * @param file 文件 + * @param charset 编码 + * @param c Bean类 + * @param Bean类型 + * @return Bean + */ + public static T xmlToBean(File file, Charset charset, Class c) { + return xmlToBean(FileUtil.getReader(file, charset), c); + } + + /** + * 从{@link Reader}中读取XML字符串,并转换为Bean + * + * @param reader {@link Reader} + * @param c Bean类 + * @param Bean类型 + * @return Bean + */ + @SuppressWarnings("unchecked") + public static T xmlToBean(Reader reader, Class c) { + try { + JAXBContext context = JAXBContext.newInstance(c); + Unmarshaller unmarshaller = context.createUnmarshaller(); + return (T) unmarshaller.unmarshal(reader); + } catch (Exception e) { + throw new RuntimeException("convertToJava2 错误:" + e.getMessage(), e); + } finally { + IoUtil.close(reader); + } + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/util/XmlBeanUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/XmlBeanUtil.java deleted file mode 100644 index 3f7c384d0..000000000 --- a/hutool-core/src/main/java/cn/hutool/core/util/XmlBeanUtil.java +++ /dev/null @@ -1,102 +0,0 @@ -package cn.hutool.core.util; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import java.io.*; -import java.nio.charset.StandardCharsets; - -/** - * xml和Bean互转工具类,不依赖第三方库;需要使用到:javax.xml 包 - * @author dazer - * 相关介绍: - * - */ -public class XmlBeanUtil { - /** - * JavaBean转换成xml - * - * @param obj - * @param encoding eg: utf-8 - * @param format eg: true - * @return - */ - public static String convertToXml(Object obj, String encoding, boolean format) { - String result = null; - StringWriter writer = null; - try { - JAXBContext context = JAXBContext.newInstance(obj.getClass()); - Marshaller marshaller = context.createMarshaller(); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, format); - marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding); - writer = new StringWriter(); - marshaller.marshal(obj, writer); - result = writer.toString(); - } catch (Exception e) { - throw new RuntimeException("convertToXml 错误:" + e.getMessage(), e); - } finally { - if (writer != null){ - try { - writer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return result; - } - - public static String convertToXml(Object obj) { - return convertToXml(obj, StandardCharsets.UTF_8.toString(), true); - } - - /** - * xml转换成JavaBean - * - * @param xml - * @param c - * @return - */ - @SuppressWarnings("unchecked") - public static T convertToJava(String xml, Class c) { - if (xml == null || "".equals(xml)) - return null; - T t = null; - StringReader reader = null; - try { - JAXBContext context = JAXBContext.newInstance(c); - Unmarshaller unmarshaller = context.createUnmarshaller(); - reader = new StringReader(xml); - t = (T) unmarshaller.unmarshal(reader); - } catch (Exception e) { - throw new RuntimeException("convertToJava1 错误:" + e.getMessage(), e); - } finally { - if (reader != null) - reader.close(); - } - return t; - } - - @SuppressWarnings("unchecked") - public static T convertToJava(File filePath, Class c) throws IOException { - if (!filePath.exists()) - return null; - T t = null; - FileReader reader = null; - try { - JAXBContext context = JAXBContext.newInstance(c); - Unmarshaller unmarshaller = context.createUnmarshaller(); - reader = new FileReader(filePath); - t = (T) unmarshaller.unmarshal(reader); - } catch (Exception e) { - throw new RuntimeException("convertToJava2 错误:" + e.getMessage(), e); - } finally { - if (reader != null) - reader.close(); - } - return t; - } -} diff --git a/hutool-core/src/test/java/cn/hutool/core/util/XmlBeanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/JAXBUtilTest.java similarity index 64% rename from hutool-core/src/test/java/cn/hutool/core/util/XmlBeanUtilTest.java rename to hutool-core/src/test/java/cn/hutool/core/util/JAXBUtilTest.java index 8fdb8cdcb..8d9ce8989 100644 --- a/hutool-core/src/test/java/cn/hutool/core/util/XmlBeanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/util/JAXBUtilTest.java @@ -6,15 +6,25 @@ import org.junit.Test; import javax.xml.bind.annotation.*; /** - * {@link XmlBeanUtil} 工具类 + * {@link JAXBUtil} 工具类 + * 测试 xml 和 bean 互转工具类 * * @author dazer - * 测试 xml 和 bean 互转工具类 */ -public class XmlBeanUtilTest { +public class JAXBUtilTest { + + private String xmlStr = "\n" + + "\n" + + " 西安市第一中学\n" + + " 西安市雁塔区长安堡一号\n" + + " \n" + + " 101\n" + + " 101教室\n" + + " \n" + + "\n"; @Test - public void convertToXmlTest() { + public void beanToXmlTest() { SchoolVo schoolVo = new SchoolVo(); schoolVo.setSchoolName("西安市第一中学"); schoolVo.setSchoolAddress("西安市雁塔区长安堡一号"); @@ -24,22 +34,23 @@ public class XmlBeanUtilTest { roomVo.setRoomNo("101"); schoolVo.setRoom(roomVo); - String xmlStr = "\n" + - "\n" + - " 西安市第一中学\n" + - " 西安市雁塔区长安堡一号\n" + - " \n" + - " 101\n" + - " 101教室\n" + - " \n" + - "\n"; - Assert.assertEquals(XmlBeanUtil.convertToXml(schoolVo), xmlStr); + Assert.assertEquals(xmlStr, JAXBUtil.beanToXml(schoolVo)); } + @Test + public void xmlToBeanTest() { + final SchoolVo schoolVo = JAXBUtil.xmlToBean(xmlStr, SchoolVo.class); + Assert.assertNotNull(schoolVo); + Assert.assertEquals("西安市第一中学", schoolVo.getSchoolName()); + Assert.assertEquals("西安市雁塔区长安堡一号", schoolVo.getSchoolAddress()); + + Assert.assertEquals("101教室", schoolVo.getRoom().getRoomName()); + Assert.assertEquals("101", schoolVo.getRoom().getRoomNo()); + } @XmlRootElement(name = "school") @XmlAccessorType(XmlAccessType.FIELD) - private static final class SchoolVo { + public static class SchoolVo { @XmlElement(name = "school_name", required = true) private String schoolName; @XmlElement(name = "school_address", required = true)