也许我不太了解servlet的生命周期,但这就是我想要的: 我想显示一个servlet生成的页面让我们说servlet:paginaAmd。 在此页面上,我想显示存储在Web服务器上的文件夹中的图像列表。 图像的URL地址如下: / IMG / 80-80-1-1-1-1-1-1-1-1-1 其中/ img / *是我用于显示图像的servlet。
如果我想在浏览器中一次显示一个图像,那么一切正常。 但是,当我想立即放入所有列表时,图像无法正确显示。有时根本不显示,有时显示在错误的位置(位置不会及时改变),有时只显示一些图像。
我怀疑不是所有的doGet()方法都被捕获了。
有人可以给我一些建议吗? 以下是本教程实现的servlet代码:http://balusc.blogspot.fr/2007/04/imageservlet.html
@WebServlet(name = "ImgDisplay", urlPatterns = {"/img/*"})
public class ImgDisplay extends HttpServlet
{
private SessionFactory sessionfactory = new AnnotationConfiguration().configure().buildSessionFactory();
private Query query;
private String mesajEroare = "";
private HttpServletRequest _request;
private HttpServletResponse _response;
private int width = 0;
private int height = 0;
private int idImagine = 0;
private int format = 0;
private String titluArticol = "";
private String numeImagine = "";
private boolean imgValida = false;
private int DEFAULT_BUFFER_SIZE = 1024 * 100;
String fileUploadPath = "";
@Override
public void init() throws ServletException {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
this._request = request;
this._response = response;
this.SetVariabile();
if(imgValida)
{
String nImagine = this.GetImageFromDisk();
this.DisplayImage(nImagine);
}
}
private void SetVariabile()
{
String reqUrl = _request.getRequestURL().toString();
String aUrl[] = reqUrl.split("/");
String urlImg = aUrl[aUrl.length - 1];
aUrl = urlImg.split("-");
try
{
this.width = Integer.parseInt(aUrl[0]);
this.height = Integer.parseInt(aUrl[1]);
this.idImagine = Integer.parseInt(aUrl[2]);
this.format = Integer.parseInt(aUrl[3]);
this.numeImagine = aUrl[aUrl.length - 1];
this.imgValida = true;
}
catch(Exception e)
{
this.imgValida = false;
}
}
private String GetImageFromDisk()
{
String nImagine;
//preiau imaginea
PaginiImagini pa = new PaginiImagini();
Session session;
try
{
session = sessionfactory.openSession();
session.beginTransaction();
query = session.getNamedQuery("PaginiImagini.findByImagineID");
query.setInteger("imagineID", this.idImagine);
pa = (PaginiImagini) query.uniqueResult();
session.getTransaction().commit();
session.close();
}
catch( Exception e )
{
this.mesajEroare = "Nu pot citi din baza de date!";
}
// citesc imagine de pe disk
ServletContext sctx = getServletContext();
this.fileUploadPath = sctx.getInitParameter("file-upload-path");
String pathImagine = this.fileUploadPath + "/" + Setari.pathImaginiMici;
if(this.width > Setari.wImagineMica || this.height > Setari.hImagineMica)
{
pathImagine = this.fileUploadPath + "/" + Setari.pathImaginiMari;
}
nImagine = pathImagine + "/" + pa.getNumeImaginePeDisc();
return nImagine;
}
private void DisplayImage(String imageToRead) throws FileNotFoundException, IOException
{
File image = new File(imageToRead);
String contentType = getServletContext().getMimeType(image.getName());
_response.setContentType(contentType);
_response.setHeader("Content-Length", String.valueOf(image.length()));
_response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
_response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
_response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
_response.setDateHeader("Expires", 0); // Proxies.
// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;
try
{
// Open streams.
input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(_response.getOutputStream(), DEFAULT_BUFFER_SIZE);
// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0)
{
output.write(buffer, 0, length);
}
}
finally
{
// Gently close streams.
close(output);
close(input);
}
}
/**
*
* @param resource
*/
private static void close(Closeable resource)
{
if (resource != null)
{
try
{
resource.close();
}
catch (IOException e)
{
// Do your thing with the exception. Print it, log it or mail
// it.
//e.printStackTrace();
}
}
}
}
答案 0 :(得分:2)
您的servlet中存在严重的并发问题。 servlet的单个实例用于提供对此servlet的所有请求。因此servlet应该是无状态的。但你要做的第一件事是
this._request = request;
this._response = response;
这意味着如果对servlet发出两个并发请求,则可能让第一个设置这两个实例变量,然后第二个重置相同的实例变量。因此,第一图像将作为对第二请求的响应而被发送,并且不会将任何内容作为对第一请求的响应而发送。这只是可能发生的奇怪事情之一。您也可能有异常和不一致的数据。
不要将请求和响应(以及任何其他状态)存储在实例变量中。将它们从方法传递给方法。我没有分析整个代码,但是servlet中唯一的实例字段是sessionFactory字段。