📄 ch9.htm
字号:
</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>401</CENTER></TD><TD WIDTH=240>Unauthorized</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>403</CENTER></TD><TD WIDTH=240>Forbidden</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>404</CENTER></TD><TD WIDTH=240>Not Found</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>500</CENTER></TD><TD WIDTH=240>Internal Server Error</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>501</CENTER></TD><TD WIDTH=240>Not Implemented</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>502</CENTER></TD><TD WIDTH=240>Bad Gateway</TD></TR><TR VALIGN=TOP><TD WIDTH=151><CENTER>503</CENTER></TD><TD WIDTH=240>Service Unavailable</TD></TR></TABLE></CENTER><P><P>Immediately after the response header, the requested file is sent.When the file is completely transmitted, the socket connectionis closed. Each request-response pair consumes a new socket connection.<P>That's enough information to construct a basic Web server. Fullinformation on the HTTP protocol can be retrieved from <TT>HTTP://www.w3.org/</TT>.<H3><A NAME="BasicWebServer">Basic Web Server</A></H3><P>The basic Web server will follow the construction of the SimpleWebServerfrom Listing 9.2. Many improvements will have to be made to methodand response handling. The simple server does not parse or storethe request header as it arrives. The new Web server will haveto parse and store the requests for later processing. To do this,you need a class to contain an HTTP request.<H4>HTTPrequest Class</H4><P>Listing 9.5 shows the complete HTTPrequest class. The class mustcontain all the information that could be conveyed in a requestheader.<HR><BLOCKQUOTE><B>Listing 9.5. The HTTPrequest class.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>import java.io.*;<BR>import java.util.*;<BR>import java.net.*;<BR>import NameValue;<BR><BR>/**<BR> * This class maintains all the information from an HTTP request<BR> */<BR>public class HTTPrequest<BR>{<BR> public String version;<BR> public String method;<BR> public String file;<BR> public Socket clientSocket;<BR> public DataInputStream inbound;<BR> public NameValue headerpairs[];<BR><BR> /**<BR> * Create an instance of this class<BR> */<BR> public HTTPrequest()<BR> {<BR> version = null;<BR> method = null;<BR> file = null;<BR> clientSocket =null;<BR> inbound = null;<BR> headerpairs =new NameValue[0];<BR> }<BR><BR> /**<BR> * Add a name/value pair to the internalarray<BR> */<BR> public void addNameValue(String name,String value)<BR> {<BR> try<BR> {<BR> NameValuetemp[] = new NameValue[ headerpairs.length + 1 ];<BR> System.arraycopy(headerpairs,0, temp, 0, headerpairs.length);<BR> temp[headerpairs.length ] = new NameValue(name, value);<BR> headerpairs= temp;<BR> }<BR> catch (NullPointerExceptionnpe)<BR> {<BR> System.out.println("NullPointerExceptionwhile adding name-value: " + </TT><FONT FACE="ZapfDingbats">Â</FONT><TT>npe);<BR> }<BR> }<BR><BR> /**<BR> * Renders the contents of the class inString format<BR> */<BR> public String toString()<BR> {<BR> String s = method+ " " + file + " " + version + "\n";<BR> for (int x = 0;x < headerpairs.length; x++ )<BR> s += headerpairs[x] + "\n";<BR> return s;<BR> }<BR>}</TT></BLOCKQUOTE><HR><P>The NameValue class simply stores two strings: name and value.You can find the source code for it on the CD-ROM in NameValue.java.When a new pair needs to be added, a new array is allocated. Thenew array receives a copy of the old array as well as the newmember. The old array is then replaced with the newly createdentity.<P>Two data fields in the class are not directly part of an HTTPrequest. The <TT>clientSocket</TT>member allows response routines to get an output stream, and the<TT>inbound</TT> member allows easyclosure after a request has been processed. The remaining membersare all part of an HTTP request. The method <TT>toString()</TT>allows class objects to be printed using "plus notation."The following line will display the contents of a request by invokingthe <TT>toString()</TT> method:<BLOCKQUOTE><TT>System.out.println("Request: "+ request);</TT></BLOCKQUOTE><P>Now that the request container is finished, it's time to populateit.<H4>BasicWebServer Class</H4><P>This is the main class for the server. It can be broken down intorequest and response routines. Since this is a server, the requestroutines will be activated first. After some validation, the responseroutines will be called. Listing 9.6 provides the routines toparse an HTTP request.<HR><BLOCKQUOTE><B>Listing 9.6. HTTP request routines.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT> /**<BR> * Read an HTTP request into a continuousString.<BR> * @param client a connected client streamsocket.<BR> * @return a populated HTTPrequest instance<BR> * @exception ProtocolException If nota valid HTTP header<BR> * @exception IOException<BR> */<BR> public HTTPrequest GetRequest(Socket client)<BR> throws IOException,ProtocolException<BR> {<BR> DataInputStreaminbound = null;<BR> HTTPrequest request= null;<BR> try<BR> {<BR> //Acquire an input stream for the socket<BR> inbound= new DataInputStream(client.getInputStream());<BR><BR> //Read the header into a String<BR> Stringreqhdr = readHeader(inbound);<BR><BR> //Parse the string into an HTTPrequest instance<BR> request= ParseReqHdr(reqhdr);<BR><BR> //Add the client socket and inbound stream<BR> request.clientSocket= client;<BR> request.inbound= inbound;<BR> }<BR> catch (ProtocolExceptionpe)<BR> {<BR> if( inbound != null )<BR> inbound.close();<BR> throwpe;<BR> }<BR> catch (IOExceptionioe)<BR> {<BR> if( inbound != null )<BR> inbound.close();<BR> throwioe;<BR> }<BR> return request;<BR> }<BR><BR> /**<BR> * Assemble an HTTP request header String<BR> * from the passed DataInputStream.<BR> * @param is the input stream to use<BR> * @return a continuous String representingthe header<BR> * @exception ProtocolException If a preHTTP/1.0 request<BR> * @exception IOException<BR> */<BR> private String readHeader(DataInputStreamis)<BR> throws IOException,ProtocolException<BR> {<BR> String command;<BR> String line;<BR><BR> // Get the firstrequest line<BR> if ( (command= is.readLine()) == null )<BR> command= "";<BR> command += "\n";<BR><BR> // Check for HTTP/1.0signature<BR> if (command.indexOf("HTTP/")!= -1)<BR> {<BR> //Retrieve any additional lines<BR> while((line = is.readLine()) != null && !line.equals(""))<BR> command+= line + "\n";<BR> }<BR> else<BR> {<BR> thrownew ProtocolException("Pre HTTP/1.0 request");<BR> }<BR> return command;<BR> }<BR><BR> /**<BR> * Parsed the passed request String andpopulate an HTTPrequest.<BR> * @param reqhdr the HTTP request as acontinous String<BR> * @return a populated HTTPrequest instance<BR> * @exception ProtocolException If name,valuepairs have no ':'<BR> * @exception IOException<BR> */<BR> private HTTPrequest ParseReqHdr(Stringreqhdr)<BR> throws IOException,ProtocolException<BR> {<BR> &nb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -