君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

转载 http://souljava.blog.163.com/blog/static/255571212007111693218434/  

先看段打开网页的代码:

URL url=new URL("http://souljava.blog.163.com/");

URLConnection connection=url.openConnection();

connection.getInputStream();

问题1:客户端浏览器怎么判断接受到的是什么数据类型?

回答:java的附带浏览器 JEditorPane 会按以下方式,依次判断

URLConnection getContentType() 

URLConnection guessContentTypeFromName(String fname) 

    根据 URL 的指定 "file" 部分尝试确定对象的内容类型。

URLConnection guessContentTypeFromStream(InputStream is) 

   根据输入流的开始字符尝试确定输入流的类型。

问题2:如果传送的数据类型不在(RFC) 中怎么办?

回答:自定义协议处理框架

贴几个关键的类:

*abstract class URLConnection

表示客户程序与远程服务器的连接。 客户程序可以从 URLConnection 获得输入输出流

推荐覆盖:

String getContentType() 从URL 判断返回何种MIME

abstract  void connect() 解析URL ,由自己实现的超类建立soket连接

getInputStream()   从soket连接中,获取输入流

getOutputStream()  同上

*public abstract class URLStreamHandler

协议处理器, 主要负责创建与协议相关的 URLConnection 对象.

推荐覆盖:

protected abstract  openConnection(URL u) 

 URLStreamHandler 对象被重载URLStreamHandlerFactory 的 createURLStreamHandler(String protocol) 

*abstract class ContentHandler

内容处理器,负责解析服务器发送的数据,然后转换成 合适的java 数据结构

推荐覆盖:

getContent(URLConnection urlc) 

getContent(URLConnection urlc, Class[] classes) 

依次遍历classes 中的元素如果匹配就返回

ContentHandler 由ContentHandlerFactory 创建

需要覆盖:createContentHandler(String mimetype) 判断产生何种 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<classes.length;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;

  }

}

posted on 2012-10-17 23:47  刺猬的温驯  阅读(1981)  评论(1编辑  收藏  举报