java調用http接口(含圖片上傳)

調用http接口並實現圖片傳遞的關鍵分爲兩部分javascript

其一:建立servlet接口,加圖片上傳註解,用於接收傳過來的圖片等信息,並作進一步的處理後,返回json格式的結果html

其二:建立htpclient,而且運用MultipartEntity對圖片進行封裝,調用http接口,獲取返回值,進行下一步處理java

 

下面就以人臉識別登陸,來說解帶有圖片的http接口的調用過程jquery

一、建立jsp頁面,用於獲取到人臉信息web

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ZH-CN">
<head>
  <meta charset="utf-8">
  <title>人臉識別登陸</title>
  <style>
    .booth {
      width:340px;
     
      background:#ccc;
      border: 10px solid #ddd;
      margin: 0 auto;
    }
    .btn input[type=button] {
    width: 60px;
    height: 30px;
    line-height: 30px;
    margin: 3px;
}
  </style>
  <script type="text/javascript" src="js/jquery.js"></script>
</head>
<body>
  <div class="booth">
    <input type="button" value="登陸" onclick="doLogin('login');">
        <video id="video" width="320" height="240"></video>
       <canvas id='canvas' style="display:none;"></canvas>
  </div>
 
  <script type="text/javascript">

    var video = document.getElementById('video'),
    canvas = document.getElementById('canvas'),
    vendorUrl = window.URL || window.webkitURL;
    
    //媒體對象
    navigator.getMedia = navigator.getUserMedia ||
                     navagator.webkitGetUserMedia ||
                     navigator.mozGetUserMedia ||
                     navigator.msGetUserMedia;
        navigator.getMedia({
            video: true, //使用攝像頭對象
            audio: false  //不適用音頻
        }, function(strem){
            console.log(strem);
            video.src = vendorUrl.createObjectURL(strem);
            video.play();
        }, function(error) {
            //error.code
            console.log(error);
        });
    
    
function doLogin(method) {
      //繪製canvas圖形
        canvas.getContext('2d').drawImage(video, 0, 0, 320, 240);
        //把canvas圖像轉爲img圖片
        $.ajax({
            url : 'login.do?method='+method,
            type : "POST",
            dataType : 'json',
            async : false,
            data : {image : canvas.toDataURL("image/png")},
            success : function(data) {    
                alert(data.flag+'---'+data.message);
                var msg = data.message;
                if (msg != "success") {
                    resultflag=false;
                }
            },
            error : function(error) {
                tip('訪問數據異常', '異常提示');
                return true;
            }
        });
}
    
    
  </script>
</body>
</html>

二、在loginController中編寫建立httpclient的方法,並調用接口、ajax

/**
     * 調用接口,實現人臉識別登陸
     * @param req
     * @param resp
     * @param model
     * @throws IOException
     */
    @RequestMapping(value = "login_ai.do", method = RequestMethod.POST)
    public void login_ai(HttpServletRequest req, HttpServletResponse resp,
            ModelMap model) {
        try {
            resp.setContentType("application/text; charset=utf-8");
            String basePath = "upload/";
            String filePath = req.getSession().getServletContext()
                    .getRealPath("/")
                    + basePath;
            String fileName = getDate("yyyyMMddHHmmss") + ".png";
            // 默認傳入的參數帶類型等參數:data:image/png;base64,
            PrintWriter out = resp.getWriter();
            com.alibaba.fastjson.JSONObject loginInfo = new com.alibaba.fastjson.JSONObject();

            String imgStr = req.getParameter("image");
            if (null != imgStr) {
                imgStr = imgStr.substring(imgStr.indexOf(",") + 1);
            }

            // 每次上傳文件以前,須要先將以前的文件刪除掉
            File file = new File(filePath);
            if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    f.delete();
                }
            }
            // 文件上傳到服務器
            Boolean flag = ImageCompressUtil.GenerateImage(imgStr, filePath,
                    fileName);
            String newfileName = fileName.substring(0, fileName.indexOf("."))
                    + "_bak" + fileName.substring(fileName.indexOf("."));

//            loginInfo = HttpUtil.sendPostWithImage(AIConstant.LOGIN_REGIST_URL
//                    + "?method=login", filePath+newfileName);

            HttpClient client = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(AIConstant.LOGIN_REGIST_URL
                    + "?method=login");// 經過post傳遞
            /** 綁定數據 這裏須要注意 若是是中文 會出現中文亂碼問題 但只要按設置好 */
            MultipartEntity muit = new MultipartEntity();

            File fileupload = new File(filePath+newfileName);
            FileBody fileBody = new FileBody(fileupload);
            muit.addPart("file", fileBody);
            httpPost.setEntity(muit);
            /** 發送請求 */
            try {
                HttpResponse response = client.execute(httpPost);
                // 判斷師傅上傳成功 返回200
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    loginInfo = (com.alibaba.fastjson.JSONObject) com.alibaba.fastjson.JSONObject.parse(EntityUtils.toString(response
                            .getEntity()));
                }else{
                    loginInfo.put("flag", false);
                    loginInfo.put("message", "服務器相應異常!");
                }
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            out.write(loginInfo.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

其中涉及到的圖片壓縮ImageCompressUtil.GenerateImage()類及方法參見博客:    http://www.cnblogs.com/guo-eric/p/8418626.html 有詳細介紹
引入的三方文件有:apache

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

三、須要單獨寫一個web服務,發佈http接口用的,在這裏有第二步想要訪問的接口,接口編寫:json

package com.hengyunsoft.face.login;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import org.json.JSONArray;
import org.json.JSONObject;

import sun.misc.BASE64Decoder;

import com.baidu.aip.face.AipFace;
import com.hengyunsoft.face.aip.FaceManage;
import com.hengyunsoft.face.util.ImageCompressUtil;

/**
 * Servlet implementation class UploadFile
 */
@WebServlet("/login.do")
@MultipartConfig
public class Login extends HttpServlet {
    private static final long serialVersionUID = 1L;
    // 設置APPID/AK/SK
    public static final String APP_ID = "10580034";
    public static final String API_KEY = "CUEBLydMIEhyHXGgjuBLMCDx";
    public static final String SECRET_KEY = "XXXXXX";

    /**
     * @see HttpServlet#HttpServlet()
     */
    public Login() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        try {

            String method = request.getParameter("method");
            switch (method) {
            case "login":
                login_regist_inter(request, response);// 接口調用
                break;
            case "reg":
                login_regist_inter(request, response);// 接口調用
                break;
            case "del":
                del_inter(request, response);// 接口調用
                break;
            default:
                break;
            }
            
        } catch (Exception e) {
             System.out.println("接口調用異常");
        }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }


        /**
     * 登陸和註冊的接口
     * 
     * @param req
     * @param resp
     * @throws Exception
     */
    public void login_regist_inter(HttpServletRequest req,
            HttpServletResponse resp) throws Exception {
        resp.setContentType("application/text; charset=utf-8");
        PrintWriter out = resp.getWriter();

        // 接口返回值
        JSONObject returnValue = new JSONObject();
        returnValue.put("flag", true);

        // 圖片上傳路徑
        String filePath = req.getSession().getServletContext()
                .getRealPath("/upload")
                + File.separator;
        String fileName = getDate("yyyyMMddHHmmss") + ".png";

        // 獲取接口傳遞參數
        String uid = req.getParameter("uid");
        String method = req.getParameter("method");

        // 每次上傳文件以前,須要先將以前的文件刪除掉
        File file = new File(filePath);
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                f.delete();
            }
        }

        // 文件夾位置固定,文件夾採用與上傳文件的原始名字相同
        String fileSavingPath = filePath + fileName;
        // 若是存儲上傳文件的文件夾不存在,則建立文件夾
        File f = new File(filePath);
        if (!f.exists()) {
            f.mkdirs();
        }
        Part part = req.getPart("file");// 獲取文件路徑
        part.write(fileSavingPath);

        // 拿到base64編碼的圖片,就能夠調用百度的API進行驗證
        AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY);
        if (method.equals("reg")) {
            register(filePath, fileName, returnValue, uid, client);
        } else if (method.equals("login")) {
            // 須要從返回的信息中取用戶id
            login(filePath, fileName, returnValue, client);
        }

        out.write(returnValue.toString());
    }
    
    /**
     * 清除註冊信息的接口
     * 
     * @param req
     * @param resp
     * @throws Exception
     */
    public void del_inter(HttpServletRequest req,
            HttpServletResponse resp) throws Exception {
        resp.setContentType("application/text; charset=utf-8");
        PrintWriter out = resp.getWriter();

        // 接口返回值
        JSONObject returnValue = new JSONObject();
        returnValue.put("flag", true);

        // 獲取接口傳遞參數
        String uid = req.getParameter("uid");

        // 拿到base64編碼的圖片,就能夠調用百度的API進行驗證
        AipFace client = new AipFace(APP_ID, API_KEY, SECRET_KEY);
        try {
            FaceManage.deleteUser(client, uid);
            returnValue.put("message", "人臉信息刪除成功!");
        } catch (Exception e) {
            returnValue.put("flag", false);
            returnValue.put("message", "人臉信息刪除失敗!");
        }

        out.write(returnValue.toString());
    }

    
    /**
     * 登陸的第二種實現,人臉識別的方式,將註冊用戶的全部匹配度拿到,取最高
     * 
     * @param filePath
     * @param fileName
     * @param j
     * @param uid
     * @param client
     * @return
     */
    private void login(String filePath, String fileName, JSONObject aiInfo,
            AipFace client) {
        JSONObject aiJson = FaceManage
                .identifyUser(client, filePath + fileName);

        double tmp = 0.0, matchPercent = 0.0;
        String uid = "";
        try {
            JSONArray ja = aiJson.getJSONArray("result");
            double scores[] = new double[ja.length()]; // 聲明數組
            matchPercent = scores[0];
            for (int i = 0; i < ja.length(); i++) {
                JSONObject json = ja.getJSONObject(i);
                tmp = Double.parseDouble(json.get("scores").toString()
                        .replace("[", "").replace("]", ""));
                if (tmp > matchPercent) {
                    // 判斷最大值
                    matchPercent = tmp;
                    uid = json.get("uid").toString();
                }

                System.out.println(tmp);
            }
        } catch (Exception e) {
            matchPercent = 0.0;
        }

        if (matchPercent > 90) {
            System.out.println("驗證成功,人臉匹配度是:" + matchPercent);
            aiInfo.put("uid", uid);
            aiInfo.put("matchPercent", matchPercent);
            aiInfo.put("flag", true);
            aiInfo.put("message", "驗證成功,人臉匹配度是:" + matchPercent);
        } else {
            System.out.println("驗證失敗,人臉匹配度是:" + matchPercent);
            aiInfo.put("flag", false);
            aiInfo.put("uid", uid);
            aiInfo.put("matchPercent", matchPercent);
            aiInfo.put("message", "驗證失敗,人臉匹配度是:" + matchPercent);
        }
    }

    /**
     * 註冊
     * 
     * @param filePath
     * @param fileName
     * @param j
     * @param uid
     * @param client
     * @return
     */
    private void register(String filePath, String fileName, JSONObject regInfo,
            String uid, AipFace client) {

        String message = "用戶" + uid + "人臉註冊失敗!";

        int matchPercent = FaceManage.saveOrUpdateUser(client, filePath
                + fileName, uid);
        if (matchPercent == 1) {
            message = "用戶" + uid + "人臉註冊成功!";
            regInfo.put("flag", true);
        } else {
            regInfo.put("flag", false);
        }

        regInfo.put("message", message);
    }

    
    public String getDate(String pattern) {
        return new SimpleDateFormat(pattern).format(new Date());
    }
}

須要注意的是:canvas

      1)類上要加@MultipartConfig註解,該註解是用來保存上傳圖片的數組

      2)須要引入Part類:javax.servlet.http.Part; 用來將上傳圖片寫入文件中

      3)調用的人臉識別接口可參考博客:http://www.cnblogs.com/guo-eric/p/8109411.html

 

至此就完成了人臉識別登陸過程,登陸系統和人臉識別處理接口的服務相分離的實現,歡迎瞭解。

相關文章
相關標籤/搜索