maven
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11.1</version>
</dependency>
converter
@Slf4j
public class XmlStringConverter implements Converter {
private int length;
public XmlStringConverter(int length) {
this.length = length;
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
String target = format((String) source);
log.debug("java {} -> xml String, source: {}, target: {}", source.getClass(), source, target);
writer.setValue(target);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Class type = context.getRequiredType();
String source = reader.getValue();
String target = parse(source);
log.debug("xml String -> java {}, source: {}, target: {}", type, source, target);
return target;
}
@Override
public boolean canConvert(Class type) {
return String.class.equals(type);
}
private String format(String value) {
if (value.length() >= length) {
return value;
}
return StringUtils.repeat(" ", length - value.length()) + value;
}
private static String parse(String string) {
if (StringUtils.isBlank(string)) {
return null;
}
return string.trim();
}
}
@Slf4j
public class XmlIntegerConverter implements Converter {
public XmlIntegerConverter() {
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
String target = format((Integer) source);
log.debug("java {} -> xml String, source: {}, target: {}", source.getClass(), source, target);
writer.setValue(target);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Class type = context.getRequiredType();
String source = reader.getValue();
Integer target = parse(source);
log.debug("xml String -> java {}, source: {}, target: {}", type, source, target);
return target;
}
@Override
public boolean canConvert(Class type) {
return Integer.class.equals(type);
}
private String format(Integer value) {
String string = String.format("%s", value);
if (string.length() < 4) {
string = StringUtils.repeat("0", 4 - string.length()) + string;
}
return string;
}
private static Integer parse(String string) {
if (StringUtils.isBlank(string)) {
return null;
}
return Integer.valueOf(string);
}
}
@Slf4j
public class XmlDateConverter implements Converter {
private String pattern;
public XmlDateConverter(String pattern) {
this.pattern = pattern;
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
String target = format((Date) source);
log.debug("java {} -> xml String, source: {}, target: {}", source.getClass(), source, target);
writer.setValue(target);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Class type = context.getRequiredType();
String source = reader.getValue();
Date target = parse(source);
log.debug("xml String -> java {}, source: {}, target: {}", type, source, target);
return target;
}
@Override
public boolean canConvert(Class type) {
return Date.class.equals(type);
}
private String format(Date value) {
return DateFormatUtils.format(value, pattern);
}
private Date parse(String string) {
if (StringUtils.isBlank(string)) {
return null;
}
Date date;
try {
date = DateUtils.parseDate(string, new String[]{pattern});
} catch (Exception e) {
throw new RuntimeException(e);
}
return date;
}
}
utils
@Slf4j
public class XStreamUtils {
private static final XStream xStream;
private static final String XML_REG = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
static {
xStream = new XStream(new DomDriver());
xStream.ignoreUnknownElements();
xStream.allowTypesByRegExp(new String[]{"com.wakzz.*"});
xStream.processAnnotations(new Class[]{SendRequest.class});
}
public static <T> T parse(String xml, Class<T> clazz) {
try {
return (T) xStream.fromXML(xml);
} catch (Exception e){
log.error("xml转换javabean异常, xml: {}, class: {}", xml, clazz);
log.error(e.getMessage(), e);
}
return null;
}
public static String toXml(Object object) {
String value = null;
try (ByteArrayOutputStream output = new ByteArrayOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(output)) {
xStream.marshal(object, new CompactWriter(outputStreamWriter));
value = new String(output.toByteArray());
} catch (Exception e) {
log.error("javabean转换xml异常, class: {}, value: {}", object.getClass(), object);
log.error(e.getMessage(), e);
}
if (value == null) {
return null;
}
return XML_REG + value;
}
}
test
@Data
@XStreamAlias("appMsg")
public class SendRequest {
@XStreamAlias("appBody")
private SendBody sendBody;
private String version;
@XStreamConverter(value = XmlDateConverter.class, strings = {"yyyyMMddHHmmss"})
private Date reqTime;
}
@Data
public class SendBody {
@XStreamConverter(value = XmlStringConverter.class, ints = {20})
private String orderNo;
@XStreamConverter(value = XmlStringConverter.class, ints = {30})
private String activeNo;
@XStreamConverter(value = XmlIntegerConverter.class)
private Integer num;
@XStreamConverter(value = XmlStringConverter.class, ints = {11})
private String phoneNo;
@XStreamConverter(value = XmlDateConverter.class, strings = {"yyyyMMdd"})
private Date sendTime;
}
public static void main(String[] args) {
String xml = "" +
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<appMsg>\n" +
" <appBody>\n" +
" <orderNo>2018081322451475890044</orderNo>\n" +
" <activeNo>jt20180528102410333649</activeNo>\n" +
" <num>0001</num>\n" +
" <phoneNo>15012341234</phoneNo>\n" +
" </appBody>\n" +
" <version>1.0.0</version>\n" +
" <reqTime>20180322152245</reqTime>\n" +
"</appMsg>" +
"";
SendRequest appMsg = parse(xml, SendRequest.class);
System.out.println(appMsg);
String string = toXml(appMsg);
System.out.println(string);
}