JSP,JavaScript:将byte []显示为图像

时间:2017-12-21 18:13:00

标签: javascript java html jsp

我正在使用以下代码段从文件中选择和读取图像:

<div class="col-md-6 form-group">
<input type='file' name="image" onchange="readURL(this);"
                    class="form-control" /> 
<img id="userimg" src="#" alt="" />
</div>

的.js:

function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();

        reader.onload = function (e) {
            $('#userimg')
                .attr('src', e.target.result)
                .width(150)
                .height(200);
        };

        reader.readAsDataURL(input.files[0]);
    }
}

在我的servlet中,我将文件转换为byte[]

(request.getParameter("image")).getBytes()

并将其插入数据库。

然后,我尝试从数据库中读取它并显示在.jsp页面中,如下所示:

的.jsp

  <div class="panel panel-success">
                        <h2>Pictures</h2>
                        <%
                            List<byte[]> pics = PictureTable.getConcertPictures(concertBean.getId());
                        %>
                        <%
                            for (byte[] p : pics) {
                                String encoded = ImageHelper.encodeImage(p);
                        %>
                        <img src="data:image/jpg;base64,<%=encoded%>">
                        <%
                            }
                        %>
    </div>

ImageHelper.java:

public static String encodeImage(byte[] img) {
        return Base64.encode(img);
    }

但图像未正确显示 (某些内容会插入到数据库中)。

修改

我修改了我的代码:

的.jsp:

<div class="comments">
                <div class="panel panel-success">
                    <h2>Pictures</h2>
                    <%
                        List<byte[]> pics = PictureTable.getConcertPictures(concertBean.getId());
                    %>
                    <%
                        for (byte[] p : pics) {
                            String encoded = ImageHelper.encodeImage(p);
                    %>
                    <img src="data:image/jpg;base64,<%=encoded%>">
                    <%
                        }
                    %>
                </div>
                <!-- /container -->
                <form
                    action="GalleryController?action=add_concert_picture&concertID=<%=concertBean.getId()%>"
                    method="post" class="panel panel-success"
                    enctype="multipart/form-data">
                    <div class="col-md-6 form-group">
                        <input type='file' name="image" class="form-control" />
                    </div>
                    <button type="submit" class="btn">Submit</button>
                </form>
            </div>

的servlet:

Part filePart = request.getPart("image");
InputStream fileContent = filePart.getInputStream();
PictureTable.insertConcertPicture(cid, user.getUser().getId(), fileContent);

PictureTable.java:

public static void insertConcertPicture(int concertId, int userId, InputStream photo) {
        try (Connection connection = ConnectionPool.getConnectionPool().checkOut()) {

            PreparedStatement ps = connection
                    .prepareStatement("INSERT INTO concertphototable(ConcertId, UserId, Photo) VALUES(?,?,?)");

            ...
            ps.setBinaryStream(3, photo);

            ps.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

图片仍未正确显示,但现在提交&#34;提交&#34;页面的一部分甚至不可见。

2 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点。我会返回base64 String并将其存储在数据库中。然后你可以将它返回给JSP来渲染它。

要做到这一点,你必须:

<input type="file" name="file" onchange="encodeImageFileAsURL(this)" />
<form method="POST" action="/upload">
    <input id="image" type="text" name="image" value="asdf" /><br />
    <br /> <input type="submit" value="Submit" />
</form>
<script type="text/javascript">
    function encodeImageFileAsURL(element) {
        var file = element.files[0];
        var reader = new FileReader();
        reader.onloadend = function() {
            document.getElementById("image").value = reader.result;
        }
        reader.readAsDataURL(file);
    }
</script>

在/ upload控制器中:

@PostMapping("/upload")
public ModelAndView singleFileUpload(@RequestParam("image") String image, RedirectAttributes redir) {
    jdbcTemplate.update("INSERT INTO concertphototable(ConcertId, UserId, Photo) VALUES(?, ?, ?)", 1, 1, image);
    String imageString = jdbcTemplate.queryForObject("Select Photo from concertphototable where ConcertId = " + 1,
            String.class);
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("redirect:uploadStatus");
    redir.addFlashAttribute("image", imageString);
    return modelAndView;
}

然后到uploadStatus页面:

<img src=${image}>

不要混淆Spring部分,你应该记住,你必须将base64字符串从jsp发布到服务器然后存储它。然后将其检索为String并将其传递给图像src标记中的jsp,将显示图像。如果您没有特定的理由将图像作为blob存储到数据库中,则必须按照上述方式进行。

答案 1 :(得分:1)

我相信你的一些问题是技术性的,有些是与方法有关的。我的回答主要集中在方法论上。

我们使用JavaScript客户端和C#Web API服务器做了类似的事情。我们采用了一种非常简单的开发/验证模型(下面),使我们能够在数据经历转换的每个点快速找到并隔离错误。

我们最初在遇到您遇到的许多相同问题时遇到了困难。我们如何解决问题可能对您有所帮助。

用户tsolakp提出了一个很好的观点。您应该考虑直接返回字节数据。如果你打算从客户端到服务器的二进制文件,那么我建议你认真考虑下载数据。我们对大多数数据使用二进制上传/下载。我知道现在这不流行,但它确实在我们的系统中更有效率。

你提到过:

  

SRC =&#34;数据:图像/ JPG; BASE64,/ 9J / 4AAQSkZJRgABAQEAAAAAAAD / 4Zf2RXhpZgAATU0AKgAAAAg ...这   继续为veeeeeeery做好准备。

这是你可以控制的。我建议你创建一个非常小的jpeg,它可以被人类轻松读取/验证,并用它来逐步验证你的上传和下载流程。

我们在javascript客户端上传二进制数据时使用了以下代码流。

&#13;
&#13;
var byte[] = atob(jpeg string);
var xhr = new XMLHttpRequest();
xhr.open...
xhr.onload...
xhr.setRequestHeader("Content-type", "application/octet-stream");
xhr.send(new Uint8Array(byte[]));
&#13;
&#13;
&#13;

我们使用了一个非常小的jpeg(例如,5x10px),因此在数据流的每一步都很容易验证。

  1. 将jpeg字符串转换为byte [],然后将其转换回字符串并验证它以确保一切正常。

  2. 如上面的Http代码所示,我们不得不将JavaScript byte []转换为Uint8Array(byte []),以便将其传输到服务器。在我们将它发送到服务器之前,我们将其转换回byte [],然后转换为jpeg字符串格式以验证到此点的整体流程。我们发现了一些容易识别的问题,可以通过打破这些小块来实现。

  3. 我们到目前为止,我们添加了客户端 - 服务器通信。到达服务器后,我们验证服务器上的二进制数据与步骤2中提取的客户端数据相匹配。

  4. 在将数据存储到服务器之前,我们将上传的数据返回给客户端,以再次验证它在每个点是否相同并且可以正确解码。在这里,我们发现了一些问题并确定了对媒体转换器的需求(您的Java问题可能会有所不同)。

  5. 最后,一旦数据得到验证,我们就会以类似的方式逐步完成系统数据存储过程。

  6. 我们通过采取小的渐进步骤将数据推送到服务器并检索它,从而揭示了6-7个问题。最初我们完成了整个端到端的事情并且打破了一堵墙。这就是为什么我们切换到一块餐开发/验证过程。我的价值2美分。

    如果你打破问题,它可能有助于解决你在这里提到的问题:

      

    但图像显示不正确(某些内容会插入到数据库中)。

    在整个数据路径中,这一点非常重要。

    我知道你的系统上的下载代码会有所不同,但我已经将我们的下载代码用于说明,如果不将问题分解成更小的部分,有许多顺序步骤会引入容易被屏蔽的错误。

    &#13;
    &#13;
    var xhr = new XMLHttpRequest();
    xhr.open...
      xhr.responseType = "arraybuffer";
    xhr.onload... = () => {
        if (xhr.status === 200) {
          var arrayBuffer = xhr.response;
          var unsigned8Int = new Uint8Array(arrayBuffer);
          // Here we had to convert the unsigned8bit array back to a JavaScript array.
          // Then convert js byte[] to a string and prepend the image header as
          // you are doing in your code.
          //
          // The last step was to prepend the image header as you are doing, but
          // we used binary to asci. 
          var data = "data:image/jpeg;base64," + btoa(byte[]);
    
        };
        xhr.setRequestHeader("Content-type", "application/octet-stream");
        xhr.send();
    &#13;
    &#13;
    &#13;

    我多年没有使用过Java,但我会看看是否可以挖掘一些可能与您的实际设计相关的技术信息。