最近作的一個項目,涉及到報文(XML)的加簽,驗籤.加簽前要對報文進行規範化.java
須要規範化的緣由:XML格式的報文信息,通常都要轉爲Document對象進行解析處理,而從對象中解析出的內容頗有可能與另外一方加簽時的原內容有出入.如:<Object id="001">若是另外一方加簽時,不當心多了個空格<Object id="001" >,而驗籤時從Document中解析出的內容卻沒有空格,那麼驗籤確定沒法經過的.相似此種格式還有不少,如<input/>與<input><input/>;換行符是\r\n仍是\n?這些若是不統一,加簽,驗籤是幾乎沒法成功的!spa
所以就須要有統一的標準規範!因爲規範方法有多種,實際業務中雙方要約定好規範方法!code
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import javax.xml.crypto.OctetStreamData; import javax.xml.crypto.dsig.CanonicalizationMethod; import javax.xml.crypto.dsig.TransformService; public class XmlTest { public static void main(String[] args) throws Exception { byte[] bytes = Files.readAllBytes(Paths.get("E:/HDE_W3C_Message_Sample.xml")); System.out.println(new String(bytes).replaceAll("\r\n", "★\r\n")); System.out.println("---------------------------------------------------"); TransformService ts = TransformService.getInstance(CanonicalizationMethod.INCLUSIVE, "DOM"); String result; try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes); ByteArrayOutputStream baos = new ByteArrayOutputStream()) { OctetStreamData data = new OctetStreamData(bais); OctetStreamData newData = (OctetStreamData) ts.transform(data, null); InputStream is = newData.getOctetStream(); byte[] buf = new byte[1024*1024]; int len = is.read(buf); while (len != -1) { baos.write(buf, 0, len); len = is.read(buf); } result = baos.toString(StandardCharsets.UTF_8.toString()); System.out.println(result.replace("\n", "★\r\n")); } System.out.println("---------------"); } }
上述規範進行的處理有:
1.將全部的\r\n替換爲\n;
2.替換無效的空白;如<Object id="001" >中Object與id之間的空白是有效的,而>前面的就是無效的,標籤體內容的空白也是有效的
3.標籤體爲空的統一展開爲開始和結束;如<input/>轉爲<input><input/>
orm
主要涉及到3個類
javax.xml.crypto.OctetStreamData;
javax.xml.crypto.dsig.CanonicalizationMethod;
javax.xml.crypto.dsig.TransformService;xml
javax.xml.crypto.dsig.TransformService; 是用來生成一個轉換對象
javax.xml.crypto.dsig.CanonicalizationMethod; 中定義了多個規範化標準方法,都是以URI的方式展示
javax.xml.crypto.OctetStreamData; 存放須要轉換的XML內容對象
CanonicalizationMethod 中的規範化方法有如下幾種:get
final static String INCLUSIVE = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"; final static String INCLUSIVE_WITH_COMMENTS = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"; final static String EXCLUSIVE = "http://www.w3.org/2001/10/xml-exc-c14n#"; final static String EXCLUSIVE_WITH_COMMENTS = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments";