JSPページのデータベースから画像を取得して表示するにはどうすればよいですか?
次のステップを見てみましょう。
<img>
要素が必要です。src
属性を指定する必要があります。src
属性は有効なhttp://
URLを指す必要があります。したがって、ローカルディスクファイルシステムパスfile://
ではなく、サーバーとクライアントが物理的に異なるマシンで実行されると機能しません。http://example.com/context/images/foo.png
)またはリクエストパラメータ(例:http://example.com/context/images?id=1
)に画像識別子が含まれている必要があります。/images/*
などの特定のURLパターンをリッスンさせることができます。byte[]
またはInputStream
のいずれかとして取得されます。 JDBC API は ResultSet#getBytes()
を提供します および ResultSet#getBinaryStream()
この場合、および JPA API は @Lob
を提供します。byte[]
またはInputStream
を応答のOutputStream
に書き込むことができます。Content-Type
応答ヘッダーも設定する必要があります。 <mime-mapping>
のweb.xml
で拡張および/または上書きできる画像ファイル拡張子に基づいて、 ServletContext#getMimeType()
で適切なものを取得できます。それであるはずです。ほとんどコード自体を記述します。 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">
必要に応じて、 [〜#〜] el [〜#〜] でsrc
を動的に設定し、 [〜#〜] jstl [〜#〜]を使用して繰り返し処理することもできます。 :
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
次に、/images/*
のURLパターンでGETリクエストをリッスンする servlet を定義/作成します。以下の例では、ジョブに単純なVanilla 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つの問題として対処することをお勧めします。両方に関連するいくつかの質問と回答があります。
MySQLからBLOBをロードする方法
例えば blobとして保存された画像を取得する をご覧ください。
画像を動的に表示する方法
例えば サムネイルを動的に表示 をご覧ください。
出力ストリームが表示されない場合は、フラッシュして閉じてみてください。 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();