先看段打开网页的代码:URL url=new URL("http://souljava.blog.163.com/");
URLConnection connection=url.openConnection();
connection.getInputStream();
问题1:客户端浏览器怎么判断接受到的是什么数据类型?
回答:java的附带浏览器JEditorPane会按以下方式,依次判断
URLConnectiongetContentType()
根据 URL 的指定 "file" 部分尝试确定对象的内容类型。
根据输入流的开始字符尝试确定输入流的类型。
问题2:如果传送的数据类型不在(RFC) 中怎么办?
回答:自定义协议处理框架
贴几个关键的类:
*abstract classURLConnection
表示客户程序与远程服务器的连接。 客户程序可以从URLConnection获得输入输出流
推荐覆盖:
StringgetContentType()从URL 判断返回何种MIME
abstract voidconnect()解析URL ,由自己实现的超类建立soket连接
getInputStream()从soket连接中,获取输入流
*public abstract classURLStreamHandler
协议处理器,主要负责创建与协议相关的URLConnection对象.
推荐覆盖:
protected abstractopenConnection(URLu)
URLStreamHandler 对象被重载URLStreamHandlerFactory的createURLStreamHandler(Stringprotocol)
*abstract classContentHandler
内容处理器,负责解析服务器发送的数据,然后转换成 合适的java 数据结构
推荐覆盖:
依次遍历classes中的元素如果匹配就返回
ContentHandler 由ContentHandlerFactory 创建
需要覆盖:createContentHandler(Stringmimetype) 判断产生何种ContentHandler
自定义协议处理框架
自定义的echo协议import java.net.*;
import java.io.*;
import echo.*;
public class EchoClient{
public static void main(String args[])throws IOException{
//设置URLStreamHandlerFactory
URL.setURLStreamHandlerFactory(new EchoURLStreamHandlerFactory());
//设置ContentHandlerFactory
URLConnection.setContentHandlerFactory(new EchoContentHandlerFactory());
URL url=new URL("echo://localhost:8000");
EchoURLConnection connection=(EchoURLConnection)url.openConnection();
connection.setDoOutput(true);
PrintWriter pw=new PrintWriter(connection.getOutputStream(),true);
while(true){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String msg=br.readLine();
pw.println(msg); //向服务器发送消息
String echoMsg=(String)connection.getContent(); //读取服务器返回的消息
System.out.println(echoMsg);
if(echoMsg.equals("echo:bye")){
connection.disconnect(); //断开连接
break;
}
}
}
}
package echo;
import java.net.*;
import java.io.*;
public class EchoContentHandler extends ContentHandler{
public Object getContent(URLConnection connection)throws IOException{
InputStream in=connection.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(in));
return br.readLine();
}
public Object getContent(URLConnection connection,Class[] classes)throws IOException{
InputStream in=connection.getInputStream();
for(int i=0;i
if(classes[i]==InputStream.class)
return in;
else if(classes[i]==String.class)
return getContent(connection);
}
return null;
}
}
package echo;
import java.net.*;
public class EchoContentHandlerFactory implements ContentHandlerFactory{
public ContentHandler createContentHandler(String mimetype){
if(mimetype.equals("text/plain")){
return new EchoContentHandler();
}else{
return null;
}
}
}
package echo;
import java.net.*;
import java.io.*;
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;
}
}
}
package echo;
import java.net.*;
import java.io.*;
public class EchoURLStreamHandlerFactory implements URLStreamHandlerFactory{
public URLStreamHandler createURLStreamHandler(String protocol){
if(protocol.equals("echo"))
return new EchoURLStreamHandler();
else
return null;
}
}