ECMAScript 6 имеет «генераторы», которые позволяют вам легко программировать в асинхронном стиле.
function* myGenerator() {
const callback = yield;
let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
console.log("response is:", response);
// examples of other things you can do
yield setTimeout(callback, 1000);
console.log("it delayed for 1000ms");
while (response.statusText === "error") {
[response] = yield* anotherGenerator();
}
}
Для запуска вышеуказанного кода вы делаете это:
const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function
Если вам нужно настроить таргетинг на браузеры, которые не поддерживают ES6, вы можете запустить код через Babel или short-compiler для генерации ECMAScript 5.
Обратный вызов ...args
завернут в массив и разрушен, когда вы их читаете так что шаблон может справиться с обратными вызовами, которые имеют несколько аргументов. Например, с узлом fs :
const [err, data] = yield fs.readFile(filePath, "utf-8", callback);
Ответ из BalusC является (как обычно) правильным.
Но сохраните одно (как уже было сказано им). Окончательный запрос выполняется из браузера, чтобы получить URL-адрес из созданного тега <img>
. Это не выполняется в контексте jsf.
Итак, если вы попытаетесь, например, доступ к фазеId (протоколирование или по какой-либо причине)
context.getCurrentPhaseId().getName()
Это приведет к ошибке NullPointerException
, и какое-то вводящее в заблуждение сообщение об ошибке вы получите:
org.primefaces.application.resource.StreamedContentHandler () - Error in streaming dynamic resource. Error reading 'image' on type a.b.SomeBean
мне достаточно времени, чтобы выяснить, в чем проблема.
Здесь есть пара возможностей (и, пожалуйста, опубликуйте весь класс, если это не так).
1) Вы не инициализируете изображение правильно. 2) Ваш поток пуст, поэтому вы ничего не получаю
Я предполагаю, что student.getImage () имеет подпись байта [], поэтому сначала убедитесь, что эти данные фактически нетронуты и представляют изображение. Во-вторых - вы не указываете тип контента, который должен быть «image / jpg» или все, что вы используете.
Вот некоторый код шаблона, чтобы проверить его, я использую для этого Primefaces 2.
/** 'test' package with 'test/test.png' on the path */
@RequestScoped
@ManagedBean(name="imageBean")
public class ImageBean
{
private DefaultStreamedContent content;
public StreamedContent getContent()
{
if(content == null)
{
/* use your database call here */
BufferedInputStream in = new BufferedInputStream(ImageBean.class.getClassLoader().getResourceAsStream("test/test.png"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int val = -1;
/* this is a simple test method to double check values from the stream */
try
{
while((val = in.read()) != -1)
out.write(val);
}
catch(IOException e)
{
e.printStackTrace();
}
byte[] bytes = out.toByteArray();
System.out.println("Bytes -> " + bytes.length);
content = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/png", "test.png");
}
return content;
}
}
и некоторая разметка ...
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
>
<h:head>
</h:head>
<h:body>
<p:graphicImage value="#{imageBean.content}" />
</h:body>
</html>
Если этот код работает, то вы настроены правильно. Несмотря на то, что это код мусора для потоков (не используйте его в процессе производства) , он должен дать вам возможность устранить неисправность. Я предполагаю, что вы можете что-то происходить в вашей JPA или другой базе данных, где вы байт [] пуст или он отформатирован неправильно. Кроме того, у вас может быть проблема с контентом.
Наконец, я бы клонировал данные из компонента, чтобы student.getImage () был только скопирован в новый массив, а затем использован. Таким образом, если у вас что-то неизвестное происходит (что-то еще перемещает объект или меняет байт [], вы не возитесь с вашими потоками.
Сделайте что-то вроде:
byte[] data = new byte[student.getImage().length]
for(int i = 0; i < data.length; i++)
data[i] = student.getImage()[i];
, так что ваш bean-экземпляр имеет копию (или Arrays.copy () - независимо от того, что плавает ваша лодка). Я не могу подчеркнуть, что что-то простое, как этот / тип содержимого, как правило, неверно. Удачи вам.
Попробуйте включить тип mime. В вашем опубликованном примере у вас есть это как "". Пустое изображение может быть связано с тем, что он не распознает поток как файл изображения, так как вы сделали это поле пустой строкой. Поэтому добавьте тип mime image / png или image / jpg и посмотрите, работает ли это:
String mimeType = "image/jpg";
StreamedContent file = new DefaultStreamedContent(bytes, mimeType, filename);