java 实体类转xml格式(jaxb 和 xstrem)(一)

1.javxb方式

 定义可以接口xmlTag ,model时效表示可以转化为xml格式

/**
 * 描述:XmlTag
 *
 * @author 归墟
 * @date 2021/2/25 20:31
 */
public interface XmlTag {

    /**
     * 转换为xml格式
     *
     * @return string 类型 失败为null
     */
    String toXml();
}

定义jaxbXmltag 标记选用的方式转化方式


/**
 * 描述:XmlTag
 *
 * @author 归墟
 * @date 2021/2/24 10:42
 */
public interface JaxbXmlTag extends XmlTag{
    /**
     * 处理转换
     *
     * @return f返回
     * @throws Exception 异常
     */
    default String handToXml() throws Exception {
        StringWriter writer = new StringWriter();
        XMLStreamWriter streamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
        //使用动态代理模式, 对streamWriter功能进行干涉调整
        XMLStreamWriter cdataStreamWriter = (XMLStreamWriter) Proxy.newProxyInstance(
                streamWriter.getClass().getClassLoader(),
                streamWriter.getClass().getInterfaces(),
                new JaxbCdataHandler(streamWriter)
        );
        JAXBContext context = JAXBContext.newInstance(this.getClass());
        Marshaller mar = context.createMarshaller();
        mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        mar.setProperty(Marshaller.JAXB_ENCODING, ENCODING);
        //自定义
        NamespacePrefixMapper mapper = getNamespacePrefix();
        if (mapper != null) {
            mar.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper);
        }

        mar.marshal(this, cdataStreamWriter);
        return writer.toString();
    }

    /**
     * 自动以根号 命名空间 前缀
     *
     * @return 前缀消息
     */
    NamespacePrefixMapper getNamespacePrefix();

    /**
     * 默认utf-8编码
     */
    String ENCODING = "UTF-8";
}

自定义数据转化adapter ,可以处理cdata格式

public class JaxbStringCdataAdapter extends XmlAdapter<String, String> {


    @Override
    public String unmarshal(String v) {
        return v;
    }

    @Override
    public String marshal(String v) {
        return CdataConstant.PRE + v + CdataConstant.SUFFIX;
    }
}

处理cdata格式,动态代理转化cdata 避免符号被转意

public class JaxbCdataHandler implements InvocationHandler {

    private static Method gWriteCharactersMethod = null;

    static {
        try {
            gWriteCharactersMethod = XMLStreamWriter.class
                    .getDeclaredMethod("writeCharacters", char[].class, int.class, int.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    private final XMLStreamWriter writer;

    public JaxbCdataHandler(XMLStreamWriter writer) {
        this.writer = writer;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (gWriteCharactersMethod.equals(method)) {
            if (!(args[0] instanceof char[])) {
                return method.invoke(writer, args);
            }
            String text = new String((char[]) args[0]);
            if (text.startsWith(CdataConstant.PRE) && text.endsWith(CdataConstant.SUFFIX)) {
                writer.writeCData(text.substring(9, text.length() - 3));
                return null;
            }
        }
        return method.invoke(writer, args);
    }

}

实体demo

@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "root", namespace = "name-sp")
@Slf4j
public class JaxbXmlDemo implements JaxbXmlTag {
    @XmlElement(name = "id")
    @Getter(onMethod = @__(@XmlTransient))
    private String no;

    @XmlJavaTypeAdapter(value = JaxbStringCdataAdapter.class)
    @XmlElement(name = "msg")
    @Getter(onMethod = @__(@XmlTransient))
    private String text;
    private String token;

    @Override
    public String toXml() {
        try {
            return this.handToXml();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("失败===数据为{}", JSON.toJSONString(this));
        }
        return null;
    }

    @Override
    public NamespacePrefixMapper getNamespacePrefix() {
        return new NamespacePrefixMapper() {
            @Override
            public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
                return "test-prefix";
            }
        };
    }
}

gitlhub项目地址:https://github.com/foralllove/my-utils

gitee地址:https://gitee.com/huanghe3/my-utils

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值