转载 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; } } |