zoukankan      html  css  js  c++  java
  • web应用图片存取体验我们到底能走多远系列(19)

    我们到底能走多远系列(19)

    扯淡: 连续加班,效率急剧下降中.....

    遇到存图片的问题,解决方案很多,时间太紧,从简单方式开始学习吧。

    1,把图片存到数据库里,用的时候把它取出来。取出来有有个选择是需要一个零时文件来存,用路径在页面显示,这样问题比较多,不建议使用。

    另一种方式就是直接把取出来的二进制文件传给页面,如下结合ibatis实现:

    bean代码:

    注意:license字段和identityCard字段是byte[],在数据库中我们采用clob来定义(orcale数据库)。
    View Code
    public class Dealer extends User {
    
        /**
         * 
         */
        private static final long serialVersionUID = -7791699407718373300L;
        private String contact;
        private String contactPhone;
        private String payee;
        private String accountNumber;
        private int bankType;
        private String bankName;
        private byte[] license;
        private byte[] identityCard;
        private String opinion;
        private Long industryId;
        private Long userId;
        private Long parentUserId;
    
        public int getBankType() {
            return bankType;
        }
    
        public void setBankType(int bankType) {
            this.bankType = bankType;
        }
    
        public byte[] getLicense() {
            return license;
        }
    
        public void setLicense(byte[] license) {
            this.license = license;
        }
    
        public byte[] getIdentityCard() {
            return identityCard;
        }
    
        public void setIdentityCard(byte[] identityCard) {
            this.identityCard = identityCard;
        }
    
        public String getContact() {
            return contact;
        }
    
        public void setContact(String contact) {
            this.contact = contact;
        }
    
        public String getContactPhone() {
            return contactPhone;
        }
    
        public void setContactPhone(String contactPhone) {
            this.contactPhone = contactPhone;
        }
    
        public String getPayee() {
            return payee;
        }
    
        public void setPayee(String payee) {
            this.payee = payee;
        }
    
        
    
        public String getAccountNumber() {
            return accountNumber;
        }
    
        public void setAccountNumber(String accountNumber) {
            this.accountNumber = accountNumber;
        }
    
        public String getBankName() {
            return bankName;
        }
    
        public void setBankName(String bankName) {
            this.bankName = bankName;
        }
    
        public String getOpinion() {
            return opinion;
        }
    
        public void setOpinion(String opinion) {
            this.opinion = opinion;
        }
    
        public Long getIndustryId() {
            return industryId;
        }
    
        public void setIndustryId(Long industryId) {
            this.industryId = industryId;
        }
    
        public Long getUserId() {
            return userId;
        }
    
        public void setUserId(Long userId) {
            this.userId = userId;
        }
    
        public Long getParentUserId() {
            return parentUserId;
        }
    
        public void setParentUserId(Long parentUserId) {
            this.parentUserId = parentUserId;
        }
    
    }
    ibatis的sqlMap文件中一个正常的插入语句:
        <insert id="addDealer" parameterClass="dealer">
    
             insert into tb_Dealer (CONTACT, CONTACT_PHONE, PAYEE, ACCOUNT_NUMBER, BANK_TYPE, BANK_NAME, LICENSE, IDENTITY_CARD, OPINION,USER_ID,PARENT_USER_ID)
             values (#contact#, #contactPhone#, #payee#, #accountNumber#, #bankType#, #bankName#, #license#, #identityCard#, #opinion#,#userId#, #parentUserId#)
    
        </insert>

     以下是示例代码:把流写到response里即可。

        public ModelAndView showLicenseImage(HttpServletRequest request, HttpServletResponse response) {
    
            User user = (User) request.getSession().getAttribute("user");
            Dealer dealer = dealerService.getById(user.getId());
            
            byte[] license = dealer.getLicense();
            try {
                ServletOutputStream outStream = response.getOutputStream();
                response.setContentType("image/*"); // 设置返回的文件类型  
                outStream.write(license); // 输出数据  
            } catch (IOException e) {
                
                e.printStackTrace();
            }
            return null;
        }

     这是页面img标签的写法,注意src属性,是后台地址

    <img src="showCardImage.html" width="80" height="40" />

     2,页面 上传图片(就是文件嘛)

    利用spring mvc的框架,比较轻松就可以实现:

    control层的关键代码:request转型MultipartHttpServletRequest 取出MultipartFile,代码还利用了spring的FileCopyUtils工具,实现相对路径存数据库,文件存文件夹。

    // 处理上传图片
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            // 取得图片
            MultipartFile newImageFile = multipartRequest.getFile("newImage");
            SimpleDateFormat df = new SimpleDateFormat(BusinessConstants.DATE_FORMAT);
            String filename = newImageFile.getOriginalFilename();
            String file_ext = filename.substring(filename.lastIndexOf(BusinessConstants.DOT) + 1);
            // 图片文件名
            String imageName = newImageFile.getName() + df.format(new Date()) + BusinessConstants.DOT
                    + file_ext;
            byte[] advImageBytes = null;
            InputStream advImageStream = null;
            // 存放图片的路径
            File file = new File(request.getSession().getServletContext().getRealPath(
                    BusinessConstants.IMAGE_FILE_PATH + imageName));
            File oldFile = new File(request.getSession().getServletContext().getRealPath(
                    BusinessConstants.IMAGE_FILE_PATH + oldImageName));
            try {
                file.createNewFile();
                advImageStream = newImageFile.getInputStream();
                advImageBytes = FileCopyUtils.copyToByteArray(advImageStream);
                FileCopyUtils.copy(advImageBytes, file);
                advImageStream.close();
                // 删除原图片
                oldFile.delete();
            } catch (IOException e) {
    
                e.printStackTrace();
            }

    multipartResolver的配置如下:

        <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 设置上传文件的最大尺寸为1MB -->
            <property name="maxUploadSize">
                <value>1000000000000</value>
            </property>
        </bean>

    在 Spring 中,MultipartResolver 主要用来处理文件上传,它支持 Commons FileUpload (http://jakarta.apache.org/commons/fileupload) 和 COS FileUpload (http://www.servlets.com/cos)。 缺省中Spring是没有multipart处理,因为一些开发者想要自己处理它们。

    如果你想使用Spring的multipart,需要在web应用的上下文中添加multipart解析器。这样,每个请求就会被检查是否包含 multipart。然而如果请求中包含multipart,你的上下文中定义的MultipartResolver就会解析它。这样你请求中的 multipart属性就会象其它属性一样被处理。

     说白了配置multipartResolver就是为了在上面的代码可行:

    MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
    
    // 取得图片
    
    MultipartFile newImageFile = multipartRequest.getFile("newImage");

    特别注意点:

    上传的表单中必须指定其 enctype 为 mulitpart/form-data

    3,button模拟file标签,很多地方在上传文件的按钮是一个button,或者是图片,可是ie对file有所谓的安全限制,如果是file触发的事件涉及提交表单,就必须是鼠标真是点击浏览按钮过后。网上有人利用button的onclik事件指向file的onclik事件,来实现点击button相当于点击浏览,但是表单在file的onchange事件中无法提交。

    所以有了以下的解决方案,原理是鼠标移动到button时,吧file按钮带到鼠标下,因为file按钮设置成透明,这样就可以实现实际点击了:

    看效果可以把opacity 设成50,你懂的。

    html:

        <div id="tt" style="position:relative; margin-right:400px;">
                <input type="button" id="batchButton1" value="批量上传" onmouseover="floatFile('file1')" style="height:28px; 80px;">
                <div id="div1">
                    <div id="file1text" ></div>
                    <input id="file1" name="myfile" type="file" onchange="batchRelease()" style="position:absolute;filter:alpha(opacity=0);height:28px; 40px;">
                    
                </div>
    
            </div>

    js:

    function floatFile(id)
        {   
        
            document.getElementById(id).style.posTop=event.srcElement.offsetTop;
            document.getElementById(id).style.posLeft=event.x-document.getElementById(id).offsetWidth/2;
        }
        //选择完一个文件之后,自动创建一个新的div 和 file表单,用于下回使用,hidden刚用过的file
        function showText(obj)
        {
            $(obj.id+"text").innerHTML=obj.value+"&nbsp;&nbsp;<a href='javascript:del("+fileNum+")'>删除</a>";
            $("file"+fileNum).style.display='none';
            fileNum=fileNum+1;
            //直接追加innerHTML(innerHTML+=)会清空原来file中的内容
            $("div"+(fileNum-1)).insertAdjacentHTML('AfterEnd','<div id="div'+fileNum+'"><div id="file'+fileNum+'text" ></div><input id="file'+fileNum+'" name="myfile" type="file"  onchange="showText(this)"  style="position:absolute;filter:alpha(opacity=0);30px;"hidefocus></div>');
        }

    目前项目还在继续,很多图片的问题还没有解决,还在寻求比较好的方案中,特别有一个是图片剪切浏览这个,各位有好方案的,能发个链接,或指点一下,感激不尽。

    让我们继续前行

    ----------------------------------------------------------------------

    努力不一定成功,但不努力肯定不会成功。
    共勉。

  • 相关阅读:
    一般工程文件和DLL工程文件区别
    [转载 js]javascript的陷井
    函数两种定义方法的区别
    D2视频补完,哈哈,有我的镜头
    YUI中js的继承示例
    状态模式
    YUI2.x和YUI3的差别
    函数两种定义方法的区别
    YUI中js的继承示例
    D2视频补完,哈哈,有我的镜头
  • 原文地址:https://www.cnblogs.com/killbug/p/2852906.html
Copyright © 2011-2022 走看看