浏览 6504 次
锁定老帖子 主题:如何确定HTTP请求报头的字符编码?
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-04-14
引用 http://202.113.18.30:8003/mp3/流行歌曲/beyond/请将手放开/请将手放开.mp3
为了能够实现分块下载,我要先得到文件的相关信息,比如文件的大小,以及这个URL的服务器支持的HTTP协议的版本。 因此我先向服务器发送一个HEAD请求,其请求行应该是这样: 引用 HEAD /mp3/流行歌曲/beyond/请将手放开/请将手放开.mp3 HTTP/1.1 现在的问题是,Request-URI(/mp3/流行歌曲/beyond/请将手放开/请将手放开.mp3 )中含有中文字符,因此发送的时候需要用适当的字符编码将它编码为字节流。那么我怎样才能得到这个字符编码的信息呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-04-14
附:我现在的实现代码
private static DataInfo getDataInfo(URL addr)throws IOException{ String host =addr.getHost(); String file =addr.getFile(); int port =addr.getPort(); if(port==-1) port =80; Socket s =new Socket(host,port); PrintStream out =new PrintStream(s.getOutputStream(),false,"gb2312"); BufferedReader in =new BufferedReader( new InputStreamReader(s.getInputStream(),"gb2312")); out.print("HEAD "+file+" HTTP/1.1\r\n"); out.print("Host: "+host+":"+port+"\r\n"); out.print("Accept: */*\r\n"); out.print("Referer: "+addr+"\r\n"); out.print("User-Agent: Mozilla/4.0 (compatible; MSIE 5.00; Windows 98)\r\n"); out.print("\r\n"); out.flush(); String str; while((str=in.readLine())!=null){ //解析信息 } out.close(); in.close(); ... } |
|
返回顶楼 | |
发表时间:2007-04-14
http header一般都是iso8859-1的,除非给服务器配置时做特殊的设定
|
|
返回顶楼 | |
发表时间:2007-04-15
试试这个:
out.print("HEAD "+URLEncode.encode(file)+" HTTP/1.1\r\n"); |
|
返回顶楼 | |
发表时间:2007-04-16
谢谢楼上两位的回答~
out.print("HEAD "+URLEncode.encode(file)+" HTTP/1.1\r\n"); 这种方法事实上用了平台默认的编码(在我的电脑上是GBK)来进行URL编码 |
|
返回顶楼 | |
发表时间:2007-04-16
Eastsun 写道 谢谢楼上两位的回答~
out.print("HEAD "+URLEncode.encode(file)+" HTTP/1.1\r\n"); 这种方法事实上用了平台默认的编码(在我的电脑上是GBK)来进行URL编码 那你试试这个? public static String encode(String s,String enc) throws UnsupportedEncodingException |
|
返回顶楼 | |
发表时间:2007-04-16
我现在的问题关键是怎么确定这个字符编码enc
注意我想知道的是请求报头的编码,而不是传输内容的字符编码~ |
|
返回顶楼 | |
发表时间:2007-04-16
经过我初步对JDK中源代码的研究,这个编码貌似是由
System.getProperty("file.encoding", "ISO8859_1"); 确定的。 我查找的路线: java.net.URL中的HTTP协议是由sun.net.www.protocol.http.Handler实现的: package sun.net.www.protocol.http; import java.io.IOException; import java.net.URL; import java.net.Proxy; /** open an http input stream given a URL */ public class Handler extends java.net.URLStreamHandler { protected String proxy; protected int proxyPort; protected int getDefaultPort() { return 80; } public Handler () { proxy = null; proxyPort = -1; } public Handler (String proxy, int port) { this.proxy = proxy; this.proxyPort = port; } protected java.net.URLConnection openConnection(URL u) throws IOException { return openConnection(u, (Proxy)null); } protected java.net.URLConnection openConnection(URL u, Proxy p) throws IOException { return new HttpURLConnection(u, p, this); } } 而这个sun.net.www.protocol.http.HttpURLConnection有代码: private void writeRequests() throws IOException { ... http.writeRequests(requests, poster); ... } 其中的http是个sun.net.www.http.HttpClient类: //HttpClient的writeRequests方法 public void writeRequests(MessageHeader head, PosterOutputStream pos) throws IOException { requests = head; requests.print(serverOutput); poster = pos; if (poster != null) poster.writeTo(serverOutput); serverOutput.flush(); } 其中requests.print方法的代码是: public synchronized void print(PrintStream p) { for (int i = 0; i < nkeys; i++) if (keys[i] != null) { p.print(keys[i] + (values[i] != null ? ": "+values[i]: "") + "\r\n"); } p.print("\r\n"); p.flush(); } serverOutput的代码是: public void openServer(String server, int port) throws IOException { serverSocket = doConnect(server, port); try { serverOutput = new PrintStream( new BufferedOutputStream(serverSocket.getOutputStream()), false, encoding); } catch (UnsupportedEncodingException e) { throw new InternalError(encoding+" encoding not found"); } serverSocket.setTcpNoDelay(true); } 而其中encoding是由HttpClient的父类NetworkClient决定的: protected static String encoding; static { final int vals[] = {0, 0}; final String encs[] = { null }; AccessController.doPrivileged( new PrivilegedAction() { public Object run() { vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue(); vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue(); encs[0] = System.getProperty("file.encoding", "ISO8859_1"); return null; } }); if (vals[0] == 0) defaultSoTimeout = -1; else defaultSoTimeout = vals[0]; if (vals[1] == 0) defaultConnectTimeout = -1; else defaultConnectTimeout = vals[1]; [color=red]encoding = encs[0];[/color] try { if (!isASCIISuperset (encoding)) { encoding = "ISO8859_1"; } } catch (Exception e) { encoding = "ISO8859_1"; } } |
|
返回顶楼 | |