当前位置: 首页 > 面试题库 >

图像过大将无法加载

林君博
2023-03-14
问题内容

我正在使用MEDIUMBLOB将图像存储在DB中。当我尝试通过servlet加载图像时,可以看到这些图像。但是,如果图像很大(1
MB或更大),我可以在浏览器中看到一半或3/4的图像。

当我下载相同的图像并将其放在公共Web内容中时,它可以完美运行。任何想法如何克服这个问题?我需要在servlet或MySQL中设置任何变量吗?

(由JSF生成的)HTML代码如下:

<img src="DisplayImage?mainID=drawing" />

图像servlet执行以下操作:

    String imgLen = rs1.getString(1);
    int len = imgLen.length();
    byte[] rb = new byte[len];
    InputStream readImg = rs1.getBinaryStream(1);
    InputStream inputStream = readImg;
    int index = readImg.read(rb, 0, len);
    response.reset();
    response.setHeader("Content-Length", String.valueOf(len));
    response.setHeader("Content-disposition", "inline;filename=/file.png");
    response.setContentType("image/png");
    response.getOutputStream().write(rb, 0, len);
    response.getOutputStream().flush();

编辑1

当我使用以下代码并将文件保存到本地磁盘时,我会看到完整的映像。

    String imgLen = rs1.getString(1);
    int len = imgLen.length();
    rb = new byte[len];
    inputStream = rs1.getBinaryStream(1);
    while ((read = inputStream.read(rb)) != -1) {
        out.write(rb, 0, read);
    }
    out.flush();
    out.close();

编辑2

保存一半的图像时,我注意到这些 图像 的大小为 100KB 。我的1 MB图像显示大小为100KB。所有图像都在发生这种情况:(

我认为这是最大的提示,这是怎么回事。但是我没有弄错什么。

编辑3

如果我从中删除以下内容web.xml,则可以查看这些图像。

    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>

我可以删除那些吗?我不重新收集为什么我要添加这些…

编辑4

我的web.xml文件是

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
        <context-param>
            <param-name>javax.faces.PROJECT_STAGE</param-name>
            <param-value>Development</param-value>
        </context-param>
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>/faces/*</url-pattern>
        </servlet-mapping>
        <session-config>
            <session-timeout>
                60
            </session-timeout>
        </session-config>
        <welcome-file-list>
            <welcome-file>faces/index.xhtml</welcome-file>
        </welcome-file-list>
        <filter>
            <filter-name>restrict</filter-name>
            <filter-class>com.sac.filter.MyFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>restrict</filter-name>
            <url-pattern>*.xhtml</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>MyFacesExtensionsFilter</filter-name>
            <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>MyFacesExtensionsFilter</filter-name>
            <servlet-name>Faces Servlet</servlet-name>
        </filter-mapping>

        <servlet>
            <servlet-name>DisplayImage</servlet-name>
            <servlet-class>com.sac.databean.DisplayImage</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>DisplayImage</servlet-name>
            <url-pattern>/DisplayImage</url-pattern>
        </servlet-mapping>
        <servlet>
            <servlet-name>SaveMyImage</servlet-name>
            <servlet-class>com.sac.databean.SaveMyImage</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>SaveMyImage</servlet-name>
            <url-pattern>/SaveMyImage</url-pattern>
        </servlet-mapping>
    </web-app>

问题答案:

测量图像长度的方式是错误的。您基本上是在将图像字节转换为人类可读的字符(按照不易理解的顺序,但不包括),然后计算字符的数量。这是不对的。您需要计算原始和未转换的字节数。一个字符不一定只用一个字节来表示,而是可以用一个以上的字节来表示。

有两种方法可以解决您的问题:

  1. 使用ResultSet#getBytes()代替。
        byte[] content = resultSet.getBytes("content");
    // ...
    response.setContentLength(content.length);
    response.getOutputStream().write(content);

请注意,这是记忆中拱,因为每个bytebyte[]基本积累Java的内存的一个字节。

  1. 还要在查询中选择BLOB长度。如何执行取决于所使用的数据库。在MySQL中,您可以使用此LENGTH()功能。
    SELECT content, LENGTH(content) AS contentLength FROM image WHERE id = ?
    

然后您按以下步骤处理:

        InputStream content = resultSet.getBinaryStream("content");
    int contentLength = resultSet.getInt("contentLength");
    // ...
    response.setContentLength(contentLength);
    SomeUtil.streamByBuffer(content, response.getOutputStream());

(其中该过程不是通过byte[]完整图片的长度进行的)

更新
:毕竟,图像上的请求似乎已经调用了MyFacesExtensionsFilter,这显然过分地缓存了响应,而没有在chain.doFilter()返回时适当地刷新响应。此过滤器仅在调用时才调用映射规则FacesServlet。但这不应该发生。图像请求应该只调用了图像servlet,而不是面部servlet。

根据映射规则,在FacesServlet/faces/*映射图像servlet时调用/DisplayImage。在<img src>你已经有相对于当前请求的URL,所以它最终最终成为/faces/DisplayImage这将首先调用FacesServlet,然后DisplayImageservlet的。错了

您应该相应地更改JSF代码,以便<img src>最终成为相对于域的,从而仅调用/DisplayImageservlet。

<img src="/contextpath/DisplayImage?mainID=drawing" />

您只需使用中的前导斜杠即可实现此目的<h:graphicImage>。它将自动添加上下文路径。

<h:graphicImage value="/DisplayImage?mainID=drawing" />


 类似资料:
  • 遇到了一个奇怪的问题,试图通过模型内的url从这里下载任何照片->https://jsonplaceholder.typicode.com/photos,例如“https://via.placeholder.com/150/92c952”,但得到错误: 另外,如果我试图从其他链接加载图像,例如->https://avatars.mds.yandex.net/get-pdb/1088712/8b19

  • 我想在android opencv上用Mat类加载图像,但我有一些错误。我在我的项目上添加库。我的代码:private CameraBridgeViewBase mopencvCameraView; private BaseLoaderCallback mLoaderCallback=new BaseLoaderCallback(this){@override public void onMana

  • 我的Build.Gradle文件 UPD.这个简单的应用程序可以加载图片从互联网,但它不能加载图片从我的服务器。我的服务器的一些图片加载得很好,但其他的不是。我已经迷路了

  • 我正在尝试加载存储在应用程序文件夹上的图像当我打开活动时,我从logcat收到了这个错误: 1-20 01:30:40.125 14331-14331/mx.eusaga。af W/ImageView:无法打开内容:content://mx.eusaga.af.fileprovider/imagenes/1-db384fa8-f28b-4595-abbf-d45d38fd4036.jpgjava.

  • 这是我写的加载图像图标的代码。你能建议我需要做什么吗,因为我得到一个错误: java.lang.RuntimeException:无法编译的源代码-错误的sym类型:ImageDisplayTest.class.getClassLoader

  • 我使用滑翔库来显示网格视图中的图像,但是在我的图像视图中显示了注释。 E/Glide:class com。邦普泰克。滑行负载发动机GlideException:无法加载资源 我的代码在使用位图时工作正常。这是我的密码: