GWT. Грузятся старые картинки, а не новые.

27 views
Skip to first unread message

Keus

unread,
Jun 22, 2010, 1:49:05 AM6/22/10
to Google App Engine for Java on Russian
Вроде на вопросы про GWT тут не отвечают, но попробую ещё раз, с
другой проблемой.

Пользователь загружает в хранилище данных GAE картинки через
специально диалоговое окно и затем ему в том же диалоге показываются
все загруженные им картинки, которые он может удалить.

Но когда пользователь удаляет картинку и затем загружает другую, то в
диалоге показывается удаленная им картинка, а не новая. Хотя если
открыть ссылку на картинку в новой вкладке браузера, там будет новая
картинка. Пробовал на в двух разных браузерах, но результат тот же.
Картинки начинают правильно показываться, если я обновлю страницу в
браузере.

Ссылки на картинки образуются через сервлет.
Image chart = new Image();
chart.setUrl(GWT.getModuleBaseURL() + "chartLoad?key=" + key +
"&index=" + String.valueOf(index));

С чем может быть связан данный феномен? Это связано с кэшированием в
браузерах или с GWT? Можно как-то сделать, что бы всегда картинка
получалась с сервера?

Vitaly Gashock

unread,
Jun 22, 2010, 2:46:40 AM6/22/10
to google-appengi...@googlegroups.com
Быстрее всего это связано с кешированием в браузере.
А каким образом Вы отображаете картинки в диалоговом окне?


--
Kind regards,
Vitaly Gashock


22 июня 2010 г. 8:49 пользователь Keus <dmiha...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 3:14:34 AM6/22/10
to Google App Engine for Java on Russian
У меня есть класс, расширяющий DialogBox, в котором есть панель
FlowPanel, в неё я вставляю ещё панели в каждой из которых присоединен
объект класса Image.

После каждого добавления новой картинке, которая сохраняется в объекте
GAE, или удаления старой, я получаю их все снова по одной и вывожу в
диалоге. Точнее не сами картинки, а ссылки к сервлету со специальными
параметрами.

Код выглядит примерно так. Index - это количество картинок сохраненных
в определенном объекте в GAE.

protected void displayCharts(int index) {

// Очистить панель для вставки новых картинок.
imagePanel.clear();

for(int i = 0; index-1 >= i; i++) {

// Создать панель с кнопкой удаления и картинкой.
ChartPanel deletePanel = new ChartPanel(key, i, this);

imagePanel.add(deletePanel);
}
}


Это класс с панелью для картинки и кнопки её удаления.

public class ChartPanel extends FlowPanel implements ClickHandler{

private TradingJournalConstants constants =
GWT.create(TradingJournalConstants.class);
private final OrderServiceAsync orderService =
GWT.create(OrderService.class);
private int index;
private String key = new String();
private ChartsUploadDialog dialog;
private Button delete = new Button(constants.delete());

public ChartPanel(String key, int index, ChartsUploadDialog dialog) {
super();

this.index = index;
this.key = key;
this.dialog = dialog;
delete.addClickHandler((ClickHandler) this);

Image chart = new Image();
chart.setUrl(GWT.getModuleBaseURL() + "chartLoad?key=" + key +
"&index=" + String.valueOf(index));

add(delete);
add(chart);

}

@Override
public void onClick(ClickEvent event) {
deleteChart();
}

private void deleteChart() {
// Удалить график.
orderService.deleteChart(key, index, new AsyncCallback<Void>() {
public void onFailure(Throwable error) {
}
public void onSuccess(Void result) {
dialog.getPreviewCharts();
}
});
}
}


On 22 июн, 13:46, Vitaly Gashock <gsho...@gmail.com> wrote:
> Быстрее всего это связано с кешированием в браузере.
> А каким образом Вы отображаете картинки в диалоговом окне?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 8:49 пользователь Keus <dmihail...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 3:21:51 AM6/22/10
to Google App Engine for Java on Russian
Я закрываю диалоговое окно с картинками и затем снова его открываю, а
картинки всё равно показываются не правильные. Помогает только
обновление страницы, т.е. перезагрузки в браузере самого приложения.

Думаю, может ещё быть причина в файле развертывания самого GAE
приложения, т.е. в appengine-web.xml. Но пробую разные параметры для
<static-files>, но ничего не меняется.


On 22 июн, 13:46, Vitaly Gashock <gsho...@gmail.com> wrote:

> Быстрее всего это связано с кешированием в браузере.
> А каким образом Вы отображаете картинки в диалоговом окне?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 8:49 пользователь Keus <dmihail...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 3:22:55 AM6/22/10
to Google App Engine for Java on Russian
А можно это кэширование программно отключить для моего приложения?

On 22 июн, 13:46, Vitaly Gashock <gsho...@gmail.com> wrote:

> Быстрее всего это связано с кешированием в браузере.
> А каким образом Вы отображаете картинки в диалоговом окне?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 8:49 пользователь Keus <dmihail...@gmail.com> написал:

Vitaly Gashock

unread,
Jun 22, 2010, 3:51:03 AM6/22/10
to google-appengi...@googlegroups.com
Реально код для установки URL-ов картинок у Вас выполняется в конструкторе. Это значит, что при первом открытии диалога (читай, после рефреша) все картинки нормально сетапятся и отображаются.
Когда Вы скрываете диалог он просто становится невидимым, но инстанс его уже есть. При повторном открытии диалога естественно конструктор не срабатывает и у Вас отображаются старые картинки -- как следствие того, что не отработали вызовы к сервлету, который вычитывает картинки из дата-стора.

Как вариант: попробуйте код:

               Image chart = new Image();
               chart.setUrl(GWT.getModuleBaseURL() + "chartLoad?key=" + key + "&index=" + String.valueOf(index));

выделить в отдельный метод и продергивать этот метод в момент создания диалога (в конструкторе) и в момент открытия диалога. Например, сделать в классе диалога метод для его открытия и в нем помимо команды отображения диалога передергивать метод для подгрузки картинок.
Вроде так, если я верно понял проблему.


--
Kind regards,
Vitaly Gashock


22 июня 2010 г. 10:22 пользователь Keus <dmiha...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 5:39:25 AM6/22/10
to Google App Engine for Java on Russian
Да, в момент открытия диалога картинки в первый раз запрашиваются из
объекта в хранилище и добавляются в панель с картинками в конструкторе
диалога. Но этот же код вызывается ещё в двух случаях, после удаления
картинки и поле добавления.

Можно сказать следующим образом, по этой ссылке
http://localhost:8888/tradingjournal/chartLoad?key=a&index=0 есть
картинка <<А>> и она показывается в диалоге, так же есть картинка <<Б>> по
ссылке http://localhost:8888/tradingjournal/chartLoad?key=a&index=1
(разница между ними только в последней цифре, обозначающей её номер в
объекте на GAE). Затем пользователь удаляет картинку <<А>> и диалог
снова запрашивает ссылки на все картинки. По идее должна показывается
картинка <<Б>>, но показывается удаленная картинка <<А>> (но на сервере её
уже нет). Сейчас картинка <<Б>> имеет ту же ссылку, что была у картинки
<<А>>, т.е. http://localhost:8888/tradingjournal/chartLoad?key=a&index=0.

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

Вроде бы так браузеры должны вести себя относительно статических
картинок, т.е. тех, что не изменяются и их можно один раз получить с
сервера, сохранить в браузере и затем, когда надо подставлять в
страницу из браузера, а не загружать повторно с сервера. Но у меня по
одно и той же ссылке могут быть разные картинки в разные моменты
времени.

Удивительно до чего умные браузер и GWT, сейчас специально через
отладчик более внимательно проследил, когда происходит вызов сервлета
с картинками и оказалось он не всегда вызывается.

Скажем у меня есть объект с 1 картинкой, после открытия диалога для её
просмотра и манипуляций, код

Image chart = new Image();
chart.setUrl(GWT.getModuleBaseURL() + "chartLoad?key=" + key +
"&index=" + String.valueOf(index));

вызывается один раз и следом идет вызов сервлета, тоже один раз. Тут
всё правильно.

Затем я добавляю картинку и заново хочу получить все картинки,
происходит вызов chart.setUrl() 2 раза, а обращение к сервлету только
одно, для вновь добавленного файла. Добавляю третью картинку и снова
chart.setUrl() вызывается как надо, т.е. 3 раза, но обращение к
сервлету только одно, для третьей картинки. Получается, что браузер
или GWT (или может GAE к этому тоже причастна) не считают нужным
обращаться снова к сервлету за картинками, а дают мне их от куда-то из
своих недр.

Затем я закрываю диалог и снова открываю. Происходит 3 вызова
chart.setUrl(), но не одного обращения к серверу.

Когда я удаляю какую-либо одну из трех картинок происходит 2 вызова
chart.setUrl(), но не одного запроса на сервер.

Если я после этого добавлю новую картинку, т.е. к оставшимся двум
добавлю третью, то мне показывается удаленная до этого картинка, а не
новая. Опять же к серверу обращений не было.

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


On 22 июн, 14:51, Vitaly Gashock <gsho...@gmail.com> wrote:
> Реально код для установки URL-ов картинок у Вас выполняется в конструкторе.
> Это значит, что при первом открытии диалога (читай, после рефреша) все
> картинки нормально сетапятся и отображаются.
> Когда Вы скрываете диалог он просто становится невидимым, но инстанс его уже
> есть. При повторном открытии диалога естественно конструктор не срабатывает
> и у Вас отображаются старые картинки -- как следствие того, что не
> отработали вызовы к сервлету, который вычитывает картинки из дата-стора.
>
> Как вариант: попробуйте код:
>
> Image chart = new Image();
> chart.setUrl(GWT.getModuleBaseURL() + "chartLoad?key=" + key
> + "&index=" + String.valueOf(index));
>
> выделить в отдельный метод и продергивать этот метод в момент создания
> диалога (в конструкторе) и в момент открытия диалога. Например, сделать в
> классе диалога метод для его открытия и в нем помимо команды отображения
> диалога передергивать метод для подгрузки картинок.
> Вроде так, если я верно понял проблему.
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 10:22 пользователь Keus <dmihail...@gmail.com> написал:

Vitaly Gashock

unread,
Jun 22, 2010, 5:46:11 AM6/22/10
to google-appengi...@googlegroups.com
А Вы картинки в blob-поле объекта храните?

--
Kind regards,
Vitaly Gashock


22 июня 2010 г. 12:39 пользователь Keus <dmiha...@gmail.com> написал:

Vitaly Gashock

unread,
Jun 22, 2010, 5:46:42 AM6/22/10
to google-appengi...@googlegroups.com
Почему бы не попробовать сервлетом доставать картинки из дата-стора по ID-шникам?

--
Kind regards,
Vitaly Gashock


22 июня 2010 г. 12:46 пользователь Vitaly Gashock <gsh...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 5:48:57 AM6/22/10
to Google App Engine for Java on Russian
Да, они у меня списком в поле объекта хранятся.

On 22 июн, 16:46, Vitaly Gashock <gsho...@gmail.com> wrote:
> А Вы картинки в blob-поле объекта храните?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 12:39 пользователь Keus <dmihail...@gmail.com> написал:


>
>
>
> > Да, в момент открытия диалога картинки в первый раз запрашиваются из
> > объекта в хранилище и добавляются в панель с картинками в конструкторе
> > диалога. Но этот же код вызывается ещё в двух случаях, после удаления
> > картинки и поле добавления.
>
> > Можно сказать следующим образом, по этой ссылке
> >http://localhost:8888/tradingjournal/chartLoad?key=a&index=0есть
> > картинка <<А>> и она показывается в диалоге, так же есть картинка <<Б>> по

> > ссылкеhttp://localhost:8888/tradingjournal/chartLoad?key=a&index=1


> > (разница между ними только в последней цифре, обозначающей её номер в
> > объекте на GAE). Затем пользователь удаляет картинку <<А>> и диалог
> > снова запрашивает ссылки на все картинки. По идее должна показывается
> > картинка <<Б>>, но показывается удаленная картинка <<А>> (но на сервере её
> > уже нет). Сейчас картинка <<Б>> имеет ту же ссылку, что была у картинки

> > <<А>>, т.е.http://localhost:8888/tradingjournal/chartLoad?key=a&index=0.

Keus

unread,
Jun 22, 2010, 5:50:09 AM6/22/10
to Google App Engine for Java on Russian
Вот так
@Persistent
private List<Blob> imageCharts;

On 22 июн, 16:46, Vitaly Gashock <gsho...@gmail.com> wrote:
> А Вы картинки в blob-поле объекта храните?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 12:39 пользователь Keus <dmihail...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 5:55:27 AM6/22/10
to Google App Engine for Java on Russian
А это как? У меня сервлет обращается к объекту, получает у него
определенную картину в виде массива байт и возврашает в виде картинки
gif. Вот код:

protected void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException {

response.setContentType("image/gif");
String key = request.getParameter("key");
int index = Integer.parseInt(request.getParameter("index"));

OrderServiceImpl orderService = new OrderServiceImpl();
try {
byte[] chart = orderService.getPreviewChart(key, index);
if(chart != null) {
ServletOutputStream os = response.getOutputStream();
os.write(chart);
}
} catch (NotLoggedInException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

On 22 июн, 16:46, Vitaly Gashock <gsho...@gmail.com> wrote:
> Почему бы не попробовать сервлетом доставать картинки из дата-стора по
> ID-шникам?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 12:46 пользователь Vitaly Gashock <gsho...@gmail.com>написал:

Vitaly Gashock

unread,
Jun 22, 2010, 5:58:47 AM6/22/10
to google-appengi...@googlegroups.com
Я бы сделал класс PictureBean, в котором помимо Blob-поля еще есть ID этой картинки в датасторе.
Описано это в http://ru.enetri.com/2010/05/24/2.html
Вам там будет интересен код для получения картинок из дата-стора и отправка их на клиент в тег <img ../>
Вы ведь можете в у себя на UI формировать ссылку для загрузки картинки помимо индексов будет и ID картинки?

--
Kind regards,
Vitaly Gashock


22 июня 2010 г. 12:50 пользователь Keus <dmiha...@gmail.com> написал:

Keus

unread,
Jun 22, 2010, 6:33:22 AM6/22/10
to Google App Engine for Java on Russian
Сайт указанный в ссылке что-то не открывается. Но я готов любой способ
попробовать для получения картинки, просто нашел только тот что у себя
реализовал.

On 22 июн, 16:58, Vitaly Gashock <gsho...@gmail.com> wrote:
> Я бы сделал класс PictureBean, в котором помимо Blob-поля еще есть ID этой
> картинки в датасторе.

> Описано это вhttp://ru.enetri.com/2010/05/24/2.html


> Вам там будет интересен код для получения картинок из дата-стора и отправка
> их на клиент в тег <img ../>
> Вы ведь можете в у себя на UI формировать ссылку для загрузки картинки
> помимо индексов будет и ID картинки?
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 12:50 пользователь Keus <dmihail...@gmail.com> написал:

Vitaly Gashock

unread,
Jun 22, 2010, 6:49:34 AM6/22/10
to google-appengi...@googlegroups.com
У меня Енетри открывается...
Суть такая, что при выдаче списка картинок для отображения нужно учитывать id картинки, который инкапсулирован в PictureBean. При аплоаде файла нужно создавать новый объект в датасторе и потом уже в своем коде хранить не

> >        @Persistent
> >        private List<Blob> imageCharts;

а что-то типа
private List<PictureBean> imageCharts;


--
Kind regards,
Vitaly Gashock


22 июня 2010 г. 13:33 пользователь Keus <dmiha...@gmail.com> написал:

Keus

unread,
Jun 23, 2010, 12:37:06 AM6/23/10
to Google App Engine for Java on Russian
Большое спасибо, Виталий!

Когда по твоему совету URL-ы картинок стал делать уникальными и
неповторимыми, то всё заработало как надо, даже кэширование, которое
делало мне проблемы, теперь работает в мою пользу. :)


On 22 июн, 17:49, Vitaly Gashock <gsho...@gmail.com> wrote:
> У меня Енетри открывается...
> Суть такая, что при выдаче списка картинок для отображения нужно учитывать
> id картинки, который инкапсулирован в PictureBean. При аплоаде файла нужно
> создавать новый объект в датасторе и потом уже в своем коде хранить не
>
> > >        @Persistent
> > >        private List<Blob> imageCharts;
>
> а что-то типа
> private List<PictureBean> imageCharts;
>
> --
> Kind regards,
> Vitaly Gashock
>

> 22 июня 2010 г. 13:33 пользователь Keus <dmihail...@gmail.com> написал:

Vitaly Gashock

unread,
Jun 23, 2010, 4:37:09 AM6/23/10
to google-appengi...@googlegroups.com
Пожалуйста ;)
Рад, что смог помочь.

--
Kind regards,
Vitaly Gashock


23 июня 2010 г. 7:37 пользователь Keus <dmiha...@gmail.com> написал:
Reply all
Reply to author
Forward
0 new messages