有关上传图片的个人理解

背景

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

我要写的内容是:原本上传营业证书的格式是图片,后来改为也可以上传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!

原文地址:https://www.cnblogs.com/miaoww/p/8556863.html