Chinese processing of Tomcat (2):
The last article introduced how Tomcat coded for receiving characters, now let's see what happened when writing HTML documents to the client?
When TOMCATE writes the data to the client, TOMCATE is implemented by the output stream of Response. But how JSP uses the stream of Response?
When using the Object OUT output in JSP, OUT is an object instance of a JSPWriter implementation class, JSpWriterImpl (ServletResponse response, int SZ, Boolean Autoflush) is a constructor of this class, which uses Response, and within JSPWriterImpl A reference to a java.io.writer object instance, when writing data using JSPWriter (JSP's OUT object), the following functions are called to initialize
protected void initout () THROWS IOException
{
IF (out == NULL)
{
OUT = response.getwriter (); / Initializes java.io.writer object
}
} To initialize the internal object.
Then in the implementation of the functions of the respective output data of JSPWriter is the method of calling the top Java.io.writer object.
Therefore, whether it is JSP or servlet, when writing HTML, it is through Response.GetWriter (); 2-en-stream is obtained by getOutputStream ().
A response exists a character stream, there is also a 2-en-stream, but only one stream can be opened at the same time. As for the relationship between the two, we introduced it later. JSP's OUT object is the character stream of Response.
The same REQUEST also exists a character stream and a 2-enveloped stream, but only one stream can be opened at the same time.
The relationship between the two streams of Response
Let's examine the achievement of getOutputStream () and getWriter functions for the achievement of Response's implementation:
Public servletOutputStream GetputStream () THROWS IOException
{
. . . . . . . . . . . . . . . . . . . . .
stream = createoutputStream (); // / Create a 2-way output stream of Response
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Return stream;
}
Public PrintWriter getWriter () THROWS IOEXCEPTION
{
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ResponseStream newstream = (responsestream) createoutputStream (); create 2-enveloped stream
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
OutputStreamWriter OSR = New OutputStreamWriter (Newstream, getcharacterencoding ());
Writer = new responseWriter (OSR, NewStream); // gets Response character output stream
. . . . . . . . . . . . . . . . . . . . . . . . . .
}
}
Obviously, our character stream is from 2-en-stream conversion.
There are two functions to pay attention to:
Public String getCharacterencoding () // Response encoding, default is ISO-8859-1
{
IF (Encoding == NULL) // If no code is specified {
RETURN "ISO-8859-1";
Else
{
Return encoding;
}
}
Public void setContentType (String Type); Set the type and encoding of Response
{
. . . . . . . . . . . . .
Encoding = Requestutil.ParsechacTerencoding (TYPE); get the specified encoding
IF (Encoding == Null)
{
Encoding = "ISO-8859-1"; // If no code is specified
}
Else
IF (Encoding! = NULL)
{
ContentType = Type "; charset =" encoding;
}
}
Ok, now we know the character stream of Response when writing characters (regardless of JSP or servlet), that is, OutputStreamWriter OSR = New OutputStreamWriter (NewStream, getcharacterencoding ());
Note that NEWSTREAM is the implementation of the 2 into the RESPONSE.
So we have to see the implementation of OutputStreamWriter:
Investigate the source code of OutputStreamWriter, he has a streamencoder type object, which relies on him to convert the encoding;
StreamEncoder is provided by Sun, it has one
Public Static StreamWriter foroutputStreamWriter (Object Obj, String S) is available to the STREAMENCODER object instance.
For JSP, servlet is constructed when it is constructed when the OutputStream parameter is the 2-way flow of Response, OBJ is OutputStreamWriter object, and s is the name of the encoding method. In fact, it is an example of a Sub-class of a streamencoder.
Return New Charsetse (OutputStream, Obj, Charset.Forname (S1)); CharsetSe is a subclass of StreamEncoder.
He has a function to achieve encoding conversion:
Void Implwrite (CHAR AC [], INT I, INT J) THROWS IOEXCEPTION / / / AC is a char group to output string
{
Charbuffer Charbuffer = Charbuffer.Wrap (AC, I, J);
. . . . . . . . . . . . . . . . . . . . . . .
CODERRESULT CODERRESULT = Encoder.Encode (charbuffer, bb, false); / bb is Bytebuffer, stored after encoding BYTE buffer
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Writebytes (); // / transform BB to the BYTE array writes into the 2-way flow to Response
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
}
At this point, we understand the encoding conversion process behind Tomcat.