如何通过Java Servlet与Ajax获取并展示JPG图片?
解决方法:将Servlet返回的图片显示到页面上
你的核心问题在于当前的Ajax请求默认是处理文本响应,但Servlet返回的是图片二进制数据,所以需要调整处理方式。这里给你两种方案,推荐第一种,更简单直接:
方案1:直接用img标签的src指向Servlet(推荐)
不需要用Ajax,直接把请求参数拼在Servlet的URL后面,赋值给img元素的src,利用img标签的原生加载能力:
修改JS代码
function getImage(page) { // 获取页面上的img元素(替换成你实际的元素ID) const targetImg = document.getElementById("your-image-element-id"); // 拼接请求参数,设置src targetImg.src = `GetImageServlet?bookIDIn=${currentBook.id}&userIDIn=${currentBook.ownerID}&pageIn=${page}`; // 处理图片加载失败的情况 targetImg.onerror = function() { document.getElementById("serverErrorCode").innerHTML = "101_GETIMAGE_ERR"; showErrorModal(); }; }
调整Servlet代码
原来的Servlet在参数无效时返回"false"文本,这会导致img加载失败(因为文本不是合法图片),建议改成返回HTTP错误状态码,更符合规范:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String ownerID = request.getParameter("userIDIn"); String bookID = request.getParameter("bookIDIn"); String page = request.getParameter("pageIn"); boolean resp = ownerID != null && bookID != null && page != null; if(resp){ resp = !ownerID.isEmpty() && !bookID.isEmpty() && !page.isEmpty(); } if(resp){ String root = baseRoot + ownerID + "\\" + bookID + "\\page\\p" + page + ".jpg"; ServletContext cntx = request.getServletContext(); String mime = cntx.getMimeType(root); if (mime == null) { response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; } response.setContentType(mime); File file = new File(root); response.setContentLength((int)file.length()); try (FileInputStream in = new FileInputStream(file); OutputStream out = response.getOutputStream()) { byte[] buf = new byte[1024]; int count = 0; while ((count = in.read(buf)) >= 0) { out.write(buf, 0, count); } } // try-with-resources自动关闭流,更安全 } else { // 替换原来的print("false"),返回400错误状态码 response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } }
这样当参数无效时,img的onerror事件会触发,直接执行你的错误处理逻辑。
方案2:用Ajax处理二进制响应(如果必须用Ajax)
如果业务场景必须用Ajax请求,需要修改Ajax的响应类型为blob,然后将二进制数据转成可用于img的URL:
修改JS代码
function getImage(page) { const xhr = new XMLHttpRequest(); xhr.open("POST", "GetImageServlet", true); // 关键:设置响应类型为blob(二进制数据) xhr.responseType = "blob"; // 设置表单编码类型 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 拼接请求参数 const formData = `bookIDIn=${currentBook.id}&userIDIn=${currentBook.ownerID}&pageIn=${page}`; xhr.onload = function() { if (xhr.status === 200) { // 将blob转成临时URL const imgUrl = URL.createObjectURL(xhr.response); const targetImg = document.getElementById("your-image-element-id"); targetImg.src = imgUrl; // 图片加载完成后释放临时URL,避免内存泄漏 targetImg.onload = function() { URL.revokeObjectURL(imgUrl); }; } else { // 请求失败处理 document.getElementById("serverErrorCode").innerHTML = "101_GETIMAGE_ERR"; showErrorModal(); } }; xhr.onerror = function() { document.getElementById("serverErrorCode").innerHTML = "102_GETIMAGE_ERR"; showErrorModal(); }; xhr.send(formData); }
同样建议调整Servlet的错误返回逻辑(和方案1一样返回错误状态码),这样能更准确地判断请求是否成功。
内容的提问来源于stack exchange,提问作者Erich Brahmin
相关产品推荐
相关产品推荐

