Как я могу получить и отобразить изображения из базы данных на странице JSP?
Как получить и отобразить изображения из базы данных на странице JSP?
Ответ 1
Давайте посмотрим по шагам, что должно произойти:
- JSP - это в основном технология просмотра, которая должна генерировать HTML-вывод.
- Чтобы отобразить изображение в HTML, вам нужен элемент HTML
<img>
. - Чтобы он мог найти изображение, вам нужно указать его атрибут
src
. - Атрибут
src
должен указывать на действительныйhttp://
адресhttp://
и, следовательно, на файл путиfile://
системы локального дискаfile://
, который никогда не будет работать, когда сервер и клиент работают на физически разных машинах. - URL-адрес изображения должен иметь идентификатор изображения либо в пути запроса (например,
http://example.com/context/images/foo.png
), либо в качестве параметра запроса (например,http://example.com/context/images?id=1
). - В мире JSP/Servlet вы можете позволить сервлету прослушивать определенный шаблон URL, такой как
/images/*
, так что вы можете просто выполнить некоторый код Java для определенных URL. - Изображения являются двоичными данными и должны быть получены как
byte[]
илиInputStream
из БД, JDBC API предлагаетResultSet#getBytes()
иResultSet#getBinaryStream()
для этого, а JPA API предлагает@Lob
для этого. - В сервлете вы можете просто записать этот
byte[]
илиInputStream
вOutputStream
ответа обычным способом ввода-вывода Java. - Клиентская сторона должна быть проинструктирована о том, что данные должны обрабатываться как изображение, таким образом, по крайней мере, также должен быть установлен заголовок ответа
Content-Type
. Вы можете получить правильный с помощьюServletContext#getMimeType()
зависимости от расширения файла изображения, которое вы можете расширить и/или переопределить с помощью<mime-mapping>
в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
Я предлагаю вам решить эту проблему как две проблемы. Есть несколько вопросов и ответов, связанных с обоими.
-
Как загрузить blob из MySQL
См. например Получить изображение, сохраненное как blob
-
Как динамически отображать изображение
См. например Динамическое отображение миниатюр
Ответ 3
Попробуйте очистить и закрыть поток вывода.
Ответ 4
Вы также можете создать собственный тег для отображения изображения.
1) создать пользовательский тег java class и tld файл.
2) написать логику для отображения изображения, например преобразования байта [] в строку Base64.
поэтому он используется для каждого изображения, независимо от того, показываете ли вы только одно изображение или несколько изображений на одной странице jsp.
Ответ 5
Я использовал базу данных SQL SERVER, поэтому код ответа соответствует. Все, что вам нужно сделать, это включить тег <img>
на странице jsp и вызвать сервлет из его атрибута src, такого как
<img width="200" height="180" src="DisplayImage?ID=1">
Здесь 1 - уникальный идентификатор изображения в базе данных, а ID - переменная. Мы получаем значение этой переменной в сервлете. В коде сервлета мы берем вход двоичного потока из правильного столбца в таблице. Это ваше изображение хранится в столбце. В моем коде я использовал третий столбец, потому что мои изображения хранятся в виде двоичных данных в третьем столбце. После извлечения данных входного потока из таблицы мы читаем его содержимое в потоке вывода, чтобы его можно было записать на экран. Вот он
import java.io.*;
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.*;
import javax.servlet.http.*;
import model.ConnectionManager;
public class DisplayImage extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)
throws 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 = ConnectionManager.getConnection();
int ID = Integer.parseInt(request.getParameter("ID"));
try {
stmt = conn.createStatement();
sql = "SELECT * FROM IMAGETABLE WHERE ID="+ID+"";
ResultSet result = stmt.executeQuery(sql);
if(result.next()){
in=result.getBinaryStream(3);//Since my data was in third 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(DisplayImage.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());
}
}
}
}
После выполнения вашего jsp или html файла вы увидите изображение на экране.