У вас обычно нет доступа к данным в Elasticsearch во время обработки вашего события Logstash. Рассмотрите возможность использования конвейера на Ingest node
Определенно не храните изображения в базе данных, но Вы захотите сохранить канал передачи изображения в базе данных. Это позволит Вам хранить изображение примерно где угодно.
Так как Вы используете два приложения кота, Ваш лучший выбор может состоять в том, чтобы сохранить изображения за пределами любого приложения и передать изображение потоком назад пользователю вместо того, чтобы позволить коту управлять файлами. Иначе я спросил бы, почему Вы пытаетесь сделать это с двумя веб-приложениями.
Однако хранение загруженных изображений в каталоге веб-приложения не является мудрой вещью сделать, и Вы знаете это.
Между прочим, Вы могли бы хотеть посмотреть этот поток stackoverflow, в последнее время обсужденный, где сохранить изображения. Это не могло бы решить Вашу проблему, конечно, вселит Вам больше веры в том, что Вы делаете.
Я использовал два веб-приложения для предотвращения по записи загруженных изображений в случае, если я повторно развертываю новый военный файл главного приложения.
Но поскольку Вы упоминаете, что нет никакой другой опции, но передавать их потоком через Сервлет или что-то, что я предполагаю, что могу сохранить их внешним каталогом кота.
Я не хотел писать этот Сервлет Потоковой передачи. Просто слишком маленький проект иметь дело со всей путаницей (как надлежащий тип контента, 404, и т.д.) при записи сервлета потоковой передачи.
Я решил это по-разному.
Во-первых, непортативный путь, то, что Glassfish (и я действительно верю, Tomcat также) позволяет Вам отображать внешний каталог в на иерархию веб-приложений. Это работает действительно хорошо и делает точно, что Вы хотите. Это позволяет Вам сохранить свои изображения во внешнем каталоге далеко от Вашего веб-приложения, и все же подать их.
Однако эта техника не является портативной.
Путь к я сделал это, портативно путем создания фильтра.
Вы помещаете фильтр, где-нибудь очевидный, говорите "/изображения".
То, что делает фильтр, является этим:
это проверяет на изображение (или что-либо, это работает с любым статическим ресурсом) в специальном каталоге в веб-приложении. Для нашего примера мы будем использовать URL "/webapp/images".
если файл НЕ существует, мы копируем файл с Вашего внешнего местоположения в к соответствующему пятну в веб-приложении. Так, скажем, reqyest URL является "/images/banner.gif". И что Ваши файлы хранятся на диске в "/home/app/images". Так, наш исходный файл является "/home/app/images/banner.gif". Мы затем копируем его туда, где мы хотим это в дереве веб-приложения. Мы используем "ServletContext.getRealPath" для этого. Так, место назначения будет "ServletContext.get RealPath ("/webapp/images/banner.gif"). Просто скопируйте источник в место назначения.
Эффективно Вы заканчиваете тем, что имели кэш файла в своем дереве развертывания веб-приложений. Вниз сторона - то, что это - кэш, таким образом, это должно сохраняться (т.е. необходимо проверить, является ли оригинал более новым, чем кэш, удостоверьтесь, что Вы удаляете, если источник удален, и т.д.). Кроме того, это копирует Ваши ресурсы, таким образом, Ваши изображения используют, в конечном счете, вдвое больше дискового пространства. Наконец, существует начальная стоимость копии при запуске.
Однако это ДЕЙСТВИТЕЛЬНО работает, и это препятствует тому, чтобы Вы имели для подавания статических ресурсов с помощью собственного кода. (Который является 3-м решением, отобразите фильтр/сервлет, чтобы прервать URL и просто передать его потоком Ваш сам.)
Я посмотрел бы на конструкцию в Tomcat (предполагающий, что это существует) сделать отображение для Вас. Я знаю, что это существует в Glassfish. (Google alternatedocroot, чтобы Glassfish видел, как он работает.)
<servlet>
<description></description>
<display-name>ImageDisplayServlet</display-name>
<servlet-name>ImageDisplayServlet</servlet-name>
<servlet-class>com.example.images.ImageDisplayServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageDisplayServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
О, ya настраивают Ваш Сервлет как вышеупомянутое для лучших результатов :P
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Image streaming Servlet.
*/
public class ImageDisplayServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public ImageDisplayServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String relativePath = trimToEmpty(request.getPathInfo());
// Make sure no one try to screw with us.
// This is important as user can literally access any file if we are not careful
if(isXSSAttack(relativePath) == false) {
String pathToFile = this.getServletContext().getRealPath(request.getPathInfo());
File file = new File(pathToFile);
System.out.println("Looking for file " + file.getAbsolutePath());
// show a 404 page
if(!file.exists() || !file.isFile()) {
httpError(404, response);
} else {
try {
streamImageFile(file, response);
} catch(Exception e) {
// Tell the user there was some internal server error.\
// 500 - Internal server error.
httpError(500, response);
e.printStackTrace();
}
}
} else {
// what to do if i think it is a XSS attack ?!?
}
}
private void streamImageFile(File file, HttpServletResponse response) {
// find the right MIME type and set it as content type
response.setContentType(getContentType(file));
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
response.setContentLength((int) file.length());
// Use Buffered Stream for reading/writing.
bis = new BufferedInputStream(new FileInputStream(file));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[(int) file.length()];
int bytesRead;
// Simple read/write loop.
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
// To late to do anything about it now, we may have already sent some data to user.
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
// To late to do anything about it now, we may have already sent some data to user.
}
}
}
}
private String getContentType(File file) {
if(file.getName().length() > 0) {
String[] parts = file.getName().split("\\.");
if(parts.length > 0) {
// only last part interests me
String extention = parts[parts.length - 1];
if(extention.equalsIgnoreCase("jpg")) {
return "image/jpg";
} else if(extention.equalsIgnoreCase("gif")) {
return "image/gif";
} else if(extention.equalsIgnoreCase("png")) {
return "image/png";
}
}
}
throw new RuntimeException("Can not find content type for the file " + file.getAbsolutePath());
}
private String trimToEmpty(String pathInfo) {
if(pathInfo == null) {
return "";
} else {
return pathInfo.trim();
}
}
private void httpError(int statusCode, HttpServletResponse response) {
try {
response.setStatus(statusCode);
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.append("<html><body><h1>Error Code: " + statusCode + "</h1><body></html>");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean isXSSAttack(String path) {
boolean xss = false;
// Split on the bases of know file separator
String[] parts = path.split("/|\\\\");
// Now verify that no part contains anything harmful
for(String part : parts) {
// No double dots ..
// No colons :
// No semicolons ;
if(part.trim().contains("..") || part.trim().contains(":") || part.trim().contains(";")) {
// Fire in the hole!
xss = true;
break;
}
}
return xss;
}
/**
* @see HttpServlet#doPost(Ht/promotions/some.jpgtpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Хорошо Вот Сервлет, что я быстро записал, что это может передать изображения потоком:
Вот Список ограничений, и знайте проблемы:
Использование:
Позвольте говорят, что Вы развертываете это веб-приложение, названное изображениями как отдельное приложение.
http://www.example.com/images/promotions/promo.jpg
средства там должны быть каталогом в "продвижениях" с изображением "promo.jpg" с в этом, отображает веб-приложение.
PS: не спрашивайте, почему я делаю этот Контейнер Сервлета только решение, которое сосет достижение.