Осмысление заголовков x- * при кэшировании изображений facebook в настольном java-приложении - PullRequest
0 голосов
/ 03 марта 2011

Это должно быть довольно просто ... как это часто бывает ...

Я пишу настольное приложение на Java, которое должно хранить кеш изображений из Facebook.

Кажется, я не могу точно определить, когда произошел сбой или пропуск кэша, как я ожидал бы, основываясь на дате модификации ресурса.

Я заметил, что заголовок last-modified в ответах Facebook почти всегда (в случае изображений профиля, полученных методом, описанным ниже) полуночи 1 января 2009 года ... Просматривая несколько страниц на сайте с Монитор ресурсов Chrome открыт, я вижу, что на многих изображениях эта дата действительно установлена ​​как последняя измененная, и что в случаях, когда это верно, они также, по крайней мере, имеют значение X-Backend, X-Blockid & X-Cache-by (или иногда X-N) полей. Есть и другие случаи, когда last-modified установлена ​​на более старую дату, а X-* нет, и другие перестановки тоже (в основном это похоже на интерфейс и рекламную графику).

Пока что поиск информации по этим x-* заголовкам в сочетании с ограниченным базовым знанием HTTP оставил мне немного мудрее в том, как правильно реализовать мой кеш. Очевидно, что между обычным браузером и серверами Facebook нет проблем с установлением актуальности изображений в кеше, но мне не ясно, какой механизм используется для этого.

На данный момент у меня есть метод, который открывает URLConnection для соответствующего ресурса facebook, устанавливая ifmodifiedsince в тех случаях, когда в кэше уже существует соответствующий файл. Если я получу код ответа 304, тогда я вернусь - после вызова setLastModified для файла кэша для хорошей меры (отчасти потому, что на данный момент кэш изображений собирается в SVN, и им всем присваивается значение lastModified всякий раз, когда они происходят с проверить).

public static void downloadPicture(String uid) {
    try {
        URL url = new URL("http://graph.facebook.com/" + uid + "/picture?type=large");
        String fileName = "data/images/" + uid + ".jpg";

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        File cachedPic = new File(fileName);
        long lastModified = cachedPic.lastModified();
        if (cachedPic.exists()) {
            conn.setIfModifiedSince(lastModified);
        }

        conn.connect();

        if (conn.getResponseCode() == 304) {
            System.out.println("Using cache for " + uid);
            cachedPic.setLastModified(conn.getLastModified());
            return;
        }

        System.out.println("Downloading new for " + uid);

        ReadableByteChannel rbc = Channels.newChannel(conn.getInputStream());

        FileOutputStream fos = new FileOutputStream(fileName);
        fos.getChannel().transferFrom(rbc, 0, 1 << 24);
        fos.close();
    } catch (MalformedURLException e) {
        System.err.println("This really shouldn't happen...");
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Несомненно, есть и другие улучшения, которые необходимо внести в способ, которым я выполняю этот процесс (приведенный выше код отнимает значительное количество времени для каждого отдельного элемента, чего он явно не должен, и я уверен, что смогу решить - хотя комментарии по наилучшей практике все еще приветствуются), но мне нужно выяснить, почему я, кажется, всегда получаю 304, когда присутствует какой-либо кэшированный файл, и каков правильный метод для обеспечения отправки правильных запросов.

1 Ответ

1 голос
/ 14 июня 2011

Я думаю, что частью проблемы здесь является перенаправление, которое делает FB при использовании URL API графа для получения изображения.URL http://graph.facebook.com/user_uid/picture фактически перенаправит вас на другой URL для изображения.Из того, что я видел, перенаправленный URL-адрес изменяется при изменении изображения профиля.Таким образом, фактический URL-адрес изображения будет меняться не очень часто, а URL-адрес, на который вы будете перенаправлены, будет меняться.

Я не могу указать на какую-либо "официальную" документацию для резервного копирования утверждений, это только то, что я испытал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...