JSP,JavaScript:显示字节[]作为图像



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

<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();
        }
    }

该图像仍未正确显示,但是现在页面的"提交"部分甚至不可见。

有很多方法可以做这个。我将返回base64字符串并将其存储在数据库中。然后,您可以将其退还给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>

在您的/上传控制器中:

@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;
}

,然后到上载页面:

<img src=${image}>

不要对您应该牢记的弹簧部分感到困惑,即您必须将Base64字符串从JSP发布到服务器,然后将其存储。然后,将其作为字符串检索,然后将其传递到图像SRC标签中的JSP,并显示图像。如果您没有特定原因将图像存储为blob到数据库中,则必须使用上述方式。

我相信您的某些问题是技术性的,有些是与方法相关的。我的反应主要集中于方法。

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

我们最初在您似乎遇到的许多相同问题上苦苦挣扎。我们如何解决我们的问题可能会为您提供一些帮助。

用户tsolakp提出了一个很好的观点。您应该考虑直接返回字节数据。如果您要从客户端到服务器二进制二进制,那么我也建议您认真考虑下载数据。对于大多数数据,我们使用二进制上传/下载。我知道这不是当今的时尚,但是在我们的系统中肯定会更有效。

您提到:

src =" data:image/jpg; base64,/9J/4aaqskzjrgabaqeaaaaaaaaaaaad/4zf2rxhpzgaatu0akgaaaag ...这个 继续为veeeeeeyery长。

这是您可以控制的东西。我建议您创建一个非常小的JPEG,该JPEG易于通过人类阅读/验证,并使用它来逐步验证您的上传和下载流量。

我们在二进制数据的JavaScript客户端上使用以下代码流。

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[]));

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

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

  2. 如上述HTTP代码所示,我们必须将JavaScript Byte []掩盖到Uint8array(Byte [])以将其传输到服务器。在将其发送到服务器之前,我们将其转换回字节[],然后转换为JPEG字符串格式,以验证到达这一点的整体流程。我们发现了几个问题,可以通过将流量分解为这些小块来易于识别。

  3. 一旦我们走了这么远,我们添加了客户端服务器通信。到达服务器后,我们验证了服务器上的二进制数据是否与步骤2中提取的客户端数据匹配。

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

  5. 最后,一旦数据验证到这一点,我们然后以类似的方式踏入系统数据存储过程。

我们有6-7个问题通过采取小型渐进步骤将数据推向服务器并检索它来揭示。最初,我们做了整个端到端的事情,并撞到了断墙。这就是为什么我们转到零食开发/验证过程的原因。我的2美分。

如果您解决问题,它可能有助于解决您在此处提到的问题:

但是图像未正确显示(确实将某些内容插入了数据库中)。

沿数据路径一直很重要。

我知道您的系统上的下载代码会有所不同,但是我包括了我们的下载代码,以说明有许多顺序的步骤可以引入错误,如果您不将问题分解为较小的部分,则很容易掩盖。

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();

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

最新更新