[ Team LiB ] Previous Section Next Section

6.11 Exercises

Exercise 6-1. The FileCopy3 program in Example 6-4 omits exception-handling and channel-closing code for simplicity. Make this program more robust by adding that code, using Example 6-2, or other examples, as a model.

Exercise 6-2. The ChannelToWriter.copy( ) method of Example 6-5 reads bytes from a ReadableByteChannel, decodes them using a CharsetDecoder, and writes the resulting characters to a Writer. Write a method that does the reverse: reads characters from a Reader, encodes them using a CharsetEncoder, and writes the resulting bytes to a WritableByteChannel. Use a low-level encoding loop based on the decoding loop of Example 6-5.

Exercise 6-3. The BGrep class of Example 6-3 is a block-oriented rather than line-oriented regular-expression matcher. Modify the program to search a line at a time, rather than searching an entire file at a time. The easiest way to do this is probably to abandon the java.nio package and use java.io.BufferedReader to read lines. An alternative is to use the scan( ) method of the ChannelTokenizer class (see Examples Example 6-8 and Example 2-8).

Exercise 6-4. The HttpGet program in Example 6-9 discards HTTP headers. Modify it with a -h command-line option, which, when present, causes it to print out the headers it receives.

Exercise 6-5. A shortcoming of the HttpGet program of Example 6-9 is that it does not understand and follow HTTP redirects. Some servers use these HTTP response codes to distribute load, and HttpGet is unable to download pages from such servers. Modify the program so that if the response code is in the 300-399 range, it parses the HTTP headers, looking for one that begins "Location:". If it finds such a header, it prints a message and attempts to fetch the URL that follows it. If you don't want to write a full-featured HTTP header parser, note that you can convert the headers to a string, and then simply use string methods to search for "\nLocation:" within that string.

Exercise 6-6. The PrintServiceWebInterface class of Example 6-13 uses the GatheringByteChannel interface to send response data from a ByteBuffer array. It divides its response up into a set of fixed headers and a variable body. In fact, however, the first part of the body is also fixed. Additionally, a more robust implementation would include a "Content-Length:" header that specifies the (variable) length, in bytes, of the body. Modify the program to address these two issues by using an array of four buffers instead of two. The first buffer would hold the fixed part of the headers. The second would hold the variable Content-Length header and the header-terminating blank line. The third buffer would hold the fixed part of the document body, and the fourth would hold the variable part of the body. This fourth buffer would be filled, and its length measured, before the second buffer was filled. If you added a "print headers" option to HttpGet in the previous exercise, you can use that modified version to test your Content-Length implementation here.

Exercise 6-7. The PrintServiceWebInterface class of Example 6-13 demonstrated a simple framework for a multiplexing server. Modify this framework to create a generic server framework, like that of Example 5-10. With the New I/O API, you should need only a single thread to do this. You'll probably want to create a per-client state object and associate it with each SelectionKey you use.

Exercise 6-8. Study the HttpDownloadManager class of Example 6-14. Analyze it for weaknesses, and remedy them. For example:

  • The DownloadImpl.addData( ) method inefficiently reallocates its array every time it is called.

  • The Listener interface provides notification only when the download completes or aborts; it does not provide the information a web browser would need to monitor the progress of a download, such as notification of connection establishment and data read.

  • It does not parse HTTP response headers, so, for example, it cannot follow redirects and cannot tell the caller how many bytes to expect based on the Content-Length headers.

    [ Team LiB ] Previous Section Next Section