解决xml解析中报文格式和encoding不一致的解析错误

1.错误现象

我遇到过这样的xml文件,用c++解析的时候,报如下的错误:

Fatal Error at file "d:/test2.xml", line 1, column 40
   Message: An exception occurred! Type:UTFDataFormatException, Message:invalid byte 2 (? of a 2-byte sequence.

用java解析这个文件的时候,报如下错误

Invalid byte 1 of 1-byte UTF-8 sequence.
java.io.UTFDataFormatException: Invalid byte 1 of 1-byte UTF-8 sequence.
 at org.apache.xerces.impl.io.UTF8Reader.invalidByte(Unknown Source)
 at org.apache.xerces.impl.io.UTF8Reader.read(Unknown Source)
 at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)
 at org.apache.xerces.impl.XMLEntityScanner.skipChar(Unknown Source)
 at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
 at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
 at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
 at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
 at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
 at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
 at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
 at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)

 

2.程序内容

java程序内容如下:

c++程序用到了xerces-c,代码段如下:

 

3.原因分析

文件test2.xml内容如下:

我把这个文件放在本地,用ie打开该文件,解析有问题,不能正常显示。

修改encoding="gbk",然后说用ie打开,就没有问题了。

再次运行java程序和c++程序,正常运行,没有报告错。

说明文件格式有问题,最简单的解决办法就是修改文件的encoding段。

但是有些时候这样做起来可操作性能不强。

我遇到的问题是,别人发给我一个错误的文件,我打电话给对方,告诉他,文件格式有问题,对方不承认,还说别的厂商为什么没有找他,“晕”,死活不修改,而且程序一直会自动运行,手工去修改显然不显示,用脚本修改文件的额内容也不好。

 

放心,程序是“万能”的,平时遇到的所谓bug,看似不可能的问题,认真分析之后,都能通过程序来解决问题。

 

4.分析、解决问题

既然xml文件的内容没有被编码为encoding指定的内容,我们可以把文件的内容读出来,然后在进行编码,将编码后的内容进行解析,问题就解决了。

再不修改文件内容的情况下,修改java程序,内容如下:

运行正确,成功打印出根节点名字。

程序先将文件的内容读出,然后转换成utf-8的编码,组装成一个字符流进行解析。

 

c++程序也是一样,先读出文件内容,然后用icu转换成utf-8编码,组装成内容结构进行解析。

c++程序段内容如下:

上面用到了一些icu的函数,没有用过icu的兄弟,可以查看一下这方面的资料。

 

 

 

对于 HTTP POST 请求,其请求报文包体可能包含请求参数、JSON 数据、XML 数据等多种类型。在 Java 解析 HTTP POST 请求报文包体的方法也因此而异,下面将分别介绍不同类型请求体的解析方法。 1. 请求参数类型 对于请求参数类型的请求体,可以通过 HttpServletRequest 对象的 getParameter() 方法获取请求参数。在使用该方法之前,需要先设置请求体的字符编码为 UTF-8,否则可能会出现文乱码的情况。 ```java request.setCharacterEncoding("UTF-8"); String param1 = request.getParameter("param1"); String param2 = request.getParameter("param2"); // ... ``` 2. JSON 数据类型 对于 JSON 数据类型的请求体,可以使用 Gson 库将 JSON 数据转化为 Java 对象。在使用 Gson 之前需要先引入该库,可以通过 Maven 或 Gradle 等方式进行引入。 ```java Gson gson = new Gson(); MyObject myObject = gson.fromJson(request.getReader(), MyObject.class); // ... ``` 其,MyObject 是一个 Java 类,用于表示 JSON 数据。 3. XML 数据类型 对于 XML 数据类型的请求体,可以使用 Java 自带的 SAX 或 DOM 解析器进行解析。以 SAX 解析器为例,其解析过程如下: ```java SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); MyHandler handler = new MyHandler(); parser.parse(request.getInputStream(), handler); MyObject myObject = handler.getMyObject(); // ... ``` 其,MyHandler 是一个实现了 SAXHandler 接口的 Java 类,用于解析 XML 数据,并将解析结果封装在 MyObject 对象。 需要注意的是,在使用 SAX 或 DOM 解析解析 XML 数据时,需要先对 XML 数据进行格式化,以便于解析器能够正确解析。 ```java TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); StreamResult result = new StreamResult(new StringWriter()); DOMSource source = new DOMSource(document); transformer.transform(source, result); String xmlString = result.getWriter().toString(); ``` 在以上代码,我们使用 DOM 解析器将 XML 数据转化为 Document 对象,并将其格式化为字符串形式。 以上就是 Java 解析 HTTP POST 请求报文包体的基本方法,需要根据不同的请求体类型进行相应的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值