站長資訊網(wǎng)
        最全最豐富的資訊網(wǎng)站

        使用HTML5實現(xiàn)掃描PC二維碼且觸發(fā)WAP端上傳資源功能的示例代碼

        講解一篇Java代碼根據(jù)參數(shù)動態(tài)生成PC二維碼效果,且成功掃描并上傳圖形或視頻資源的功能。

        技術(shù)難度一般,關(guān)鍵在于如何把一整套邏輯思路整合到項目上,如果調(diào)用,應(yīng)該到哪些技術(shù),理清了交互關(guān)系,詳細對于大家而言這就是一份入門級別的代碼參考,以作提升。

        粗略介紹一下應(yīng)用到的技術(shù)問題,前端方法使用簡單的html元素布局,生成<img>二維碼即可,后端框架為SpringMVC,結(jié)構(gòu)簡單,查閱清晰,應(yīng)用到的二維碼Jar包為:qrcode_swetake.jar 。

        一、從前端開始入手,先構(gòu)建頁面布局確保能夠生成二維碼效果:

        使用HTML5實現(xiàn)掃描PC二維碼且觸發(fā)WAP端上傳資源功能的示例代碼

        實現(xiàn)出來的成型效果如上圖所示,鼠標移入移出則顯示隱藏二維碼效果框,自行慢慢摸索CSS如何實現(xiàn)了,這里需要說明的是二維碼只需要一句話即可動態(tài)生成。

        <c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>  <img src="${ctx}/upload/codeImg.html?userId=${loginUserId}" />

        設(shè)置一個<img>標簽動態(tài)生成接收返回的二維碼圖,高寬度自行根據(jù)實際情況設(shè)定,然后就嗶的一聲手機即可訪問的,當(dāng)然測試階段請確保IP同在一個局域網(wǎng)。

        掃描出來的頁面也異曲同工,關(guān)鍵在于你要設(shè)計成什么樣子,只要能實現(xiàn)上傳功能即可。

        我應(yīng)用的前端上傳插件為jquery.form.js,主要JS方法如下:

        <input type="file" name="tempFile" id="tempFile"        accept= ".avi,.mpg,.mp4,.mov;capture=camera" onchange="previewFile('tempFile');"/>  <input type="file" name="tempFile" id="tempFile"       accept= "image/jpg,image/JPG,image/jpeg,image/JPEG,image/pdf,image/png;capture=camera"       onchange="previewFile('tempFile');"/>        <script language="javascript">          function previewFile(id){        var x = document.getElementById("tempFile");        if(!x || !x.value) return;        var patn = /.jpg$|.JPG$|.jpeg$|.JPEG$|.pdf$|.PDF$|.png$|.PNG$/;        var inpType = "image/jpg,image/JPG,image/jpeg,image/JPEG,image/pdf,image/PDF,image/png,image/PNG";        var type = $("#type").val();        if(type=='video'){            patn = /.mp4$|.MP4$|.mov$|.MOV$/;            inpType = ".MP4,.MOV,.mp4,.mov";        }        if(!patn.test(x.value)){               if(type=='video'){                alertMsg("請上傳mov、mp4格式的視頻");            }else{                alertMsg("請上傳jpg、png、pdf格式的文件");            }        }else{                initShow();              $("#uploadForm").ajaxSubmit(options);        }         }             var options  = {          dataType:"json",          url:'${ctx}/upload/uploadAndSaveFile.html',              type:'post',              contentType: "application/x-www-form-urlencoded; charset=utf-8",           success:function(data)  {              initHide();              if(data.success){                  //alertCallBack("上傳成功<br/>請前往PC端刷新后查閱!",function(){                      document.location.href="${ctx}/upload/toUploadEndDetail.html";                  //});              }else{                  alertCallBack(data.message,function(){                      window.location.reload();                  });                  //alertMsg(data.message);              }          },          error :function(data){              initHide();              alertMsg(data);          },          beforeSubmit:showRequest  // pre-submit callback          //clearForm:true       };               function showRequest(formData, jqForm, options) {          var queryString = $.param(formData);      }  </script>

        以上代碼由于涉及公司內(nèi)部邏輯,故存在個別地方的刪減動作,但整體思路已清晰羅列出來了。

        這里需要講到一個應(yīng)用到的UI插件,即alertMsg使用到的hint彈出框效果。smallarAlert.js

        附件資源均會統(tǒng)一部署上來,插件自適應(yīng)效果可兼容IE、谷歌、360、火狐等主流瀏覽器,內(nèi)置樣式及功能等也可自行重寫,具體應(yīng)用自行度娘搜索該插件了,這里就不一一講解了。

        二、從后端著手處理二維碼生成技術(shù)及資源保存動作:

        /**       * @Descript :生成二維碼圖片url       * @author : Teny_lau       * @CreatedTime : 2016年11月21日-下午3:44:44       * @param model       * @param request       * @param response       */      @RequestMapping("/codeImg")      public void toCodeImg(Model model, HttpServletRequest request, HttpServletResponse response) {          String localIp = getInternetIp(request);          String path = request.getSession().getServletContext().getContextPath();          String port = StringUtils.getNullBlankStr(request.getServerPort());// 獲取服務(wù)器端口          String userId = StringUtils.getNullBlankStr(request.getParameter("userId"));//接收參數(shù)          String params = "userId=" + userId;          // 字節(jié)長度須控制在124個長度以內(nèi),否則報異常數(shù)組索引值溢出          String content = localIp + ":" + port + path + "/upload/toUploadMain.html?" + params;          EncoderHandler encoder = new EncoderHandler();          encoder.encoderQRCoder(content, response);      }             private String getInternetIp(HttpServletRequest request) {          String ip = StringUtils.getNullBlankStr(request.getHeader("x-forwarded-for"));          if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {              ip = StringUtils.getNullBlankStr(request.getHeader("Proxy-Client-IP"));          }          if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {              ip = StringUtils.getNullBlankStr(request.getHeader("WL-Proxy-Client-IP"));          }          if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {              ip = StringUtils.getNullBlankStr(request.getRemoteAddr());// 獲取客戶端IP地址          }          String localIp = "";// 獲取網(wǎng)段地址          try {              InetAddress localInter = InetAddress.getLocalHost();              localIp = StringUtils.getNullBlankStr(localInter.getHostAddress());          } catch (UnknownHostException e1) {              e1.printStackTrace();          }          if (!ip.equals(localIp) && !"127.0.0.1".equals(ip)) {              // 當(dāng)程序獲取非服務(wù)器網(wǎng)口時,自動重置為本地網(wǎng)口              ip = localIp;          }          if ("127.0.0.1".equals(ip)) {              // 根據(jù)網(wǎng)卡取本機配置的IP              InetAddress inet = null;              try {                  inet = InetAddress.getLocalHost();              } catch (Exception e) {                  e.printStackTrace();              }              ip = StringUtils.getNullBlankStr(inet.getHostAddress());          }          // 對于通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照','分割          if (ip != null && ip.length() > 15) { // "***.***.***.***".length() = 15              if (ip.indexOf(",") > 0) {                  ip = ip.substring(0, ip.indexOf(","));              }          }          return ip;      }         /**       * 提交資源信息       *        * @param model       * @param request       * @return       */      @RequestMapping("uploadAndSaveFile")      @ResponseBody      public void uploadAndSaveFile(HttpServletRequest request, HttpServletResponse response) {          Map<String, Object> result = new HashMap<String, Object>();          try {              String type = StringUtils.getNullBlankStr(request.getParameter("type"));              saveUploadFile(request);              result.put("success", true);          } catch (RuntimeException run) {              result.put("success", false);              result.put("message", run.getMessage());          } catch (Exception e) {              result.put("success", false);              result.put("message", "上傳失敗<br/>請重新或掃碼上傳!");              // FileUtil.deleteFiles(fileNames);          }          try {              response.setContentType("text/html;charset=gbk");              JSONObject jsonObj = JSONObject.fromObject(result);              response.getWriter().print(jsonObj);          } catch (IOException e) {              e.printStackTrace();          }      }             /**       * @Descript :保存上傳資源       * @author : Teny_lau       * @CreatedTime : 2016年11月21日-下午3:28:39       */      private void saveUploadFile(HttpServletRequest request) {          String userId = StringUtils.getNullBlankStr(request.getParameter("userId"));//接收參數(shù)          Map<String, Object> queryMap = new HashMap<String, Object>();          queryMap.put("","");          List<XXX> flashList = new ArrayList<XXX>();          String oldFlashName = "";// 舊文件          //由于以下邏輯存在項目代碼,故以下對象均為舉例說明,具體要求視項目自行修改          Old oldEntity = new Old();          if (flashList != null && flashList.size() > 0) {              oldEntity = flashList.get(0);              //獲取已上傳的舊文件名,便于在插入新文件時,刪除舊文件,避免資源過多占用空間內(nèi)存              oldFlashName = oldEntity.getFlashName();          }          MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;          CommonsMultipartFile file1 = (CommonsMultipartFile) multipartRequest.getFile("tempFile");// 上傳資源參數(shù)          if (file1 != null && !file1.isEmpty()) {              // 判斷上傳資源等文件大小 控制在500M以內(nèi),自行根據(jù)項目要求斟酌              int maxSize = 500 * 1024 * 1024;              if (file1.getSize() >= maxSize) {                  throw new RuntimeException("保存失敗,文件控制在500M以內(nèi)");              }              String fileName = saveFile(file1, request, oldFlashName);//這里返回的為重命名新文件名稱          }         }         private String saveFile(CommonsMultipartFile file, HttpServletRequest request, String oldFileName) {          String fileName = file.getOriginalFilename();          String uploadPath = request.getSession().getServletContext().getRealPath(FILEPATH);          // 判斷是否有上傳文件          File targetFile = null;          String groupId = StringUtils.getNullBlankStr(request.getParameter("groupId"));//接收參數(shù)          String newTransFileName = DateUtils.getCurrentDateTime14() + groupId + "." + org.apache.commons.lang3.StringUtils.substringAfterLast(fileName, ".");          String newFilePath = uploadPath + File.separator + newTransFileName;          try {              targetFile = new File(new StringBuilder().append(newFilePath).toString());              // 文件重命名              file.transferTo(targetFile);              String oldFilePath = "";              if (StringUtils.isNotBlank(oldFileName)) {                  oldFilePath = uploadPath + File.separator + oldFileName;                  FileUtil.delSingleFile(oldFilePath);              }              // 復(fù)制文件到指定盤              // CopyFileUtil.copyFile(origiNewPath, oldFilePath, true);                         } catch (NullPointerException e) {              e.printStackTrace();          } catch (Exception e) {              e.printStackTrace();          }          return newTransFileName;      }

        代碼先一一貼上,以上代碼由于存在公司邏輯,故也做了個別刪減動作,但整體思路的增刪改上傳等功能已一一展示在這里了。

        個別工具類方法如下:

        1、StringUtils.getNullBlankStr

        /**       * 功能描述:       * 判斷字符串是否為null或為空字符串,則返回空字符串""       *       * @param obj String       *            待檢查的字符串       * @return String       *         如果為null或空字符串(包括只含空格的字符串)則返回"",否則返回原字符串去空格       */      public static String getNullBlankStr(Object obj) {             if (obj == null) {              return "";          } else {              return obj.toString().trim();          }      }

        校驗判斷為空時則返回空字符串的動作。

        2、DateUtils.getCurrentDateTime14()

        /**       * 獲取當(dāng)前應(yīng)用服務(wù)器的系統(tǒng)日期時間       *        * @return 日期時間字符串,格式:yyyyMMddHHmmss       */      public static String getCurrentDateTime14() {          DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");          return df.format(new Date(System.currentTimeMillis()));      }

        具體時間格式可自行定義,根據(jù)具體情況而定。

        3、EncoderHandler和FileUtil 工具類,參考附件文件源碼。

        特別注意:

        這里的EncoderHandler需要提醒到的一個問題點是,該方法接收字節(jié)長度是有最大值限制的,即最大可保存124個字符,超出長度則報數(shù)據(jù)越界異常。

        public void encoderQRCoder(String content, HttpServletResponse response) {          try {              Qrcode handler = new Qrcode();              handler.setQrcodeErrorCorrect('M');              handler.setQrcodeEncodeMode('B');              handler.setQrcodeVersion(7);                             // System.out.println(content);              byte[] contentBytes = content.getBytes("UTF-8");                             BufferedImage bufImg = new BufferedImage(140, 140, BufferedImage.TYPE_INT_RGB);                             Graphics2D gs = bufImg.createGraphics();                             gs.setBackground(Color.WHITE);              gs.clearRect(0, 0, 140, 140);                             // 設(shè)定圖像顏色:BLACK              gs.setColor(Color.BLACK);                             // 設(shè)置偏移量 不設(shè)置肯能導(dǎo)致解析出錯              int pixoff = 2;              // 輸出內(nèi)容:二維碼              if (contentBytes.length > 0 && contentBytes.length < 124) {                  boolean[][] codeOut = handler.calQrcode(contentBytes);                  for (int i = 0; i < codeOut.length; i++) {                      for (int j = 0; j < codeOut.length; j++) {                          if (codeOut[j][i]) {                              gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);                          }                      }                  }              } else {                  System.err.println("QRCode content bytes length = " + contentBytes.length + " not in [ 0,120 ]. ");              }                             gs.dispose();              bufImg.flush();                             // 生成二維碼QRCode圖片              ImageIO.write(bufImg, "jpg", response.getOutputStream());                         } catch (Exception e) {              e.printStackTrace();          }      }

        ——————————————————————————————

        // 字節(jié)長度須控制在124個長度以內(nèi),否則報異常數(shù)組索引值溢出          String content = localIp + ":" + port + path + "/upload/toUploadMain.html?" + params;          EncoderHandler encoder = new EncoderHandler();          encoder.encoderQRCoder(content, response);

        所以content字符串拼接時,注意長度不得超出124個字節(jié),否則報錯,如下圖所示:

        使用HTML5實現(xiàn)掃描PC二維碼且觸發(fā)WAP端上傳資源功能的示例代碼

        恩,以上內(nèi)容即為今天要講解的動態(tài)生成二維碼并上傳資源的所有知識點了,各位猿人們多動手操作幾次,相信你也能很好的學(xué)好一項小技術(shù),如有任何疑問或建議的歡迎來博吐槽。

        附件資源無法下載情況下,請自行挪步鏈接:down.51cto.com/data/2261528

        如果各位童鞋還有任何建議或比較好的想法,歡迎加入JAVA開發(fā)項目討論群:214404624。

        發(fā)揮你聰智的大腦,挖掘更新鮮更充滿活力的好點子,我們共同探討技術(shù)層面的研究和可實施性。

        贊(0)
        分享到: 更多 (0)
        網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號
        主站蜘蛛池模板: 久久精品亚洲男人的天堂| 亚洲午夜精品久久久久久app| 99久久99久久精品免费看蜜桃| 国产成人无码精品久久久久免费| 色欲国产麻豆一精品一AV一免费| 国产精品福利片免费看| 精品人妻系列无码天堂| 欧美成人精品第一区二区| 久久国产精品-国产精品| 欧美精品v欧洲精品| 欧美精品91欧美日韩操| 99久久精品国产一区二区三区 | 青青青青久久精品国产h| 日本aⅴ精品中文字幕| 热久久国产欧美一区二区精品| 国产精品九九久久免费视频 | 久久久精品一区二区三区| 日韩精品极品视频在线观看免费 | 精品国产爽爽AV| 国产成人精品久久亚洲高清不卡| 国产成人精品亚洲日本在线| 精品一区二区三区无码免费视频 | 国产午夜精品理论片| 欧美777精品久久久久网| 97精品人妻系列无码人妻| 精品午夜福利在线观看| 无码精品人妻一区二区三区人妻斩| 日韩蜜芽精品视频在线观看| 久久精品女人天堂AV麻| 精品91自产拍在线观看二区| 国产精品伊人久久伊人电影| 欧美日韩精品一区二区三区| 国产成人精品综合网站| 国产精品www| 国产精品久久国产精品99盘| 国产精品久久自在自线观看| 国产精品1024香蕉在线观看| 久久精品国产精品国产精品污| 国产精品久久久久9999| 亚洲视频在线精品| 亚洲一区无码精品色|