XML报文处理总结
1. 基本转换工具类
基于JAXBContext可满足报文和java实体转换的基本需求
/**
* 版权: taylor
* 描述: 校验工具类
* 创建时间:2020年03月25日
*/
package com.taylor.xml.common.util;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.groups.Default;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import com.taylor.parsers.processor.core.listener.MarshallerListener;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
/**
* 类用途:校验工具类
*
* @author hucaihui
* @version [V1.2, 2020年03月25日]
* @since []
*/
public class ValidDataUtil {
/** 北京时区 */
private static final String ASIA_ZONE_ID = "+8";
/**验证器*/
private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
/**
* 校验失败提示最大长度
*/
private static final Integer FAIL_STRING_LENGTH_MAX = 950;
/**
* 检查数据格式
* @param object 需要验证的带有{@link javax.validation.constraints}注解的实体
* @param <T> the type of the object to validate
* @param groups the group or list of groups targeted for validation (defaults to {@link Default})
* @return 是否验证通过 {@link Result#isSuccess()}{@code true}表示通过,不通过时{@link Result#getMsg()}获取失败信息
*/
@NonNull
public static <T> Result validData(@NonNull T object, Class<?>... groups) {
String validateMsg = validator.validate(object,groups).stream().map(ConstraintViolation::getMessage)
.collect(Collectors.joining(","));
if (StringUtils.isBlank(validateMsg)) {
return Result.success();
}else {
return Result.build(Status.BAD_REQUEST,
validateMsg.length() > FAIL_STRING_LENGTH_MAX ? validateMsg.substring(0,FAIL_STRING_LENGTH_MAX) : validateMsg);
}
}
/**
* 将XML转为指定的POJO
* @param clazz POJO类常量
* @param reader 字符流
* @param <T> 需要转换的POJO类
* @return POJO实体 (实际一定能转换,因此忽略了转换警告)
* @throws JAXBException XML格式异常
*/
private static <T> T xmlReaderToObject(Class<T> clazz, Reader reader) throws JAXBException {
// XML 转为对象的接口
Unmarshaller unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
return clazz.cast(unmarshaller.unmarshal(reader));
}
/**
* 将报文XML样例文件转为指定的报文实体
* @param clazz POJO类常量
* @param path XML文件路径
* @param <T> 需要转换的报文类
* @return POJO实体
* @throws IOException IO异常
* @throws JAXBException XML格式异常
*/
@NonNull
public static <T > T xmlToObject(@NonNull Class<T> clazz, @NonNull String path) throws IOException, JAXBException {
try (Reader reader = new InputStreamReader(clazz.getResourceAsStream(path))){
return xmlReaderToObject(clazz,reader);
}
}
/**
* 将XML转为指定的POJO
* @param clazz POJO类常量
* @param xmlStr xml字符串
* @param <T> 需要转换的POJO类
* @return POJO实体 (实际一定能转换,因此忽略了转换警告)
* @throws JAXBException XML格式异常
* @throws IOException IO异常
*/
@NonNull
public static <T> T xmlStrToObject(@NonNull Class<T> clazz,@NonNull String xmlStr) throws IOException, JAXBException {
try (Reader reader = new StringReader(xmlStr)){
return xmlReaderToObject(clazz,reader);
}
}
/**
* 将POJO转为指定的XML
* @param obj 需要转换的POJO实体
* @param <T> 需要转换的POJO类
* @return XML字符串
* @throws JAXBException XML格式异常
* @throws IOException IO异常
*/
@NonNull
public static <T > String beanToXml(@NonNull T obj)
throws JAXBException, IOException {
// 对象 转为XML的接口
Marshaller marshaller = JAXBContext.newInstance(obj.getClass()).createMarshaller();
//格式化输出xml
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
try(StringWriter writer = new StringWriter()) {
//去掉standalone属性
writer.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n ");
marshaller.setProperty(Marshaller.JAX