让我们分步骤看看会发生什么:
src
http://
file://
http://example.com/context/images/foo.png
http://example.com/context/images?id=1
/images/*
byte[]
InputStream
ResultSet#getBytes()
ResultSet#getBinaryStream()
@Lob
OutputStream
Content-Type
ServletContext#getMimeType()
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">
如果需要,您还可以在使用 EL 动态设置 src ="https://stackoverflow.com/tags/jstl/info">JSTL:
<c:forEach items="${imagenames}" var="imagename"> <img src="${pageContext.request.contextPath}/images/${imagename}"> </c:forEach>
然后定义/创建一个servlet,它侦听 /images/*,下面的示例使用普通的 JDBC 来完成这项工作:
/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 和缓存标头并正确响应这些请求,请使用此 静态资源servlet的抽象模板。
让我们分步骤看看会发生什么:
元素。
src
属性。src
属性需要指向有效的http://
URL,因此不是本地磁盘文件系统路径file://
因为当服务器和客户端在物理上不同的机器上运行时,这永远不会起作用。http://example.com/context/images/foo.png
)或作为请求参数(例如http://example.com/context/images?id=1
)。/images/*
,这样您就可以在特定的 URL 上执行一些 Java 代码。byte[]
或InputStream
的形式获取,JDBC API 提供ResultSet#getBytes()
和ResultSet#getBinaryStream()
为此,JPA API 提供@Lob
为此。李>byte[]
或InputStream
写入响应的OutputStream
(通常的 Java IO 方式。Content-Type
响应头也需要设置。您可以通过ServletContext#getMimeType()
基于图像文件扩展名,您可以通过web.xml 中的
。
扩展和/或覆盖该扩展名应该是这样。它几乎自己编写代码。让我们从 HTML 开始(在 JSP 中):
如果需要,您还可以在使用 EL 动态设置
src
="https://stackoverflow.com/tags/jstl/info">JSTL:然后定义/创建一个servlet,它侦听
/images/*,下面的示例使用普通的 JDBC 来完成这项工作:
就是这样。如果您担心 HEAD 和缓存标头并正确响应这些请求,请使用此 静态资源servlet的抽象模板。
另请参阅: