java调用http接口(含图片上传)

调用http接口并实现图片传递的关键分为两部分

其一:创建servlet接口,加图片上传注解,用于接收传过来的图片等信息,并做进一步的处理后,返回json格式的结果

其二:创建htpclient,并且运用MultipartEntity对图片进行封装,调用http接口,获取返回值,进行下一步处理

下面就以人脸识别登录,来讲解带有图片的http接口的调用过程

1、创建jsp页面,用于获取到人脸信息

<%@ 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 {
      340px;
     
      background:#ccc;
      border: 10px solid #ddd;
      margin: 0 auto;
    }
    .btn input[type=button] {
     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>

2、在loginController中编写创建httpclient的方法,并调用接口、

/**
     * 调用接口,实现人脸识别登录
     * @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 有详细介绍
引入的三方文件有:

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;

3、需要单独写一个web服务,发布http接口用的,在这里有第二步想要访问的接口,接口编写:

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());
    }
}

需要注意的是:

      1)类上要加@MultipartConfig注解,该注解是用来保存上传图片的

      2)需要引入Part类:javax.servlet.http.Part; 用来将上传图片写入文件中

      3)调用的人脸识别接口可参考博客:http://www.cnblogs.com/guo-eric/p/8109411.html

至此就完成了人脸识别登录过程,登录系统和人脸识别处理接口的服务相分离的实现,欢迎了解。

原文地址:https://www.cnblogs.com/guo-eric/p/8465351.html