最近使用HttpClient,和Java的java.net.URL,url有中文都会失败。
听徐师兄说HttpClient有URI这个类可以使用:
URI uri = new URI(url,false,"UTF-8");
String url = uri.toString();
例如,发送一个get请求获得一个带有中文链接的图片:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.GetMethod;
/**
* @author fuliang
*/
public class Test {
public static void main(String[] args) throws HttpException, IOException {
String url = "http://www.byecity.com/photoocean/photo/全球图片/亚洲/柬埔寨/s/7723132569.jpg";
GetMethod get = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
URI uri = new URI(url,false,"UTF-8");
HttpClient hc = new HttpClient();
get = new GetMethod(uri.toString());
int status = hc.executeMethod(get);
if (status == 200) {
bis = new BufferedInputStream(get
.getResponseBodyAsStream());
bos = new BufferedOutputStream(
new FileOutputStream("/home/fuliang/photo.jpg"));
byte[] buffer = new byte[1024];
int len = 0;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
}
} finally {
if(get != null){
get.releaseConnection();
}
if(bis != null){
bis.close();
}
if(bos != null){
bos.close();
}
}
}
}
如果使用java.net.URL而不想引入httpclient的包,我写了一个方法可以基本解决中文url的问题,对非ascii码进行encoding(健壮性肯定没有httpclient那个好,也可以直接把httpclient中的那个源码摘出来用):
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class URLUtil {
public static String encodeURL(String url,String encode)
throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
StringBuilder noAsciiPart = new StringBuilder();
for (int i = 0; i < url.length(); i++) {
char c = url.charAt(i);
if (c > 255) {
noAsciiPart.append(c);
} else {
if (noAsciiPart.length() != 0) {
sb.append(URLEncoder.encode(noAsciiPart.toString(),encode));
noAsciiPart.delete(0, noAsciiPart.length());
}
sb.append(c);
}
}
return sb.toString();
}
}
举一个同样使用java.net.URL下载的例子:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import org.apache.log4j.Logger;
public class Downloader {
private static Logger logger = Logger.getLogger(Downloader.class);
public static boolean download(String urlString, String savePath) {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
urlString = URLUtil.encodeURL(urlString,"UTF-8");
bis = new BufferedInputStream(
getDownloadInputStream(urlString));
bos = new BufferedOutputStream(new FileOutputStream(savePath));
byte[] buffer = new byte[2048];
int len;
while ((len = bis.read(buffer,0,buffer.length)) != -1) {
bos.write(buffer, 0, len);
}
} catch (MalformedURLException e) {
logger.error("Error url: " + urlString, e);
return false;
} catch (IOException e) {
logger.error("Get connection " + urlString + "failed",
e);
return false;
} finally {
try {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
} catch (IOException e) {
logger.error("close failed", e);
return false;
}
}
return true;
}
private static InputStream getDownloadInputStream(String urlString)
throws IOException {
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
return inputStream;
}
public static OutputStream getSavaOutputStream(String path)
throws FileNotFoundException {
OutputStream fileOutputStream = new FileOutputStream(path);
return fileOutputStream;
}
public static void main(String[] args) {
download("http://www.byecity.com/photoocean/photo/全球图片/欧洲/希腊/s/76291161.jpg","/home/fuliang/test.jpg");
}
}