Make writing a habit together! This is the 15th day of my participation in the “Gold Digging Day New Plan · April More text Challenge”. Click here for more details.

Introduction to the

Before JSON, XML was the most commonly used data transmission format. Although XML has a bit more redundant data, XML structure is simple and clear, which is still used in different places in the program. For Netty, it also provides support for XML data naturally.

Netty supports XML in two ways. The first is frame splitting of encoded XML data, with each frame containing a complete XML. On the other hand, the segmented frame is used for semantic parsing of XML.

You can use XmlFrameDecoder for frame splitting and XmlDecoder for parsing the content of AN XML file. We’ll cover two decoder implementations and use them in detail.

XmlFrameDecoder

Since we are receiving a stream of data, we are not sure what the data will look like. A normal XML data might be split into multiple data frames.

As follows:

   +-------+-----+--------------+
   | <this | IsA | XMLElement/> |
   +-------+-----+--------------+
Copy the code

This is normal XML data, but split into three frames, so we need to merge it into one frame as follows:

   +-----------------+
   | <thisIsAXMLElement/> |
   +-----------------+

Copy the code

It is also possible for different XML data to be split into multiple frames, as follows:

   +-----+-----+-----------+-----+----------------------------------+
   | <an | Xml | Element/> | <ro | ot><child>content</child></root> |
   +-----+-----+-----------+-----+----------------------------------+
Copy the code

The data above needs to be split into two frames:

   +-----------------+-------------------------------------+
   | <anXmlElement/> | <root><child>content</child></root> |
   +-----------------+-------------------------------------+
Copy the code

The logic of splitting is simple, and basically determines whether XML starts or ends by determining the location of the XML delimiter. The delimiters in XML are ‘<‘, ‘>’, and ‘/’.

These are the only three delimiters you need to judge in the decode method.

There is additional logic to determine, for example, whether the XML start character is valid:

private static boolean isValidStartCharForXmlElement(final byte b) { return b >= 'a' && b <= 'z' || b >= 'A' && b <= 'Z'  || b == ':' || b == '_'; }Copy the code

Comment or not:

    private static boolean isCommentBlockStart(final ByteBuf in, final int i) {
        return i < in.writerIndex() - 3
                && in.getByte(i + 2) == '-'
                && in.getByte(i + 3) == '-';
    }

Copy the code

CDATA data:

private static boolean isCDATABlockStart(final ByteBuf in, final int i) { return i < in.writerIndex() - 8 && in.getByte(i + 2) == '[' && in.getByte(i + 3) == 'C' && in.getByte(i +  4) == 'D' && in.getByte(i + 5) == 'A' && in.getByte(i + 6) == 'T' && in.getByte(i + 7) == 'A' && in.getByte(i + 8) == '[';Copy the code

After determining the starting location of the XML data using these methods, the extractFrame method is called to use ByteBuf to copy the original data and finally put it in out:

final ByteBuf frame = extractFrame(in, readerIndex + leadingWhiteSpaceCount, xmlElementLength - leadingWhiteSpaceCount);  in.skipBytes(xmlElementLength); out.add(frame);Copy the code

XmlDecoder

After splitting the XML data into frames, it’s time to parse the specific data in the XML.

Netty provides an XML data parsing method called XmlDecoder. It is mainly used to parse a frame that is already a single XML data. It is defined as follows:

public class XmlDecoder extends ByteToMessageDecoder 
Copy the code

XmlDecoder based on the XML content it reads, Parts of the XML into XmlElementStart XmlAttribute, XmlNamespace, XmlElementEnd, XmlProcessingInstruction, XmlCharacters, XmlComment, XmlS Pace, XmlDocumentStart XmlEntityReference XmlDTD and XmlCdata.

This data basically covers all possible elements in XML.

All these elements are defined in the io.net ty. The handler. Codec. The XML in the package.

But XmlDecoder reads and parses XML using a third-party XML toolkit: FasterXML.

XmlDecoder uses fasterXML AsyncXMLStreamReader and AsyncByteArrayFeeder for parsing XML data.

These two attributes are defined as follows:

    private static final AsyncXMLInputFactory XML_INPUT_FACTORY = new InputFactoryImpl();
    private final AsyncXMLStreamReader<AsyncByteArrayFeeder> streamReader;
    private final AsyncByteArrayFeeder streamFeeder;

            this.streamReader = XML_INPUT_FACTORY.createAsyncForByteArray();
        this.streamFeeder = (AsyncByteArrayFeeder)this.streamReader.getInputFeeder();
Copy the code

Decode’s logic is to read different data separately by determining the type of XML element, and finally encapsulate the read data into the various XML objects mentioned above. Finally, the XML objects are added to the Out list and returned.

conclusion

We can use XmlFrameDecoder and XmlDecoder to parse XML data in a very convenient way. Netty has built the wheels for us so we don’t have to invent them.

This article is available at www.flydean.com/14-7-netty-…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many tips you didn’t know waiting for you to discover!

Welcome to pay attention to my public number: “procedures those things”, understand technology, more understand you!