Java获取从重定向的';友好的';网址

Java获取从重定向的';友好的';网址,java,redirect,download,url-routing,nio,Java,Redirect,Download,Url Routing,Nio,我正在尝试从给定的URL下载一个文件,该URL可能是该文件的直接链接,也可能不是该文件的直接链接。是否有人知道如果URL是间接链接(即)我如何检测要写入的文件名? 如果URL是从URL中提取文件名并开始写入提取的文件名的直接链接,则没有问题,但使用重定向链接,我找到的唯一方法是写入任意文件名foo.txt,然后尝试使用该文件名。问题是我真的需要正确的文件名(和扩展名)。 我正在使用的代码示例是:(else子句中的部分既没有完成也没有工作): publicstaticbooleandlfile(s

我正在尝试从给定的URL下载一个文件,该URL可能是该文件的直接链接,也可能不是该文件的直接链接。是否有人知道如果URL是间接链接(即)我如何检测要写入的文件名? 如果URL是从URL中提取文件名并开始写入提取的文件名的直接链接,则没有问题,但使用重定向链接,我找到的唯一方法是写入任意文件名foo.txt,然后尝试使用该文件名。问题是我真的需要正确的文件名(和扩展名)。 我正在使用的代码示例是:(else子句中的部分既没有完成也没有工作):

publicstaticbooleandlfile(stringurl,stringdest){
试一试{
URL抓取=新URL(URL);
ReadableByteChannel rbc=Channels.newChannel(grab.openStream());
字符串fnRE=“.*/([a-zA-Z0-9\\-\\.\\.+)$”;
Pattern=Pattern.compile(fnRE);
Matcher Matcher=pattern.Matcher(URL);
字符串fName=“”;
如果(matcher.find())fName=matcher.group(1);
否则{//filename无法提取-请在此处执行操作-下面的操作不起作用引发格式错误
URL foo=新URL(URL);
HttpURLConnection fooConnection=(HttpURLConnection)foo.openConnection();
URL secondFoo=新URL(fooConnection.getHeaderField(“位置”);
System.out.println(“重定向URL:+secondFoo”);
fooConnection.setInstanceFollowDirections(false);
URLConnection fooURL=secondFoo.openConnection();
}
System.out.println(“连接到“+URL+”已建立!”);
if(dest.endsWith(“/”){}
else dest+=“/”;
System.out.println(“将“+fName+”写入“+dest”);
FileOutputStream fos=新的FileOutputStream(dest+fName);

fos.getChannel().transferFrom(rbc,0,1No,通常不包含该信息。响应通常不包含该信息,因为您不向数据流添加任何自己的协议信息(以防您可以控制服务器)


无论如何,您需要文件扩展名。可能使用正确的扩展名,您就完成了。

假设响应有一个“Location”头字段,我能够获得指向包含多个重定向的url的直接链接,如下所示:

String location = "http://www.example.com/download.php?getFile=1";
HttpURLConnection connection = null;
for (;;) {
    URL url = new URL(location);
    connection = (HttpURLConnection) url.openConnection();
    connection.setInstanceFollowRedirects(false);
    String redirectLocation = connection.getHeaderField("Location");
    if (redirectLocation == null) break;
    location = redirectLocation;
}
//and finally:
String fileName = location.substring(location.lastIndexOf('/') + 1, location.length());

我认为最好使用Java库,然后使用以下方法:

public static void downloadFileJsoup(String URL, String PATH) throws IOException {
    Response res = Jsoup.connect(URL)
            .userAgent("Mozilla")
            .timeout(30000)
            .followRedirects(true)
            .ignoreContentType(true)
            .maxBodySize(20000000)//Increase value if download is more than 20MB
            .execute(); 
    String remoteFilename=res.header("Content-Disposition").replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1");
    String filename = PATH + remoteFilename;
    FileOutputStream out = (new FileOutputStream(new java.io.File(filename)));
    out.write( res.bodyAsBytes());
    out.close();
}

一般来说不是这样,但是如果响应有
内容处置:附件;filename=myfile.zip
头,您可以从中提取文件名。@IanRoberts-是的,我认为这是正确的,但不幸的是没有返回内容处置头,我可以通过跟踪URL获得的所有头都告诉我它的php/html等。在不知道要写入的文件名的情况下,是否无法下载文件?是否无法说“下载到默认文件名”或类似的话?这似乎很疯狂,因为它在其他语言中很容易实现,但我需要在java.boo中完成这项工作:-(不,这是HTTP工作,与Java无关。如果服务器不提供该信息(内容配置),您可以将字节读入缓冲区。某些文件格式包含自己的原始文件名(特别是开放格式).你好,是的,你说得对。我刚刚看了一个python脚本,我写了一个python脚本来做同样的事情,它只能通过读取标题中的内容配置来工作。我假设,当我将url与urllib2连接时,它必须在返回标题之前遵循重定向,因为它提供了与我从java获得的完全不同的标题。我很抱歉e我已经读过,您可以设置一个属性来强制执行重定向,但我似乎无法使其正常工作。Hmmmmmmm@psf在没有
内容处置
标题的情况下,浏览器和wget等工具只需从URL的最后一个路径段猜测要使用的文件名。
public static void downloadFileJsoup(String URL, String PATH) throws IOException {
    Response res = Jsoup.connect(URL)
            .userAgent("Mozilla")
            .timeout(30000)
            .followRedirects(true)
            .ignoreContentType(true)
            .maxBodySize(20000000)//Increase value if download is more than 20MB
            .execute(); 
    String remoteFilename=res.header("Content-Disposition").replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1");
    String filename = PATH + remoteFilename;
    FileOutputStream out = (new FileOutputStream(new java.io.File(filename)));
    out.write( res.bodyAsBytes());
    out.close();
}