zoukankan      html  css  js  c++  java
  • 问题集录02--文件上传(可跨域)

    之前工作中遇到了表单跨域上传的问题,寻觅了挺久,才找到解决方法,在此记录。

    一、使用from表单上传

    工作原理:直接表单提交,访问ssc_media的对应接口

    架构说明:使用的是SpringBoot微服务架构,ssc_web负责前端页面和实现对应的后台接口。 ssc_media负责把图片和文件上传到mongodb。

    ${temp}:使用了thymeleaf模块,是一个url路径,指向ssc_media模块的上传文件接口。

    <body>
    <!--直接调用media模块的接口--> <form id= "uploadForm" th:action= "${temp}" method= "post" enctype ="multipart/form-data"> <h1 >测试通过Rest接口上传文件 </h1> <p >上传文件: <input type ="file" name="file" /></p> <input type ="submit" value="上传"/> </form>
    </body>

    当点击“上传”按钮时,会采用“表单提交”方式上传图片,跳转到ssc_media模块的相关接口。

    缺点是:“表单提交”方式上传成功后,会刷新页面。本项目要求:页面局部刷新。

    二、ajax提交

    工作原理:把ssc_web的后台接口当中间层,转发文件流到ssc_media的相关接口

    html:

    <body>
    <!--直接调用media模块的接口-->
    <form id= "uploadForm" enctype ="multipart/form-data">
    <p >上传文件: <input type ="file" name="file"/></p>
    <input type="button" value="上传" onclick="doUpload()"/>
    </form>

    <script language="JavaScript">
    <![CDATA[
    function doUpload() {
         var formData = new FormData($( "#uploadForm" )[0]);
         $.ajax({
              url: "/web/retailer/lotus/outlet/014/uploadDmImg/1" ,
              type: 'POST',
              data: formData,
              async: false,
              cache: false,
              contentType: false,
              processData: false,
              success: function (returndata) {
                  var obj = eval('(' + returndata + ')');
                  alert(obj.data.image);
              },
              error: function (returndata) {
                  alert("no");
              }
         });
    }
    
    ]]>
    </script>
    </body>

    ssc_web的DmController.java:

    /**
         * 上传图片
         * @param retailerCode
         * @param outletExternalId
         * @param dmId
         * @throws IOException
         */
        @RequestMapping(value = "/{retailerCode}/outlet/{outletExternalId}/uploadDmImg/{dmId}", method = RequestMethod.POST )
        @ResponseBody
        public String uploadDmImg(@PathVariable("retailerCode") String retailerCode, @PathVariable("outletExternalId") String outletExternalId,
                                @PathVariable("dmId") Long dmId,@RequestParam("file") MultipartFile multipartFile) throws IOException {
    
            String url = "http://172.19.155.33:9999/media/image/uploadDm?retailerCode="+retailerCode+"&isThumbnail=false&outletExternalId="+outletExternalId+"&dmId="+dmId;
    
            return postFile(url,multipartFile);
        }
    

    //拼请求头,ssc_media的接口要求接收MultipartFile类型文件
    public String postFile(String urlStr,MultipartFile multipartFile) throws IOException { String end = " "; String twoHyphens = "--"; String boundary = "******"; URL url = new URL(urlStr); HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setDoInput(true); httpURLConnection.setDoOutput(true); httpURLConnection.setConnectTimeout(30000); // 必须在Content-Type请求头中指定分界符中的任意字符串 httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); //获取输出流对象,预备上传文件 DataOutputStream dos = new DataOutputStream(httpURLConnection .getOutputStream()); //设置分界符,加end表示单独一行 dos.writeBytes(twoHyphens + boundary + end); //设置与上传文件相关的信息 String filename = multipartFile.getOriginalFilename(); dos.writeBytes("Content-Disposition: form-data; name="file"; filename="" + filename.substring(filename.lastIndexOf("/") + 1) + """ + end); //在上传文件信息与文件的内容之间必须有一个空行 dos.writeBytes(end); InputStream fis = multipartFile.getInputStream(); byte[] buffer = new byte[8192]; // 8k int count = 0; while ((count = fis.read(buffer)) != -1) { dos.write(buffer, 0, count); } fis.close(); dos.writeBytes(end); dos.writeBytes(twoHyphens + boundary + twoHyphens + end); dos.flush(); InputStream is = httpURLConnection.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "utf-8"); BufferedReader br = new BufferedReader(isr); String result = br.readLine(); System.out.println("result = " + result); dos.close(); is.close(); return result; }

    ssc_meida的ImageControlle.java:

    @RequestMapping(value = "/uploadDm", method = RequestMethod.POST)
        public RspVo<DmImageInfoVo> uploadDm(String retailerCode,
                                             String outletExternalId,
                                             Long dmId,
                                             Boolean isThumbnail,
                                             @RequestParam("file") MultipartFile file) {  
               //实现逻辑。。。。。。。。
        }

    额外话题:

    1、若要局部刷新页面,必须是:

    <input type="button" value="确定" />

    若是:

    <button  value="确定" />
    
    或者
    
    <input type="submit" value="确定" />

    会刷新页面。

  • 相关阅读:
    生成.project、.classpath文件
    Ecelipse上添加Server
    通信安全验证
    通过jstack定位在线运行java系统故障_案例1
    自动代码复制工具
    在Visual Studio Express 2013中开发自定义控件
    通过java类文件识别JDK编译版本
    去掉java反编译(JD-GUI)生成的源文件中注释
    循环处理目录下文件框架
    java查找重复类/jar包/普通文件
  • 原文地址:https://www.cnblogs.com/tanwei81/p/6813297.html
Copyright © 2011-2022 走看看