Вопрос-ответ

How to retrieve and display images from a database in a JSP page?

Как извлекать и отображать изображения из базы данных на странице JSP?

Как я могу извлекать и отображать изображения из базы данных на странице JSP?

Переведено автоматически
Ответ 1

Давайте пошагово посмотрим, что должно произойти:


  • JSP - это в основном технология просмотра, которая должна генерировать выходные данные HTML.

  • Для отображения изображения в формате HTML вам нужен элемент HTML <img>.

  • Чтобы он мог найти изображение, вам нужно указать его src атрибут.

  • src Атрибут должен указывать на действительный http:// URL-адрес, а следовательно, не на путь к файловой системе локального диска, file:// поскольку это никогда не сработает, когда сервер и клиент работают на физически разных машинах.

  • URL-адрес изображения должен содержать идентификатор изображения либо в пути запроса (например, http://example.com/context/images/foo.png), либо в качестве параметра запроса (например, http://example.com/context/images?id=1).

  • В мире JSP / Servlet вы можете позволить сервлету прослушивать определенный шаблон URL, например /images/*, чтобы вы могли просто выполнить некоторый Java-код на определенных URL.

  • Изображения представляют собой двоичные данные и должны быть получены либо как byte[] or InputStream из базы данных, JDBC API предлагает ResultSet#getBytes() и ResultSet#getBinaryStream() для этого, а JPA API предлагает @Lob для этого.

  • В сервлете вы можете просто записать это byte[] или InputStream в OutputStream ответ обычным способом ввода-вывода на Java.

  • Клиентская сторона должна быть проинструктирована о том, что данные должны обрабатываться как изображение, поэтому, по крайней мере, Content-Type заголовок ответа также должен быть установлен. Вы можете получить нужное через ServletContext#getMimeType() на основе расширения файла изображения, которое вы можете расширить и / или переопределить через <mime-mapping> in web.xml.

Так и должно быть. Он практически сам пишет код. Давайте начнем с HTML (на JSP):

<img src="${pageContext.request.contextPath}/images/foo.png">
<img src="${pageContext.request.contextPath}/images/bar.png">
<img src="${pageContext.request.contextPath}/images/baz.png">

При необходимости вы также можете динамически задавать src с помощью EL во время итерации с использованием JSTL:

<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>

Затем определите / создайте сервлет, который прослушивает запросы GET по шаблону URL /images/*, в приведенном ниже примере для задания используется простой ванильный JDBC:

@WebServlet("/images/*")
public class ImageServlet extends HttpServlet {

// content=blob, name=varchar(255) UNIQUE.
private static final String SQL_FIND = "SELECT content FROM Image WHERE name = ?";

@Resource(name="jdbc/yourDB") // For Tomcat, define as <Resource> in context.xml and declare as <resource-ref> in web.xml.
private DataSource dataSource;

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String imageName = request.getPathInfo().substring(1); // Returns "foo.png".

try (Connection connection = dataSource.getConnection(); PreparedStatement statement = connection.prepareStatement(SQL_FIND)) {
statement.setString(1, imageName);

try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
byte[] content = resultSet.getBytes("content");
response.setContentType(getServletContext().getMimeType(imageName));
response.setContentLength(content.length);
response.getOutputStream().write(content);
} else {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
}
}
} catch (SQLException e) {
throw new ServletException("Something failed at SQL/DB level.", e);
}
}

}

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

Смотрите также:

Ответ 2

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


  1. Как загрузить blob-объект из MySQL


    Смотрите, например, Извлечение изображения, сохраненного в виде большого двоичного объекта



  2. Как отображать изображения динамически


    Смотрите, например, Показывать миниатюры динамически



Ответ 3

Я написал и настроил код на JSP с использованием Oracle database. Надеюсь, это поможет.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpSession;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* Servlet implementation class displayfetchimage
*/

@WebServlet("/displayfetchimage")
public class displayfetchimage extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
* @see HttpServlet#HttpServlet()
*/

public displayfetchimage() {
super();
// TODO Auto-generated constructor stub
}

/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
Statement stmt = null;
String sql = null;
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
InputStream in = null;

response.setContentType("image/jpeg");
ServletOutputStream out;
out = response.getOutputStream();
Connection conn = employee.DbConnection.getDatabaseConnection();
HttpSession session = (HttpSession) request.getSession();
String ID = session.getAttribute("userId").toString().toLowerCase();
try {
stmt = conn.createStatement();
sql = "select user_image from employee_data WHERE username='" + ID + "' and rownum<=1";
ResultSet result = stmt.executeQuery(sql);
if (result.next()) {
in = result.getBinaryStream(1);// Since my data was in first column of table.
}
bin = new BufferedInputStream(in);
bout = new BufferedOutputStream(out);
int ch = 0;
while ((ch = bin.read()) != -1) {
bout.write(ch);
}

} catch (SQLException ex) {
Logger.getLogger(displayfetchimage.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (bin != null)
bin.close();
if (in != null)
in.close();
if (bout != null)
bout.close();
if (out != null)
out.close();
if (conn != null)
conn.close();
} catch (IOException | SQLException ex) {
System.out.println("Error : " + ex.getMessage());
}
}

}

// response.getWriter().append("Served at: ").append(request.getContextPath());
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/


protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Statement stmt = null;
String sql = null;
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
InputStream in = null;

response.setContentType("image/jpeg");
ServletOutputStream out;
out = response.getOutputStream();
Connection conn = employee.DbConnection.getDatabaseConnection();
HttpSession session = (HttpSession) request.getSession();
String ID = session.getAttribute("userId").toString().toLowerCase();
try {
stmt = conn.createStatement();
sql = "select user_image from employee_data WHERE username='" + ID + "' and rownum<=1";
ResultSet result = stmt.executeQuery(sql);
if (result.next()) {
in = result.getBinaryStream(1);
}
bin = new BufferedInputStream(in);
bout = new BufferedOutputStream(out);
int ch = 0;
while ((ch = bin.read()) != -1) {
bout.write(ch);
}

} catch (SQLException ex) {
Logger.getLogger(displayfetchimage.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (bin != null)
bin.close();
if (in != null)
in.close();
if (bout != null)
bout.close();
if (out != null)
out.close();
if (conn != null)
conn.close();
} catch (IOException | SQLException ex) {
System.out.println("Error : " + ex.getMessage());
}
}

}

}
Ответ 4

Попробуйте очистить и закрыть выходной поток, если он не отображается. Blob image = rs.getBlob(ImageColName);
InputStream in = image.getBinaryStream(); // Выведите большой двоичный объект в HttpServletResponse response.setContentType("image/jpeg");
BufferedOutputStream o = new BufferedOutputStream(response.getOutputStream());

    byte by[] = new byte[32768];
int index = in.read(by, 0, 32768);
while (index != -1) {
o.write(by, 0, index);
index = in.read(by, 0, 32768);
}
o.flush();
o.close();
java image jsp servlets