#java #url #content-type
#java #url #тип содержимого
Вопрос:
Мне нужно проверить тип контента (если это изображение, аудио или видео) URL-адреса, который был вставлен пользователем. У меня есть код, подобный этому:
URL url = new URL(urlname);
URLConnection connection = url.openConnection();
connection.connect();
String contentType = connection.getContentType();
Я получаю тип контента, но проблема в том, что, похоже, необходимо загрузить весь файл, чтобы проверить его тип контента. Так что это длится слишком много времени, когда файл довольно большой. Мне нужно использовать его в приложении Google App Engine, чтобы запросы были ограничены 30 секундами.
Есть ли какой-либо другой способ получить тип содержимого URL-адреса без загрузки файла (чтобы это можно было сделать быстрее)?
Комментарии:
1. Просто идея: как насчет захвата первых n байтов и последующего закрытия соединения? В большинстве случаев должно быть возможно угадать тип содержимого только по началу файла. Но я здесь не профессионал.
2. @pintxo зачем вам это делать, если вы можете прочитать параметр заголовка:
Content-Type
и вместо получения всего запроса с помощьюGET
вы просто выполняетеHEAD
вместо этого
Ответ №1:
Благодаря ответу DaveHowes и поискам в Google о том, как получить HEAD, я получил это таким образом:
URL url = new URL(urlname);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
String contentType = connection.getContentType();
Ответ №2:
Если «другой» конец поддерживает это, не могли бы вы использовать HEAD
метод HTTP?
Комментарии:
1. Помните о перенаправлениях, я столкнулся с такой же проблемой при удаленной проверке содержимого. Смотрите мой код ниже, где я проверял.
Ответ №3:
Помните о перенаправлениях, я столкнулся с такой же проблемой при удаленной проверке содержимого.
Вот мое исправление:
/**
* 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
, чтобы избежать бесконечного цикла перенаправления, но это здесь не рассматривается. Это просто вдохновение.
Комментарии:
1. неплохо. зачем вам нужно спрашивать: if (StatusCode != HttpURLConnection. HTTP_OK) {
2. @Dejell это для перенаправления дескриптора
3. Вы можете использовать
java.net.HttpURLConnection.setFollowRedirects(boolean)
для того, чтобы уменьшить размер вашего шаблонного кода.4.
setFollowRedirects
кажется,true
по умолчанию docs.oracle.com/javase/7/docs/api/java/net / …
Ответ №4:
Я столкнулся с аналогичной задачей, когда мне нужно было проверить тип содержимого URL-адреса, и способ, которым я справился с этим, — с помощью retrofit. Сначала вы должны определить конечную точку для ее вызова с URL-адресом, который вы хотите проверить:
@GET
suspend fun getContentType(@Url url: String): Response<Unit>
Затем вы вызываете это следующим образом, чтобы получить заголовок типа контента:
api.getContentType(url).headers()["content-type"]