jaxb xmlStr与对象互转+手动校验

接了个webService的老项目,记录一下处理常见xml转化验证的处理工具方式

工具类XmlUtil

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.**.healthcardadapter.constant.ExceptionConstant;
import com。**.healthcardadapter.dto.request.RequestActionBaseDTO;
import com.**.healthcardadapter.exception.BusinessException;
import com.**.healthcardadapter.exception.ErrorCode;
import lombok.extern.slf4j.Slf4j;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * Description XmlUtil转化工具
 */
@Slf4j
public class XmlUtil {

    /**
     * 对象转XML
     *
     * @param obj 目标对象
     * @return 返回string格式的xml报文
     */
    public static String objToXml(Object obj) {
        StringWriter sw = new StringWriter();
        String result = null;
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            // 去除换行
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
            // 除去xml的默认报文头部
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8";
            // 处理字段为空值时候不返回不生成字段问题
            marshaller.setListener(new Marshaller.Listener() {
                @Override
                public void beforeMarshal(Object source) {
                    Field[] fields = source.getClass().getDeclaredFields();
                    for (Field f : fields) {
                        f.setAccessible(true);
                        try {
                            //对象为空且类型为String时候设置空值
                            if (f.getType() == String.class && f.get(source) == null) {
                                f.set(source, "");
                            }
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                            log.error("对象转化xml处理空值字段时错误" + e.getMessage());
                        }
                    }
                }
            });
            marshaller.marshal(obj, sw);
            result = sw.toString();
        } catch (JAXBException e) {
            log.error("对象转XML异常:{}", e.getMessage());
            throw BusinessException.create(ErrorCode.SystemDefaultCode.INTERNAL_SERVER_ERROR, ExceptionConstant.SYS_ERROR);
        } finally {
            try {
                sw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * Description xmlSring 转对象
     *
     * @param xmlStr xmlStr
     * @param clazz  clazz
     * @return T
     *  
     */
    public static <T> T fromXml(String xmlStr, Class<T> clazz) {

        T result = null;

        // 处理CDATA
        if (StrUtil.isNotEmpty(xmlStr) && xmlStr.trim().startsWith("<![CDATA[") && xmlStr.trim().endsWith("]]>")) {
            xmlStr = xmlStr.trim().substring(9, xmlStr.length() - 3);
        }
        StringReader reader = new StringReader(xmlStr);
        try {

            JAXBContext context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            result = (T) unmarshaller.unmarshal(reader);
        } catch (JAXBException e) {
            log.error("xml转对象异常:{}", e.getMessage());
            throw BusinessException.create(ErrorCode.SystemDefaultCode.INTERNAL_SERVER_ERROR, ExceptionConstant.SYS_ERROR);
        } finally {
            reader.close();
        }
        return result;
    }

    public static void main(String[] args) {
        String message ="<![CDATA[<request><msgGuid>7163D5BA71974456BFE7436D57F9F923         </msgGuid><msgType>1</msgType><msgCreateTime>2022-06-10 09:38:36</msgCreateTime><bussinessCode>RHC_E0005</bussinessCode><orgId>630000000000</orgId><appCode></appCode><userName>test</userName><userPwd>test123123123</userPwd><stdVerCode>1.0.0</stdVerCode></request>]]>";
        RequestActionBaseDTO messageDTO = XmlUtil.fromXml(message, RequestActionBaseDTO.class);
        System.out.println(JSONUtil.toJsonStr(messageDTO));
    }

转化对象类,XmlJavaTypeAdapter  xml转对象属性去除空格

@XmlRootElement(name = "request")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
@Data
public class RequestActionBaseDTO {

    /**
     * 消息标识符号
     * 32位消息流水号,消息唯一标识 
     */
    @Length(max = 32)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String msgGuid;

    /**
     * 消息类别
     * 标识消息的类别,
     * 接口平台指定固定值为:1
     */
    @Length(max = 7)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String msgType;


 
    @Length(max = 50)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String bussinessCode;



    /**
     * 消息创建时间
     * 消息创建时间为调用接口的当前时间,格式为YYYY-MM-DDHH:mm:ss
     */
    @Length(max = 17)
    @NotBlank
    @DateTimeValidte
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String msgCreateTime;


    @Length(max = 32)
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String orgId;


 
    @Length(max = 6)
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String appCode;


  
    @Length(max = 32)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String userName;


    @Length(max = 32)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String userPwd;

    /**
     * 版本
     */
    @Length(max = 1)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String stdVerCode;

  
    @Length(max = 100)
    @NotBlank
    @XmlJavaTypeAdapter(value = CollapsedStringAdapter.class)
    private String encryption;

}

java校验注解手动触发工具类

import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.HibernateValidator;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Iterator;
import java.util.Set;

/**
 * Description dto注解校验手动触发工具类
 *
 * @ClassName ValidatorUtils
 */
@Slf4j
public class ValidatorUtils {

    private static Validator validatorFast = Validation.byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();
    private static Validator validatorAll = Validation.byProvider(HibernateValidator.class).configure().failFast(false).buildValidatorFactory().getValidator();

    /**
     * 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验
     * @param <T>
     * @param domain
     * @return
     * @throws IllegalArgumentException
     */
    public static <T> Set<ConstraintViolation<T>> validateFast(T domain) {
        Set<ConstraintViolation<T>> validateResult = validatorFast.validate(domain);
        if(validateResult.size()>0) {
            log.error(validateResult.iterator().next().getPropertyPath() +":"+ validateResult.iterator().next().getMessage());
        }
        return validateResult;
    }

    /**
     * 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验,返回webService错误信息
     * @param <T>
     * @param domain
     */
    public static <T> String validateXmlFast(T domain) {
        Set<ConstraintViolation<T>> validateResult = validatorFast.validate(domain);
        if(validateResult.size()>0) {
            return BusinessException.create(ResultCodeEnum.RESULT_CODE_1601, validateResult.iterator().next().getPropertyPath() +":"+ validateResult.iterator().next().getMessage());
        }
        return "";
    }

    /**
     * 校验所有字段并返回不合法字段
     * @param <T>
     * @param domain
     * @return
     * @throws IllegalArgumentException
     */
    public static <T> Set<ConstraintViolation<T>> validateAll(T domain) throws IllegalArgumentException {
        Set<ConstraintViolation<T>> validateResult = validatorAll.validate(domain);
        if(validateResult.size()>0) {
            Iterator<ConstraintViolation<T>> it = validateResult.iterator();
            while(it.hasNext()) {
                ConstraintViolation<T> cv = it.next();
                log.error(cv.getPropertyPath()+":"+cv.getMessage());
            }
        }
        return validateResult;
    }

 public static void main(String[] args) {
        String message = "<![CDATA[<request><id_card>632822197101030026</id_card><id_type>01</id_type></request>]]>";
        RequestQueryQRMessageDTO messageDTO = XmlUtil.fromXml(message, RequestQueryQRMessageDTO.class);
        // 注解手动触发基本校验测试
        String validatorStr = ValidatorUtils.validateXmlFast(messageDTO);
        if (StrUtil.isNotEmpty(validatorStr)) {
            return validatorStr;
        }
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值