Кстати, он должен быть доступен по общедоступному URL. Таким образом, <img src>
должен в конечном итоге ссылаться на http://
URI, а не на что-то вроде file://
URI или около того. В конечном счете, исходный код HTML выполняется на компьютере конечного пользователя, а изображения загружаются веб-браузером индивидуально во время анализа исходного кода HTML. Когда веб-браузер обнаруживает file://
URI, такой как C:\path\to\image.png
, он будет искать в файловой системе локального диска конечного пользователя изображение, а не в веб-сервере. Это, очевидно, не сработает, если веб-браузер работает на физически другой машине, чем веб-сервер.
Есть несколько способов добиться этого:
Если у вас есть полный контроль над папкой с изображениями, просто перетащите папку со всеми изображениями, например, /images
непосредственно в папке развертывания servletcontainer, такой как папка /webapps
в случае Tomcat и папка /domains/domain1/applications
в случае GlassFish. Дальнейшая настройка не требуется.
Или добавьте новый контекст веб-приложения на сервер, который указывает на абсолютное расположение файловой системы диска в папке с этими изображениями. Как это сделать, зависит от используемого контейнера. В приведенных ниже примерах предполагается, что изображения расположены в /path/to/images
, и вы хотите получить к ним доступ через http: //.../images.
.
В случае Tomcat добавьте следующую новую запись в /conf/server.xml
Tomcat внутри <Host>
:
<Context docBase="/path/to/images" path="/images" />
В случае GlassFish добавьте следующую запись в /WEB-INF/glassfish-web.xml
:
<property name="alternatedocroot_1" value="from=/images/* dir=/path/to" />
В случае WildFly добавьте следующую запись в <host name="default-host">
из /standalone/configuration/standalone.xml
...
<location name="/images" handler="images-content" />
... и далее в <handlers>
запись того же <subsystem>
, что и выше <location>
:
<file name="images-content" path="/path/to/images" />
Или создайте Servlet
, который передает изображение с диска в ответ:
@WebServlet("/images/*")
public class ImageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String filename = request.getPathInfo().substring(1);
File file = new File("/path/to/images", filename);
response.setHeader("Content-Type", getServletContext().getMimeType(filename));
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
Files.copy(file.toPath(), response.getOutputStream());
}
}
Если вы используете OmniFaces, то FileServlet
может оказаться полезным, так как он также учитывает запросы заголовка, кэширования и диапазона.
Или используйте OmniFaces <o:graphicImage>
, который поддерживает свойство компонента, возвращающее byte[]
или InputStream
:
@Named
@ApplicationScoped
public class Bean {
public InputStream getImage(String filename) {
return new FileInputStream(new File("/path/to/images", filename));
}
}
Или используйте PrimeFaces <p:graphicImage>
, который поддерживает метод бина, возвращающий специфичный для PrimeFaces StreamedContent
.
@Named
@ApplicationScoped
public class Bean {
public StreamedContent getImage() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
}
else {
// So, browser is requesting the image. Return a real StreamedContent with the image bytes.
String filename = context.getExternalContext().getRequestParameterMap().get("filename");
return new DefaultStreamedContent(new FileInputStream(new File("/path/to/images", filename)));
}
}
}
Для первого способа, а для Tomcat и WildFly - вторым, изображения будут доступны по http://example.com/images/filename.ext и, следовательно, будут ссылаться в обычном HTML следующим образом
<img src="/images/filename.ext" />
Для подхода GlassFish вторым и третьим способами изображения будут доступны по http://example.com/context/images/filename.ext и, таким образом, будут ссылаться в обычном HTML следующим образом
<img src="#{request.contextPath}/images/filename.ext" />
или в JSF следующим образом (автоматически добавляется контекстный путь)
<h:graphicImage value="/images/filename.ext" />
Для подхода OmniFaces четвертым способом, ссылаться на него следующим образом
<o:graphicImage value="#{bean.getImage('filename.ext')}" />
Для подхода PrimeFaces пятым способом укажите его следующим образом:
<p:graphicImage value="#{bean.image}">
<f:param name="filename" value="filename.ext" />
</p:graphicImage>
Обратите внимание, что пример #{bean}
- это @ApplicationScoped
, поскольку он в основном представляет службу без сохранения состояния. Вы также можете сделать это @RequestScoped
, но тогда бин будет воссоздан при каждом отдельном запросе, даром. Вы не можете сделать это @ViewScoped
, потому что в данный момент браузер должен загрузить изображение, сервер не создает страницу JSF. Вы можете сделать это @SessionScoped
, но затем он будет сохранен в памяти, даром.
Смотри также: