如何使用 Struts 2 向浏览器提供图像? 休眠3?

发布于 2024-07-07 11:40:07 字数 685 浏览 7 评论 0原文

我正在使用 Struts 2.1.2 和 Hibernate 3.2.6.GA 开发一个 Web 应用程序。 我有一个实体 User,我已使用 Hibernate 将其映射到数据库中的表 USERS。 我想要一个与该实体关联的图像,我计划将其作为 BLOB 存储在数据库中。 我还想在网页上显示图像以及 User 的其他属性。

我能想到的解决方案是有一个表IMAGES(ID, IMAGE),其中IMAGE是一个BLOB列。 USERS 将有一个名为 IMAGEIDFK 列,它指向 IMAGES 表。 然后,我将在 User 实体上映射一个名为 imageId 的属性,并以 Long 形式映射到此 IMAGEID。 使用 JSP 渲染页面时,我会将图像添加为 等,并有一个读取图像并流式传输的操作内容发送到浏览器,并设置标头以长时间缓存图像。

这行得通吗? 是否有更好的方法来渲染存储在数据库中的图像? 首先将此类图像存储在数据库中是正确的方法吗?

I am developing a web application using Struts 2.1.2 and Hibernate 3.2.6.GA. I have an entity, User, which I have mapped to a table USERS in the DB using Hibernate. I want to have an image associated with this entity, which I plan to store as a BLOB in the DB. I also want to display the image on a webpage along with other attributes of the User.

The solution I could think of was to have a table IMAGES(ID, IMAGE) where IMAGE is a BLOB column. USERS will have an FK column called IMAGEID, which points to the IMAGES table. I will then map a property on User entity, called imageId mapped to this IMAGEID as a Long. When rendering the page with a JSP, I would add images as <img src="images.action?id=1"/> etc, and have an Action which reads the image and streams the content to the browser, with the headers set to cache the image for a long time.

Will this work? Is there a better approach for rendering images stored in a DB? Is storing such images in the DB the right approach in the first place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

宁愿没拥抱 2024-07-14 11:40:07

是的,您建议的解决方案会起作用。 鉴于您正在 Java 环境中工作,将图像存储在数据库中是最好的方法。 如果您在单个服务器环境中运行,并且应用程序服务器允许您在技术上以分解格式进行部署,那么您可以将映像存储在磁盘上,但这不是最佳实践。 一种建议是使用 servlet 而不是 JSP。 为了获得良好的浏览器行为,您希望浏览器认为它正在显示的文件类型与其期望的文件类型匹配。 尽管存在 mime 类型标头,但文件扩展名仍然非常重要。 因此,您需要一个如下所示的链接:

<a href="foo.jsp"><img src="imageservlet/123456789.png"></a>

其中 123456789 是数据库中图像的主键。 您的 servlet 映射将如下所示:

<servlet>
  <servlet-name>ImageServlet</servlet-name>
  <servlet-class>com.example.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ImageServlet</servlet-name>
  <url-pattern>/imageservlet/*</url-pattern>
</servlet-mapping>

然后,在您的 servlet 中,只需解析图像 ID 的请求 URL,而不是使用查询字符串,因为查询字符串会使某些浏览器感到困惑。 使用查询字符串不会彻底破坏浏览器,但您会在缓存方面遇到奇怪的行为,并且某些浏览器可能会将内容报告为不安全。

Yes your suggested solution will work. Given that you are working in a Java environment storing the images in the database is the best way to go. If you are running in a single server environment with an application server that will let you deploy in an exploded format technically you could store the images on disk but that wouldn't be the best practice. One suggestion would be to use a servlet instead of a JSP. To get good browser behavior you want the browser to think that the file type that it is displaying matches the file type that it is expecting. Despite the existence of mime type headers the file extension is still really important. So you want a link that looks like this:

<a href="foo.jsp"><img src="imageservlet/123456789.png"></a>

Where 123456789 is the primary key of your image in the database. Your servlet mapping would look like this:

<servlet>
  <servlet-name>ImageServlet</servlet-name>
  <servlet-class>com.example.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ImageServlet</servlet-name>
  <url-pattern>/imageservlet/*</url-pattern>
</servlet-mapping>

Then in your servlet simply parse the request URL for the image ID rather than using the query string as the query string will confuse some browsers. Using the query string won't break browsers outright but you'll get odd behavior with regards to caching and some browsers may report the content as unsafe.

丢了幸福的猪 2024-07-14 11:40:07

Internet Explorer 不支持这种图像嵌入方式。

Internet Explorer does not support that style of image embedding.

第几種人 2024-07-14 11:40:07

如果您想直接显示用户图像及其属性,也许您可​​以考虑将图像数据直接嵌入 HTML 中。

使用特殊的 data: URL 方案,您可以在 HTML 页面中嵌入任何 mime 数据,格式如下:

data:;base64,; 
  

需要替换为数据的 mime 类型(例如 image/png)并且
是文件实际字节的 Base64 编码字符串。

请参阅 RFC 2557

示例

<img src="data:image/png;base64,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">

If you want to display the user image directly with their properties perhaps you can consider embedding the image data directly in the HTML.

Using a special data: URL scheme you are able to embed any mime data inside a HTML page, the format is as follows:

data:<mimetype>;base64,<data>

needs to be replaced by the mime-type of your data (image/png for instance) and
is the base64 encoded string of the actual bytes of the file.

See RFC 2557.

Example:

<img src="data:image/png;base64,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">
你曾走过我的故事 2024-07-14 11:40:07

您建议的解决方案将完美运行。 我也做过同样的事情。

但您不需要为此使用 servlet。
Struts2已经有一个流结果。

请参阅这个 Struts 2 示例,它准确地描述了您想要的内容。

Your suggested solution would work perfectly. I have done the same thing.

But you don't need a servlet for this.
Struts2 has already a stream result.

See this Struts 2 Example which describes exactly what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文