ead(buff)) != -1) {
buffer.write(buff, 0, len);
}
//把字节数组转换为字符串
System.out.println(new String(buffer.toByteArray()));
}
}
实现协议处理框架
本节将为用户自定义的 ECHO 协议实现处理框架,共创建了以下类:
- EchoURLConnection 类:继承自 URLConnection 类
- EchoURLStreamHandler 类:继承自 URLStreamHandler 类
- EchoURLStreamHandlerFactory 类:实现 URLStreamHandlerFactory 接口
- EchoContentHandler 类:继承自 ContentHandler 类
- EchoContentHandlerFactory 类:实现 ContentHandlerFactory 接口
1. 创建 EchoURLConnection 类
EchoURLConnection 类封装了一个 Socket,在 connect() 方法中创建与远程服务器连接的 Socket 对象
public class EchoURLConnection extends URLConnection {
private Socket connection = null;
public final static int DEFAULT PORT = 8000;
public EchoURLConnection(URL url) {
super(url);
}
public synchronized InputStream getInputStream() throws IOException {
if(!connected) connect();
return connection.getInputStream();
}
public synchronized OutputStream getOutputStream() throws IOException {
if(!connected) connect();
return connection.getOutputStream();
}
public String getContentType() {
return "text/plain";
}
public synchronized void connect() throws IOException {
if(!connected) {
int port = url.getPort();
if(port < 0 || port > 65535) port = DEFAULT_PORT;
this.connection = new Socket(url.getHost(), port);
this.connected = true;
}
}
public synchronized void disconnect() throws IOException {
if(connected) {
//断开连接
this.connection.close();
this.connected = false;
}
}
}
2. 创建 EchoURLStreamHandler 及工厂类
EchoURLStreamHandler 类的 openConnection()
方法负责创建一个 EchoURLConnection 对象
public class EchoURLStreamHandler extends URLStreamHandler {
public int getDefaultPort() {
return 8000;
}
protected URLConnection openConnection(URL url) throws IOException {
return new EchoURLConnection(url);
}
}
EchoURLStreamHandlerFactory 类的 createURLStreamHandle()
方法负责构造 EchoURLStreamHandler 实例
public class EchoURLStreamHandlerFactory implements URLStreamhandlerFactory {
public URLStreamHandler createURLStreamHandler(String protocol) {
if(protocol.equals("echo"))
return new EchoURLStreamHandler();
else
return null;
}
}
在客户程序中,可以通过以下方式设置 EchoURLStreamHandlerFactory
URL.setURLStreamHandlerFactory(new EchoURLStreamHandlerFactory());
URL url=new URL("echo://localhost:8000");
3. 创建 EchoContentHandler 类及工厂类
URLConnection 类还提供了 getContent()
方法,它有两种重载形式:
public Object getContent();
public Object getContent(Class[] classes);
第二个 getContent() 方法把服务器发送的数据优先转换为 classes 数组第一个元素指定的类型,如果转换失败,再尝试转换第二个元素指定的类型,以此类推
下例 HttpClient 演示处理服务器发送的数据
public class HttpClient {
public static void main(String args[]) throws IOException {
URL url = new URL("http://www,javathinker.net/hello.htm");
URlConnection connection = url.openConnection();
//接收响应结果
InputStream in = connection.getInputStream();
Class[] types = {String.class, InputStream.class};
Object obj = connection.getContent(types);
if(obj instanceof String) {
System.out.println(obj);
} else if(obj instanceof InputStream) {
in = (InputStream) obj;
FileOutputStream file = new FileOutputStream("data");
byte[] buff = new byte[1024];
int len = -l;
while((len = in.read(buff)) != -1) {
file.write(buff, 0 ,len);
}
System.out.println("正文保存完毕");
} else {
System.out.println("未知的响应正文类型");
}
}
}