1、编写自定义XPPDriver代码:
package com.c.common; import java.io.Writer; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.XppDriver; public class MyXppDriver extends XppDriver { public HierarchicalStreamWriter createWriter(Writer out) { return new MyPrettyPrintWriter(out); } }
2、编写自定义格式化器,可以使XML中的特殊字符被<cdata>包含起来。
package com.mport.xstream; import java.io.PrintWriter; import java.io.Writer; import com.thoughtworks.xstream.core.util.FastStack; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; public class MyPrettyPrintWriter implements HierarchicalStreamWriter { private final QuickWriter writer; private final FastStack elementStack = new FastStack(16); private final char[] lineIndenter; private boolean tagInProgress; private int depth; private boolean readyForNewLine; private boolean tagIsEmpty; private static final char[] AMP = "&".toCharArray(); private static final char[] LT = "<".toCharArray(); private static final char[] GT = ">".toCharArray(); private static final char[] SLASH_R = " ".toCharArray(); private static final char[] QUOT = """.toCharArray(); private static final char[] APOS = "'".toCharArray(); private static final char[] CLOSE = "</".toCharArray(); public MyPrettyPrintWriter(Writer writer, char[] lineIndenter) { this.writer = new QuickWriter(writer); this.lineIndenter = lineIndenter; } public MyPrettyPrintWriter(Writer writer, String lineIndenter) { this(writer, lineIndenter.toCharArray()); } public MyPrettyPrintWriter(PrintWriter writer) { this(writer, new char[]{' ', ' '}); } public MyPrettyPrintWriter(Writer writer) { this(new PrintWriter(writer)); } public void startNode(String name) { tagIsEmpty = false; finishTag(); writer.write('<'); writer.write(name); elementStack.push(name); tagInProgress = true; depth++; readyForNewLine = true; tagIsEmpty = true; } public void setValue(String text) { readyForNewLine = false; tagIsEmpty = false; finishTag(); writeText(writer, text); } public void addAttribute(String key, String value) { writer.write(' '); writer.write(key); writer.write('='); writer.write('"'); writeAttributeValue(writer, value); writer.write('"'); } protected void writeAttributeValue(QuickWriter writer, String text) { int length = text.length(); for (int i = 0; i < length; i++) { char c = text.charAt(i); switch (c) { case '&': this.writer.write(AMP); break; case '<': this.writer.write(LT); break; case '>': this.writer.write(GT); break; case '"': this.writer.write(QUOT); break; case '\'': this.writer.write(APOS); break; case '\r': this.writer.write(SLASH_R); break; default: this.writer.write(c); } } } protected void writeText(QuickWriter writer, String text) { int length = text.length(); String CDATAPrefix = "<![CDATA["; String CDATASuffix = "]]>"; if (!text.startsWith(CDATAPrefix)){ boolean needCDATA=false; for (int i = 0;i < length;i++) { char c = text.charAt(i); if(c=='&'||c=='<'||c=='>'||c=='\''||c=='\r'){ needCDATA=true; break; } } if(needCDATA){ text=CDATAPrefix+text+CDATASuffix; } } this.writer.write(text); // for (int i = 0; i < length; i++) { // char c = text.charAt(i); // this.writer.write(c); // } // if (!text.startsWith(CDATAPrefix)) { // for (int i = 0; i < length; i++) { // char c = text.charAt(i); // switch (c) { // case '&': // this.writer.write(AMP); // break; // case '<': // this.writer.write(LT); // break; // case '>': // this.writer.write(GT); // break; // case '"': // this.writer.write(QUOT); // break; // case '\'': // this.writer.write(APOS); // break; // case '\r': // this.writer.write(SLASH_R); // break; // default: // this.writer.write(c); // } // } // } // // else { // for (int i = 0; i < length; i++) { // char c = text.charAt(i); // this.writer.write(c); // } // } } public void endNode() { depth--; if (tagIsEmpty) { writer.write('/'); readyForNewLine = false; finishTag(); elementStack.popSilently(); } else { finishTag(); writer.write(CLOSE); writer.write((String)elementStack.pop()); writer.write('>'); } readyForNewLine = true; if (depth == 0 ) { writer.flush(); } } private void finishTag() { if (tagInProgress) { writer.write('>'); } tagInProgress = false; if (readyForNewLine) { endOfLine(); } readyForNewLine = false; tagIsEmpty = false; } protected void endOfLine() { writer.write('\n'); for (int i = 0; i < depth; i++) { writer.write(lineIndenter); } } public void flush() { writer.flush(); } public void close() { writer.close(); } public HierarchicalStreamWriter underlyingWriter() { return this; } }
3、编写XML提交内容器
package com.c.common; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import org.apache.commons.logging.Log; import com.mport.xstream.MyXppDriver; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.mapper.MapperWrapper; /** * * @author lzq * */ public final class HttpPostXmlUtil { private static XStream xStream = null; static { if (xStream == null) { xStream = new XStream(new MyXppDriver())// ; { @Override // 告诉Xstream忽略在转换XML文档到java对象过程中XML文档多出的元素 protected MapperWrapper wrapMapper(MapperWrapper next) { return new MapperWrapper(next) { @Override public boolean shouldSerializeMember(Class definedIn, String fieldName) { if (definedIn == Object.class) { try { return this.realClass(fieldName) != null; } catch (Exception e) { return false; } } else { return super.shouldSerializeMember(definedIn, fieldName); } } }; } }; xStream.setMode(XStream.NO_REFERENCES); } } /** * 将对象转换为XML文本 * * @param obj * @return */ public static String obj2xml(Class[] types, Object obj) { xStream.processAnnotations(types); return xStream.toXML(obj); } /** * 将XML文本转换对象 * * @param xml * @return */ public static Object xml2obj(Class[] types, String xml) { xStream.processAnnotations(types); return xStream.fromXML(xml); } /** * * @param url * @param request * @param log * 日志记录对象 * @return 返回响应 */ public static String postXmlText(String url, String xmlReq, Integer timeOut, Log log) { String response = null; try { timeOut = (timeOut == null || timeOut < 1) ? 5 * 1000 : timeOut; byte[] bb = xmlReq.getBytes("UTF-8"); // 请求地址 URL targetUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) targetUrl.openConnection(); conn.setRequestMethod("POST"); conn.setConnectTimeout(timeOut);// 设置超时的时间 conn.setDoInput(true); conn.setDoOutput(true);// 如果通过post提交数据,必须设置允许对外输出数据 conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");// 必须定义为text/xml内容类型,如果定义为application/x-www-form-urlencoded、multi/form-data conn.setRequestProperty("Content-Length", String.valueOf(bb.length)); conn.connect(); OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); out.write(xmlReq); // 写入请求的字符串 out.flush(); out.close(); // 请求返回的状态 if (conn.getResponseCode() == 200) { // 请求返回的数据 BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); try { StringBuffer data = new StringBuffer(); String line = null; while ((line = br.readLine()) != null) { data.append(line + '\n'); } // 转成字符串 response = data.toString(); } catch (Exception e1) { e1.printStackTrace(); } finally { br.close(); } } else { log.error("Response Code: " + conn.getResponseCode()); } } catch (IOException e) { e.printStackTrace(); } return response; } }
d