表vaadin版本7.6.3中的图像损坏

时间:2016-03-16 18:01:13

标签: java blob vaadin inputstream

当我滚动到表格底部并且表格加载内容时,我的图片(来自 StreamResource 的图片嵌入式,我将图像存储为数据库中的blob)弄坏了。

包含 Embedded 图像的第一行表格显示得很好,但当我向下滚动时,看起来很好的图片会被破坏。

getAllPartners 方法(这里我从数据库加载blob图像):

public static Vector<PartnerDto> getAllPartner() {
        Vector<PartnerDto> result = null;

        PreparedStatement st = null;
        Connection conn = null;
        ResultSet rs = null;
        try {
            conn = Connect.getConnection();
            String sql = "select part_id,name, surname, picture from partner order by name, surname ";
            st = conn.prepareStatement(sql);
            System.out.println(sql);
            st.execute();
            rs = st.getResultSet();
            result = new Vector<PartnerDto>();
            while (rs.next()) {
                PartnerDto dto = new PartnerDto();
                dto.setPart_id(rs.getInt("part_id"));
                dto.setName(rs.getString("name"));
                dto.setSurname(rs.getString("surname"));
                Blob imageBlob = rs.getBlob("picture");
                if(imageBlob!=null){
                    InputStream binaryStream = imageBlob.getBinaryStream(1, imageBlob.length());                
                    dto.setPicture(binaryStream);
                }else{
                    dto.setPicture(null);
                }
                result.addElement(dto);
            }
        } catch (SQLException e) {
            result = null;
            e.printStackTrace();
            System.out.println(e);
        } finally {
            Connect.closeConnection(rs, st, conn);
        }
        return result;
    }

我的表(t合作伙伴)初始化:

        tPartners.addContainerProperty("Slika uporabnika", Embedded.class, null);
        tPartners.addContainerProperty("Ime", String.class, null);
        tPartners.addContainerProperty("Priimek", String.class, null);
        tPartners.addContainerProperty("Rojstni datum", String.class, null);
        tPartners.addContainerProperty("Rojstni kraj", String.class, null);
        tPartners.addContainerProperty("Naslov", String.class, null);
        tPartners.addContainerProperty("Pošta", String.class, null);
        tPartners.addContainerProperty("Emšo", String.class, null);
        tPartners.addContainerProperty("Šola", String.class, null);
        tPartners.addContainerProperty("Razred", String.class, null);
        tPartners.addContainerProperty("Poklic", String.class, null);
        tPartners.addContainerProperty("Telefon", String.class, null);
        tPartners.addContainerProperty("Mail", String.class, null);
        tPartners.addContainerProperty("Klubska številka", String.class, null);
        tPartners.addContainerProperty("Številka kartice", String.class, null);
        tPartners.addContainerProperty("Datum včlanitve", String.class, null);
        tPartners.addContainerProperty("Opomba", String.class, null);
        tPartners.addContainerProperty("File type", String.class, null);

        tPartners.setSelectable(true);
        tPartners.setImmediate(true);

下面的代码显示我如何在表格中加载图片

             //get all partners
             Vector<PartnerDto> vResutl = DBLogika.searchPartner(text);

            for (int i = 0; i < vResutl.size(); i++) {
                //class that represent PartnerDto
                PartnerDto dto = vResutl.elementAt(i);

                String bd = "";
                String din = "";

                if (dto.getBorn_date() != null) {
                    bd = sdf.format(dto.getBorn_date());
                }

                if (dto.getDate_in() != null) {
                    din = sdf.format(dto.getDate_in());
                }

                Embedded emb=new Embedded();

                StreamResource.StreamSource source = new StreamResource.StreamSource() {

                    public InputStream getStream() {
                         //get inputstream from database, I save my image as longblob in database
                         return dto.getPicture();

                    }

                 };

               //uniq name for every file
               SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
               String filename = "mytablepic" + df.format(new Date()) + ".png";

               StreamResource sourceone=new StreamResource(source, filename);

               emb.setHeight("200px");
               emb.setWidth("150px");

               emb.setSource(dto.getPicture()==null? new ThemeResource("images/user_pic.jpg"): sourceone); 

                 tPartners.addItem((new Object[] {emb, dto.getName(), dto.getSurname(), bd, dto.getBorn_place(), dto.getAddress(),
                            dto.getPostDto().getPostName(), dto.getEmso(),
                            dto.getSchool(), dto.getPartClass(), dto.getJob(), dto.getPhone(),
                            dto.getMail(), dto.getClub_number(), dto.getCard_number(),
                            din, dto.getDesc(),dto.getFileextention()}), dto);

            }

我做错了什么?

显示我问题的两张图片:

  1. how looks first time when I load content in table
  2. broken image picture, when I scroll for example to the top, and then back to top
  3. 我在 Tomcat v8.0服务器上的localhost上运行我的应用程序。

    当我使用Firebug在Firefox中检查图像时,它告诉我:无法加载图像。

    不知何故,当我滚动,并且表格需要加载它时,图像会被破坏......

    我怎么能解决这个问题?请帮帮我: - )

1 个答案:

答案 0 :(得分:0)

<强> SOLUTION:

Max Schuster in the Vaadin Forums回答:

我认为你无法重用InputStream。尝试将数据作为字节数组存储在DTO中,并在每次调用StreamSource#getStream时返回一个新的(ByteArray)InputSteam实例。

但是这种方法会让你的ram很难,因为你必须将所有图像保存在服务器内存中。即使你不需要它们。

我建议您创建一个自定义StreamSource实现,每次调用StreamSource#getStream时都会从数据库接收图像。因为如果客户端浏览器要求它,您只需要图像数据。这样,如果不再需要图像数据,则可以对其进行垃圾收集。