Servlet图像显示

时间:2013-01-27 16:59:21

标签: java servlets image-processing

也许我不太了解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();
            }
        }
    }



}

1 个答案:

答案 0 :(得分:2)

您的servlet中存在严重的并发问题。 servlet的单个实例用于提供对此servlet的所有请求。因此servlet应该是无状态的。但你要做的第一件事是

this._request = request;
this._response = response;

这意味着如果对servlet发出两个并发请求,则可能让第一个设置这两个实例变量,然后第二个重置相同的实例变量。因此,第一图像将作为对第二请求的响应而被发送,并且不会将任何内容作为对第一请求的响应而发送。这只是可能发生的奇怪事情之一。您也可能有异常和不一致的数据。

不要将请求和响应(以及任何其他状态)存储在实例变量中。将它们从方法传递给方法。我没有分析整个代码,但是servlet中唯一的实例字段是sessionFactory字段。