zoukankan      html  css  js  c++  java
  • 有关上传图片的个人理解

    背景

    最近都没有腾出来时间写博客,今天想把昨天写的有关于上传图片的内容总结一下。

    我要写的内容是:原本上传营业证书的格式是图片,后来改为也可以上传word和pdf格式。所以需要在原来代码的基础上,根据营业证书的地址后缀,判断文件格式是图片or文档or pdf,然后进行不同格式的显示。

    思路

    1.起初打算在前端进行后缀的判断,类似代码如下:

    function checkedImportExcel() {
            var msg = "";
            var fileDir = $("#file").val();
            var suffix = fileDir.substr(fileDir.lastIndexOf("."));
            if (fileDir == "") {
                msg += "选择需要导入的Excel文件! 
     ";
            }
            if (".xls" != suffix && ".xlsx" != suffix) {
                msg += "选择Excel格式的文件导入! 
    ";
            }
            if (msg != "") {
                alert(msg);
                return false;
            }
            $("#formImportExcel").submit();
        }

     可以通过判断营业证地址后缀进行判断,可最终没实现出来。

    2.后来决定在后端进行判断,传到jsp页面时多加一个为后缀的参数,类似代码如下:

     //根据后缀进行判断 营业地址是word还是pdf还是 图片
            if (null != businessLicenseAddress) {
                String[] split = businessLicenseAddress.split(Pattern.quote("."));
                int count = split.length - 1;
                String suffix = split[count];
                if ("png".equals(suffix) | "jpg".equals(suffix) | "jpeg".equals(suffix) | "gif".equals(suffix)) {
                    modelMap.addAttribute("img", "png");
                } else if ("pdf".equals(suffix)) {
                    modelMap.addAttribute("pdf", "pdf");
                } else {
                    modelMap.addAttribute("doc", "doc");
                }
            }

    最后在前端,对接受得参数用c:if进行判断,类似代码如下:

     <c:if test="${not empty img}">
           <p><img src="/hyb-ent/ent_info/findEntInfoLicenceImg/${entListInfoForm.entInfo.id}"
                                 class="img-rounded" alt="" width="50"
                                  height="50">
                                  </p>
     </c:if>
     <c:if test="${not empty pdf}">
          <p>
             <a href="/hyb-ent/ent_info/findEntInfoLicenceDoc/${entListInfoForm.entInfo.id}/${pdf}"
                                   class="btn btn-default glyphicon glyphicon-hand-down">导出营业证书pdf</a>
          </p>
     </c:if>
     <c:if test="${not empty doc}">
           <p>
              <a href="/hyb-ent/ent_info/findEntInfoLicenceDoc/${entListInfoForm.entInfo.id}/${doc}"
                                    class="btn btn-default glyphicon glyphicon-hand-down">导出营业证书doc</a>
           </p>
     </c:if>

    3.  后端导出证书,最开始使用的是URl类,打算通过读取地址,通过Url类进行打开,可是实现的时候总是报错。

      因为在实现的这个功能的时候,营业证书实际上是保存在服务器的,所以不能根据数据库中真实的地址去验证功能是否实现。所以我最开始用的地址都是本机桌面上保存的地址。所以都在c盘。可报错内容为  无法识别字符:c。

      百度发现url在读取本机内容是需要加上字段file:\可依然报错。大概解决了小一天。原来是这种项目在服务器上,文件也保存在服务器上的情况中,不需要使用URL,直接使用File类指定地址进行读取就可以。类似代码如下:

      

     public void downloadBusinessLicense(@PathVariable("address") String address, @PathVariable("filename") String filename, HttpServletResponse response, HttpServletRequest request) {
            FileInputStream fileInputStream = null;
            OutputStream outputStream = null;
            response.setHeader("Content-Disposition", "attachment;fileName=" + address);
            try {
                String filePath = request.getServletContext().getRealPath("/") + File.separator + "file" + File.separator + "MyTest." + filename;
                outputStream = response.getOutputStream();
                fileInputStream = new FileInputStream(new File(filePath));
                System.out.println(filePath);
                byte[] buf = new byte[2048];
                int length = fileInputStream.read(buf);
                while (length != -1) {
                    outputStream.write(buf, 0, length);
                    length = fileInputStream.read(buf);
                }
                outputStream.close();
                fileInputStream.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    有一个知识点也被我忘了,不需要返回输出流,输出流自动就返回。要理解“输出”的含义。且HttpServletResponse类似的类中,提供了getOutputInstream()方法。

    至此,这一部分算是写完可以交差了。可接下来要说的,几乎否定了我一整天的工作。

    <c:if test="${not empty img}">
                                    <p><img src="/hyb-ent/ent_info/findEntInfoLicenceImg/${entListInfoForm.entInfo.id}"
                                            class="img-rounded" alt="" width="50"
                                            height="50">
                                    </p>
     </c:if>


    4.之前也说过了,本来这个功能就可以显示出图片。

    这里要说一个技能点。在前端标签<img src="">,一直以为src后面接的是图片路径,其实不然。src后接的其实是一个输出流对应的url。

    可为什么本地项目启动时,可以直接src后面接一个图片路径,而没有通过controller返回一个输出流?

    因为tomcat和jetty工具,已经封装好了。不过路径和大小都有局限性。

    那为什么src后面接网络图片地址时,也能访问得到?

    因为其实那不是地址,相对应的也是通过地址访问到一个开放的Controller,得到输出流。

    所以,回到项目中去。在原本的项目中,能访问得到图片,那他src后面对应的路径,同样不会是这个照片的绝对路径,而是一个Controller,返回了一个输出流。所以其实,我只要把标签换一下,其他的复制粘贴,我这部分工作早就可以做完了。。。。what????可能没说清楚。我再解释一遍。

    src路径接的是controller,返回的是一个输出流,而OutputStream形式的输出流,都是字节传输。图片、文档、pdf三者之间根本没有区别。所以其实只要在前端把图片标签img换成一个按钮,点击下载,按钮的url和图片的一样。其实就结束了。

    那为什么我自己写的写的代码运行会报错?

    因为营业证书保存的位置在另一个项目下,当前我所写的项目是取不到营业证书的。

    所以历时一天的写代码过程曲曲折折,最后发现其实只需要写两行代码....气得我想吃辣条。

    当然直接这么调用还是有问题的。就是下载的文件没有后缀,需要自己手动加。不过没关系,重新写一个Controller,添加一个消息头

    response.setHeader("Content-Disposition","attachment;fileName="+entId+ "."+suffix);

    Over!

  • 相关阅读:
    php编程规范整理
    约瑟夫环问题的实现
    MYSQL中SHOW的使用整理收藏
    mysql使用存储过程&函数实现批量插入
    浅谈select for update 和select lock in share mode的区别
    jQuery对象扩展方法(Extend)深度解析
    WCF系列教程之WCF操作协定
    WCF系列教程之WCF实例化
    WCF系列教程之WCF中的会话
    WCF系列教程之WCF服务协定
  • 原文地址:https://www.cnblogs.com/miaoww/p/8556863.html
Copyright © 2011-2022 走看看