最快获取内容类型的方法

20

我需要检查用户插入的URL的内容类型(是否为图像、音频或视频)。 我有这样的一段代码:

URL url = new URL(urlname);
URLConnection connection = url.openConnection();
connection.connect();
String contentType = connection.getContentType();

我可以获取内容类型,但问题在于似乎需要下载整个文件才能检查其内容类型。 因此,当文件非常大时,花费的时间很长。 我需要在Google App Engine应用程序中使用它,因此请求仅限于30秒。

有没有其他方法可以在不下载文件的情况下获取URL的内容类型(以便可以更快地完成)?


一个想法:先获取前n个字节,然后关闭连接怎么样?在大多数情况下,通过文件开头就可以猜测出内容类型。但我不是专家。 - pintxo
@pintxo 为什么要这样做,如果你可以读取头参数:Content-Type,而不是使用 GET 获取整个请求,你可以直接执行 HEAD - To Kra
4个回答

34

感谢DaveHowes的答案和我在网上搜索如何获取HEAD的经验,我用以下方式得到它:

URL url = new URL(urlname);
HttpURLConnection connection = (HttpURLConnection)  url.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
String contentType = connection.getContentType();

22

如果“另一端”支持,您可以使用 HEAD HTTP 方法吗?


注意重定向,我在远程内容检查中遇到了同样的问题。请查看下面的代码,其中我进行了检查。 - To Kra

15

要注意重定向,我在远程内容检查中也遇到了同样的问题。
这是我的解决方法:

请注意重定向,我在进行远程内容检查时遇到了同样的问题。
以下是我采用的解决方法:

/**
 * Http HEAD Method to get URL content type
 *
 * @param urlString
 * @return content type
 * @throws IOException
 */
public static String getContentType(String urlString) throws IOException{
    URL url = new URL(urlString);
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("HEAD");
    if (isRedirect(connection.getResponseCode())) {
        String newUrl = connection.getHeaderField("Location"); // get redirect url from "location" header field
        logger.warn("Original request URL: '{}' redirected to: '{}'", urlString, newUrl);
        return getContentType(newUrl);
    }
    String contentType = connection.getContentType();
    return contentType;
}

/**
 * Check status code for redirects
 * 
 * @param statusCode
 * @return true if matched redirect group
 */
protected static boolean isRedirect(int statusCode) {
    if (statusCode != HttpURLConnection.HTTP_OK) {
        if (statusCode == HttpURLConnection.HTTP_MOVED_TEMP
            || statusCode == HttpURLConnection.HTTP_MOVED_PERM
                || statusCode == HttpURLConnection.HTTP_SEE_OTHER) {
            return true;
        }
    }
    return false;
}

您还可以为maxRedirectCount设置一些计数器,以避免无限重定向循环 - 但这不在本文中涵盖。这只是一个启示。


2
很好。为什么需要询问: 如果(statusCode!= HttpURLConnection.HTTP_OK){ - Dejell
@Dejell 这是用于处理重定向的。 - To Kra
1
您可以使用 java.net.HttpURLConnection.setFollowRedirects(boolean) 来减少样板代码的大小。 - Bass
setFollowRedirects 默认似乎为 true https://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html#setFollowRedirects(boolean)` - wz366

0

我曾经遇到过类似的任务,需要检查URL的内容类型,我是通过Retrofit来管理的。首先,您必须定义一个端点,以便使用要检查的URL进行调用:

@GET
suspend fun getContentType(@Url url: String): Response<Unit>

然后你可以这样调用它来获取内容类型头:

api.getContentType(url).headers()["content-type"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接