Content接口有两个实现类:StringContent和FileContent。StringContent表示字符串形式的正文,FileContent表示文件形式的正文。例如在RequestHandler类的build()方法中,如果HTTP请求发式不是GET和HEAD,就创建一个包含StringContent的Response对象,否则就创建一个包含FileContent的Response对象。
private void build() throws IOException {
Request.Action action = request.action();
//仅仅支持GET和HEAD请求方式
if ((action != Request.Action.GET) &&
(action != Request.Action.HEAD)){
response = new Response(Response.Code.METHOD_NOT_ALLOWED,
new StringContent("Method Not Allowed"));
}else{
response = new Response(Response.Code.OK,
new FileContent(request.uri()), action);
}
}
下面主要介绍FileContent类的实现。FileContent类有一个成员变量fileChannel,它表示读文件的通道。FileContent类的send()方法把fileChannel中的数据发送到ChannelIO的SocketChannel中,如果文件中的所有数据发送完毕,send()方法就返回false。例程8是FileContent类的源程序:
//例程8 FileContent.java
//此处省略import语句
public class FileContent implements Content {
//假定文件的根目录为"root",该目录应该位于classpath下
private static File ROOT = new File("root");
private File file;
public FileContent(URI uri) {
file = new File(ROOT,
uri.getPath()
.replace('/',File.separatorChar));
}
private String type = null;
/* 确定文件类型 */
public String type() {
if (type != null) return type;
String nm = file.getName();
if (nm.endsWith(".html")|| nm.endsWith(".htm"))
type = "text/html; charset=iso-8859-1"; //HTML网页
else if ((nm.indexOf('.') < 0) || nm.endsWith(".txt"))
type = "text/plain; charset=iso-8859-1"; //文本文件
else
type = "application/octet-stream"; //应用程序
return type;
}
private FileChannel fileChannel = null;
private long length = -1; //文件长度
private long position = -1; //文件的当前位置
public long length() {
return length;
}
|