我正在使用以下代码段从文件中选择和读取图像:
<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;页面的一部分甚至不可见。
答案 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客户端上传二进制数据时使用了以下代码流。
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;
我们使用了一个非常小的jpeg(例如,5x10px),因此在数据流的每一步都很容易验证。
将jpeg字符串转换为byte [],然后将其转换回字符串并验证它以确保一切正常。
如上面的Http代码所示,我们不得不将JavaScript byte []转换为Uint8Array(byte []),以便将其传输到服务器。在我们将它发送到服务器之前,我们将其转换回byte [],然后转换为jpeg字符串格式以验证到此点的整体流程。我们发现了一些容易识别的问题,可以通过打破这些小块来实现。
我们到目前为止,我们添加了客户端 - 服务器通信。到达服务器后,我们验证服务器上的二进制数据与步骤2中提取的客户端数据相匹配。
在将数据存储到服务器之前,我们将上传的数据返回给客户端,以再次验证它在每个点是否相同并且可以正确解码。在这里,我们发现了一些问题并确定了对媒体转换器的需求(您的Java问题可能会有所不同)。
最后,一旦数据得到验证,我们就会以类似的方式逐步完成系统数据存储过程。
我们通过采取小的渐进步骤将数据推送到服务器并检索它,从而揭示了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();
&#13;
我多年没有使用过Java,但我会看看是否可以挖掘一些可能与您的实际设计相关的技术信息。