[英]Images are not being displayed properly over JSP
我正在尝试开发一个网站,当我们从以前的JSP的下拉列表中选择该实体时,将在JSP上显示与特定实体相关的图像。我正在从MySQL数据库中获取图像。 我试图在Oracle Weblogic 12c和Apache Tomcat 7.x中都部署应用程序。 而且我都面临着几乎类似的问题。
A. Weblogic-仅用于显示一个图像(如果数据库中有与该下拉菜单相关的多个图像),并且也是第一次尝试显示。 对于其余的尝试,我得到以下错误:
java.net.ProtocolException:不满足声明的Content-Length,写为:“ 0”字节而不是声明
条件1 :仅显示一个图像(自启动服务器以来首次访问应用程序时间),即使存在与特定下拉列表相关的多个图像
条件2 :如果我按浏览器的“后退”按钮返回,或者再次单击URL(与浏览器无关),则直到并且除非我不重新启动服务器,否则什么都不会显示
A. Tomcat-故事与Tomcat略有不同。在Tomcat的情况下,控制台没有异常
条件1 :仅显示一个图像(自启动服务器以来首次访问应用程序时间),即使存在与特定下拉列表相关的多个图像。 将所有曾经显示为残缺的图像搁置几秒钟,直到页面完全加载。当页面完全加载时,只有一个图像曾经存在(第一个),并且所有破碎的图像都消失了
条件2 :如果我通过浏览器后退按钮返回,或者再次点击URL(与浏览器无关),而没有重新启动服务器,则所有图像以前都显示为损坏,并且在页面完全加载时消失了
使用Tomcat图像显示页面之前已被挂起将近5-10秒
相关代码段如下:
MultiimageServlet.java
package com.ankit.controller;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import com.ankit.dao.ImageDAO;
public class MultiImageservlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public MultiImageservlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try
{
int bufferSize = 8192;
BufferedInputStream input1 =null;
BufferedOutputStream output =null;
InputStream input =null;
java.net.URL url1=Thread.currentThread().getContextClassLoader().getResource("Log4j.xml");
DOMConfigurator.configure(url1);
Logger logger = Logger.getLogger(MultiImageservlet.class);
String imageName = request.getPathInfo().substring(1);
logger.info("imageName "+imageName);
List<Object> mixList = ImageDAO.find(imageName);
input = (InputStream) mixList.get(1);
input1 = new BufferedInputStream(input);
logger.info("input "+input);
Blob pic = (Blob)mixList.get(0);
logger.info("Blob "+pic);
int length = (int)pic.length();
response.setContentType("image/jpg");
response.setHeader("Content-Type", getServletContext().getMimeType(imageName));
response.setHeader("Content-Length", String.valueOf(pic.length()));
response.resetBuffer();
response.setHeader("Content-Disposition", "inline; filename=\"" + imageName + "\"");
//ServletOutputStream output = response.getOutputStream();
output = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[bufferSize];
while ((length = input1.read(buffer)) != -1) {
System.out.println("writing " + length + " bytes");
output.write(buffer, 0, length);
}
input1.close();
output.flush();
output.close();
response.flushBuffer();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}}
MultiImages.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org /TR/html4/loose.dtd">
<%@ page import ="org.apache.log4j.*" %>
<%@ page import = "org.apache.log4j.xml.DOMConfigurator" %>
<%
int timeout = session.getMaxInactiveInterval();
response.setHeader("Refresh", timeout + "; URL = login.jsp");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>multiImages</title>
</head>
<body>
<h1> Welcome <%=session.getAttribute("userName") %> </h1>
<% java.net.URL url1=Thread.currentThread().getContextClassLoader().getResource("Log4j.xml");
DOMConfigurator.configure(url1);
Logger logger = Logger.getLogger("multiImages.jsp");
logger.info("inside multiImages.jsp");
%>
<c:forEach items="${imageNames}" var="imageName">
<img src="MultiImageservlet/${imageName}" height="150" width="150">
<%
logger.info("multi servlet executed");
%>
</c:forEach>
<a href="logout.jsp"><b>Logout</b></a>
</body>
</html>
在每种情况下看起来都像缓冲区大小问题。有人可以提出建议。在同一件事上几乎卡了4-5天。
我认为您的错误是由设置"Content-Disposition"
标头引起的。 此标头用于使浏览器知道将以内联或附件形式在响应中下载文件。
无论如何,如果我正确地理解了问题,那么这不是您的情况。 您需要创建一个带有图像URL <img src="MultiImageservlet/${imageName}"
的html页面。 浏览器将发出该请求,并期望返回图像的二进制数据而不是下载内容。
以下标头应足以下载:
response.setContentType("image/jpg");
response.setHeader("Content-Type", getServletContext().getMimeType(imageName));
response.setHeader("Content-Length", String.valueOf(pic.length()));
请删除以下行:
response.resetBuffer(); // You shouldn't need this either
response.setHeader("Content-Disposition", "inline; filename=\"" + imageName + "\"");
如果问题仍然存在,我建议尝试使用一个简单的HTML页面,该页面将显示单个图像,然后尝试从该页面进行调试。
希望对您有所帮助
我有我的问题的答案.... :)
实际上来自ImageDAO的数据没有被正确刷新。我通过在每次ImageDAO.find()调用之后清除multiimageServlet中的mixList来修复它。
我也禁用了不必要的标题,因为实际上并不需要这些标题。
感谢您的帮助,cs .. :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.