public class Client {
	private String appKey;	//APP_KEY
	private String appSecret;	//APP_SECREET
	
	public Client(String appKey, String appSecret) {
		if(StringUtil.isEmpty(appKey) || StringUtil.isEmpty(appSecret)) {
			throw new IllegalArgumentException("APP_KEY and APP_Secret must be not null.");
		}
		this.appKey = appKey;
		this.appSecret = appSecret;
	}
	
	public String getAppKey() {
		return appKey;
	}
	public void setAppKey(String appKey) {
		this.appKey = appKey;
	}
	public String getAppSecret() {
		return appSecret;
	}
	public void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}
	@Override
	public String toString() {
		return "Client [appKey=" + appKey + ", appSecret=" + appSecret + "]";
	}
} public class RespConfig {

	public final static int RESP_OK = 0;
	
	public final static int FACESET_MAX_FACE = 10000;
	
} public class UrlConfig {
	
	public static final String CHART_SET = "UTF-8";

	public static final String BASE_URL = "https://apicn.faceplusplus.com/v2";
	
	//Face
	public static final String PATH_DETECT = "/detection/detect";
	
	//Person
	public static final String PATH_PERSON_CREATE = "/person/create";
	
	public static final String PATH_PERSON_DELETE = "/person/delete";
	
	public static final String PATH_PERSON_ADD_FACE = "/person/add_face";
	
	public static final String PATH_PERSON_REMOVE_FACE = "/person/remove_face";
	
	public static final String PATH_PERSON_SET_INFO = "/person/set_info";
	
	public static final String PATH_PERSON_GET_INFO = "/person/get_info";
	
	//Group
	public static final String PATH_GROUP_CREATE = "/group/create";
	
	public static final String PATH_GROUP_DELETE = "/group/delete";
	
	public static final String PATH_GROUP_ADD_PERSON = "/group/add_person";
	
	public static final String PATH_GROUP_REMOVE_PERSON = "/group/remove_person";
	
	public static final String PATH_GROUP_SET_INFO = "/group/set_info";
	
	public static final String PATH_GROUP_GET_INFO = "/group/get_info";
	
	//Faceset
	public static final String PATH_FACESET_CREATE = "/faceset/create";

	public static final String PATH_FACESET_DELETE = "/faceset/delete";
	
	public static final String PATH_FACESET_ADD_FACE = "/faceset/add_face";
	
	public static final String PATH_FACESET_REMOVE_FACE = "/faceset/remove_face";
	
	public static final String PATH_FACESET_SET_INFO = "/faceset/set_info";
	
	public static final String PATH_FACESET_GET_INFO = "/faceset/get_info";

	//Grouping
	public static final String PATH_GROUPING = "/grouping/grouping";
	
	//Info
	public static final String PATH_INFO_GET_IMAGE = "/info/get_image";
	
	public static final String PATH_INFO_GET_FACE = "/info/get_face";
	
	public static final String PATH_INFO_GET_PERSON_LIST = "/info/get_person_list";
	
	public static final String PATH_INFO_GET_FACESET_LIST = "/info/get_faceset_list";
	
	public static final String PATH_INFO_GET_GROUP_LIST = "/info/get_group_list";
	
	public static final String PATH_INFO_GET_SESSION = "/info/get_session";
	
	public static final String PATH_INFO_GET_QUOTA = "/info/get_quota";
	
	public static final String PATH_INFO_GET_APP = "/info/get_app";
	
	//train
	public static final String PATH_TRAIN_VERIFY = "/train/verify";

	public static final String PATH_TRAIN_SEARCH = "/train/search";
	
	public static final String PATH_TRAIN_IDENTIFY = "/train/identify";
	
	//recognition
	public static final String PATH_RECOGNITION_COMPARE = "/recognition/compare";
	
	public static final String PATH_RECOGNITION_VERIFY = "/recognition/verify";
	
	public static final String PATH_RECOGNITION_SEARCH = "/recognition/search";
	
	public static final String PATH_RECOGNITION_IDENTIFY = "/recognition/identify";
	
} public class Face implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 8603825983713166688L;
	// face array 被检测出的人脸的列表
	private String face_id; //被检测出的每一张人脸都在Face++系统中的标识符
	private String face_data; //人脸本地截图的路径，如果有的话，没有为空
	private String img_id; //人脸相关的图片id
	private String url;	//相关图片的url
	
	private float width; // 0~100之间的实数，表示检出的脸的宽度在图片中百分比
	private float height; // 0~100之间的实数，表示检出的脸的高度在图片中百分比
	private PointF center; // 检出的人脸框的中心点坐标, x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF eye_left; // 相应人脸的左眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF eye_right; // 相应人脸的右眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF mouth_left; // 相应人脸的左侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF mouth_right; // 相应人脸的右侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	private PointF nose; // 相应人脸的鼻尖坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比 (0~100之间的实数)
	
	// attribute object 包含一系列人脸的属性分析结果 gender object 包含性别分析结果，value的值为Male/Female, confidence表示置信度
	private Gender gender;
	// age object 包含年龄分析结果，value的值为一个非负整数表示估计的年龄, range表示估计年龄的正负区间
	private Age age;
	// race object 包含人种分析结果，value的值为Asian/White/Black, confidence表示置信度
	private Race race;
	
	private String tag;	//人脸描述
	
	/**
	 * 被检测出的每一张人脸都在Face++系统中的标识符
	 * @return
	 */
	public String getFace_id() {
		return face_id;
	}

	/**
	 * 被检测出的每一张人脸都在Face++系统中的标识符
	 * @param face_id
	 */
	public void setFace_id(String face_id) {
		this.face_id = face_id;
	}
	
	

	/**
	 * 人脸本地截图的路径，如果有的话，没有为空
	 * @return the face_data
	 */
	public String getFace_data() {
		return face_data;
	}

	/**
	 * 人脸本地截图的路径，如果有的话，没有为空
	 * @param face_data the face_data to set
	 */
	public void setFace_data(String face_data) {
		this.face_data = face_data;
	}

	/**
	 * 人脸相关的图片id
	 * @return
	 */
	public String getImg_id() {
		return img_id;
	}

	/**
	 * 人脸相关的图片id
	 * @param img_id
	 */
	public void setImg_id(String img_id) {
		this.img_id = img_id;
	}
	
	/**
	 * 图片url
	 * @return the url
	 */
	public String getUrl() {
		return url;
	}
	/**
	 * 图片url
	 * @param url the url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的宽度在图片中百分比
	 * @return
	 */
	public float getWidth() {
		return width;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的宽度在图片中百分比
	 * @param width
	 */
	public void setWidth(float width) {
		this.width = width;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的高度在图片中百分比
	 * @return
	 */
	public float getHeight() {
		return height;
	}
	
	/**
	 * 0~100之间的实数，表示检出的脸的高度在图片中百分比
	 * @param height
	 */
	public void setHeight(float height) {
		this.height = height;
	}
	
	/**
	 * 检出的人脸框的中心点坐标, x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getCenter() {
		return center;
	}
	
	/**
	 * 检出的人脸框的中心点坐标, x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param center
	 */
	public void setCenter(PointF center) {
		this.center = center;
	}
	/**
	 *  相应人脸的左眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getEye_left() {
		return eye_left;
	}
	
	/**
	 *  相应人脸的左眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param eye_left
	 */
	public void setEye_left(PointF eye_left) {
		this.eye_left = eye_left;
	}
	
	/**
	 * 相应人脸的右眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getEye_right() {
		return eye_right;
	}
	
	/**
	 * 相应人脸的右眼坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param eye_right
	 */
	public void setEye_right(PointF eye_right) {
		this.eye_right = eye_right;
	}
	
	/**
	 * 相应人脸的左侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getMouth_left() {
		return mouth_left;
	}
	
	/**
	 * 相应人脸的左侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param mouth_left
	 */
	public void setMouth_left(PointF mouth_left) {
		this.mouth_left = mouth_left;
	}
	
	/**
	 * 相应人脸的右侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @return
	 */
	public PointF getMouth_right() {
		return mouth_right;
	}
	
	/**
	 * 相应人脸的右侧嘴角坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比(0~100之间的实数)
	 * @param mouth_right
	 */
	public void setMouth_right(PointF mouth_right) {
		this.mouth_right = mouth_right;
	}
	
	/**
	 * 相应人脸的鼻尖坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比 (0~100之间的实数)
	 * @return
	 */
	public PointF getNose() {
		return nose;
	}
	/**
	 * 相应人脸的鼻尖坐标，x & y 坐标分别表示在图片中的宽度和高度的百分比 (0~100之间的实数)
	 * @param nose
	 */
	public void setNose(PointF nose) {
		this.nose = nose;
	}
	

	/**
	 * 性别分析结果
	 * @return
	 */
	public Gender getGender() {
		return gender;
	}
	
	/**
	 * 性别分析结果
	 * @param gender
	 */
	public void setGender(Gender gender) {
		this.gender = gender;
	}
	
	/**
	 * 年龄分析结果
	 * @return
	 */
	public Age getAge() {
		return age;
	}
	
	/**
	 * 年龄分析结果
	 * @param age
	 */
	public void setAge(Age age) {
		this.age = age;
	}
	
	/**
	 * 人种分析结果
	 * @return
	 */
	public Race getRace() {
		return race;
	}
	
	/**
	 * 人种分析结果
	 * @param race
	 */
	public void setRace(Race race) {
		this.race = race;
	}
	
	

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "Face [face_id=" + face_id + ", face_data=" + face_data
				+ ", img_id=" + img_id + ", url=" + url + ", width=" + width
				+ ", height=" + height + ", center=" + center + ", eye_left="
				+ eye_left + ", eye_right=" + eye_right + ", mouth_left="
				+ mouth_left + ", mouth_right=" + mouth_right + ", nose="
				+ nose + ", gender=" + gender + ", age=" + age + ", race="
				+ race + ", tag=" + tag + "]";
	}

	/**
	 * 人脸描述
	 * @return
	 */
	public String getTag() {
		return tag;
	}

	/**
	 * 人脸描述
	 * @param tag
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}

	/**
	 * 性别
	 * @author xiaoying
	 */
	public static class Gender implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 3604771785466469504L;
		// gender object 包含性别分析结果，value的值为Male/Female, confidence表示置信度
		public String value; //值为Male/Female
		public float confidence; //置信度
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
		public float getConfidence() {
			return confidence;
		}
		public void setConfidence(float confidence) {
			this.confidence = confidence;
		}
		@Override
		public String toString() {
			return "Gender [value=" + value + ", confidence=" + confidence
					+ "]";
		}

	}

	/**
	 * 年龄
	 * @author xiaoying
	 */
	public static class Age implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 221737413026253122L;
		// age object 包含年龄分析结果，value的值为一个非负整数表示估计的年龄, range表示估计年龄的正负区间
		public int value;	//一个非负整数表示估计的年龄
		public int range;	//估计年龄的正负区间
		public int getValue() {
			return value;
		}
		public void setValue(int value) {
			this.value = value;
		}
		public int getRange() {
			return range;
		}
		public void setRange(int range) {
			this.range = range;
		}
		@Override
		public String toString() {
			return "Age [value=" + value + ", range=" + range + "]";
		}
		
	}

	/**
	 * 种族
	 * @author xiaoying
	 */
	public static class Race implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 888019375173484388L;
		// race object 包含人种分析结果，value的值为Asian/White/Black, confidence表示置信度
		public String value; //值为Asian/White/Black
		public float confidence; //置信度
		public String getValue() {
			return value;
		}
		public void setValue(String value) {
			this.value = value;
		}
		public float getConfidence() {
			return confidence;
		}
		public void setConfidence(float confidence) {
			this.confidence = confidence;
		}
		@Override
		public String toString() {
			return "Race [value=" + value + ", confidence=" + confidence + "]";
		}
		
	}
} public class CompareReq extends BaseRequest {
	private String face_id1;	//第一个Face的face_id
	private String face_id2;	//第二个Face的face_id
	private Boolean async;		//该API是否为异步调用
	
	public CompareReq() {
		
	}
	
	public CompareReq(String face_id1, String face_id2) {
		this.face_id1 = face_id1;
		this.face_id2 = face_id2;
	}
	/**
	 * 第一个Face的face_id
	 * @return the face_id1
	 */
	public String getFace_id1() {
		return face_id1;
	}
	/**
	 * 第一个Face的face_id
	 * @param face_id1 the face_id1 to set
	 */
	public void setFace_id1(String face_id1) {
		this.face_id1 = face_id1;
	}
	/**
	 * 第二个Face的face_id
	 * @return the face_id2
	 */
	public String getFace_id2() {
		return face_id2;
	}
	/**
	 * 第二个Face的face_id
	 * @param face_id2 the face_id2 to set
	 */
	public void setFace_id2(String face_id2) {
		this.face_id2 = face_id2;
	}
	
	/**
	 * （可选）
	 * 如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。
	 * @return the async
	 */
	public Boolean getAsync() {
		return async;
	}
	
	/**
	 * （可选）
	 * 如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。
	 * @param async the async to set
	 */
	public void setAsync(Boolean async) {
		this.async = async;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "CompareReq [face_id1=" + face_id1 + ", face_id2=" + face_id2
				+ ", async=" + async + "]";
	}
	
	
} public class IdentityReq extends BaseRequest {
	private String group_id; //识别候选人组成的Group id
	private String group_name;	//识别候选人组成的Group name
//	可选	
	private String url;	//待识别图片的URL
	private File img;	// 待识别图片通过POST方法上传的二进制数据
	private String mode;	//检测模式可以是normal(默认) 或者 oneface 。在oneface模式中，检测器仅找出图片中最大的一张脸。仅当给出了url或img时，本选项有效。
	private String key_face_id;	//开发者也可以指定一个face_id的列表来表明对这些face进行识别。可以设置此参数key_face_id为一个逗号隔开的face_id列表。
	private Boolean async;	//如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。
	
	public IdentityReq() {
		
	}
	
	public IdentityReq(String group, boolean isId) {
		if(isId) {
			setGroup_id(group);
		} else {
			setGroup_name(group);
		}
	}
	
	/**
	 * 识别候选人组成的Group id
	 * @return the group_id
	 */
	public String getGroup_id() {
		return group_id;
	}
	/**
	 * 识别候选人组成的Group id
	 * 与setGroup_name(String group_name)只能选其一
	 * @param group_id the group_id to set
	 */
	public void setGroup_id(String group_id) {
		this.group_id = group_id;
	}
	/**
	 * 识别候选人组成的Group name
	 * @return the group_name
	 */
	public String getGroup_name() {
		return group_name;
	}
	/**
	 * 识别候选人组成的Group name
	 * 与setGroup_id(String group_id)只能选其一
	 * @param group_name the group_name to set
	 */
	public void setGroup_name(String group_name) {
		this.group_name = group_name;
	}
	/**
	 * (可选)
	 * 待识别图片的URL
	 * @return the url
	 */
	public String getUrl() {
		return url;
	}
	/**
	 * (可选)
	 * 待识别图片的URL
	 * 与setImg(File img)只能选其一
	 * @param url the url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}
	/**
	 * (可选)
	 * 待识别图片通过POST方法上传的二进制数据
	 * @return the img
	 */
	public File getImg() {
		return img;
	}
	/**
	 * (可选)
	 * 待识别图片通过POST方法上传的二进制数据
	 * 与setUrl(String url)只能选其一
	 * @param img the img to set
	 */
	public void setImg(File img) {
		this.img = img;
	}
	/**
	 * (可选)
	 * 检测模式可以是normal(默认) 或者 oneface 。在oneface模式中，检测器仅找出图片中最大的一张脸。仅当给出了url或img时，本选项有效。
	 * @return the mode
	 */
	public String getMode() {
		return mode;
	}
	/**
	 * (可选)
	 * 检测模式可以是normal(默认) 或者 oneface 。在oneface模式中，检测器仅找出图片中最大的一张脸。仅当给出了url或img时，本选项有效。
	 * @param mode the mode to set
	 */
	public void setMode(String mode) {
		this.mode = mode;
	}
	/**
	 * (可选)
	 * 开发者也可以指定一个face_id的列表来表明对这些face进行识别。可以设置此参数key_face_id为一个逗号隔开的face_id列表。
	 * @return the key_face_id
	 */
	public String getKey_face_id() {
		return key_face_id;
	}
	/**
	 * (可选)
	 * 开发者也可以指定一个face_id的列表来表明对这些face进行识别。可以设置此参数key_face_id为一个逗号隔开的face_id列表。
	 * @param key_face_id the key_face_id to set
	 */
	public void setKey_face_id(String key_face_id) {
		this.key_face_id = key_face_id;
	}
	/**
	 * (可选)
	 * 如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。
	 * @return the async
	 */
	public Boolean getAsync() {
		return async;
	}
	/**
	 * (可选)
	 * 如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。
	 * @param async the async to set
	 */
	public void setAsync(Boolean async) {
		this.async = async;
	}
	
	
} public class SearchReq extends BaseRequest {
	
	private String key_face_id;	//待搜索的Face的face_id
 	private String faceset_id; //指定搜索范围的Faceset id
 	private String faceset_name;	//指定搜索范围的Faceset name
	private Integer count;	//表示一共获取不超过count个搜索结果。默认count=3
 	private Boolean async;	//如果置为true，该API将会以异步方式被调用；也就是立即返回一个session id，稍后可通过/info/get_session查询结果。默认值为false。
	
 	public SearchReq() {
 		
 	}
 	
 	public SearchReq(String key_face_id, String faceset, boolean isId) {
 		setKey_face_id(key_face_id);
 		if(isId) {
 			setFaceset_id(faceset);
 		} else {
 			setFaceset_name(faceset);
 		}
 	}
 	
 	/**
	 * 待搜索的Face的face_id
	 * @return the key_face_id
	 */
	public String getKey_face_id() {
		return key_face_id;
	}
	/**
	 * 待搜索的Face的face_id
	 * @param key_face_id the key_face_id to set
	 */
	public void setKey_face_id(String key_face_id) {
		this.key_face_id = key_face_id;
	}
	/**
	 * 指定搜索范围的Faceset id
	 * @return the faceset_id
	 */
	public String getFaceset_id() {
		return faceset_id;
	}
	/**
	 * 指定搜索范围的Faceset id
	 * 与setFaceset_name(String faceset_name)只能选其一
	 * @param faceset_id the faceset_id to set
	 */
	public void setFaceset_id(String faceset_id) {
		this.faceset_id = faceset_id;
		this.faceset_name = null;
	}
	/**
	 * 指定搜索范围的Faceset name
	 * @return the faceset_name
	 */
	public String getFaceset_name() {
		return faceset_name;
	}
	/**
	 * 指定搜索范围的Faceset name
	 * 与setFaceset_id(String faceset_id)只能选其一
	 * @param faceset_name the faceset_name to set
	 */
	public void setFaceset_name(String faceset_name) {
		this.faceset_name = faceset_name;
		this.faceset_id = null;
	}
	/**
	 * (可选)
	 * 表示一共获取不超过count个搜索结果。默认count=3
	 * @return the count
	 */
	public Integer getCount() {
		return count;
	}
	/**
	 * (可选)
	 * 表示一共获取不超过count个搜索结果。默认count=3
	 * @param count the count to set
	 */
	public void setCount(Integer count) {
		this.count = count;
	}
	/**
	 * (可选)
	 * 该API将会以异步方式被调用
	 * @return the async
	 */
	public Boolean getAsync() {
		return async;
	}
	/**
	 * (可选)
	 * 该API将会以异步方式被调用
	 * @param async the async to set
	 */
	public void setAsync(Boolean async) {
		this.async = async;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "SearchReq [key_face_id=" + key_face_id + ", faceset_id="
				+ faceset_id + ", faceset_name=" + faceset_name + ", count="
				+ count + ", async=" + async + "]";
	}

 	
} public class VerifyReq extends BaseRequest {
	private String face_id;	//待verify的face_id
	private String person_id;	//对应的Person id
	private String person_name;	//对应的Person name
	
	public VerifyReq() {
		
	}
	
	public VerifyReq(String face_id, String person, boolean isId) {
		setFace_id(face_id);
		if(isId) {
			setPerson_id(person);
		} else {
			setPerson_name(person);
		}
	}
	
	/**
	 * 待verify的face_id
	 * @return the face_id
	 */
	public String getFace_id() {
		return face_id;
	}
	/**
	 * 待verify的face_id
	 * @param face_id the face_id to set
	 */
	public void setFace_id(String face_id) {
		this.face_id = face_id;
	}
	/**
	 * 对应的Person id
	 * @return the person_id
	 */
	public String getPerson_id() {
		return person_id;
	}
	/**
	 * 对应的Person id
	 * 与setPerson_name(String person_name)只能选其一
	 * @param person_id the person_id to set
	 */
	public void setPerson_id(String person_id) {
		this.person_id = person_id;
		this.person_name = null;
	}
	/**
	 * 对应的Person name
	 * @return the person_name
	 */
	public String getPerson_name() {
		return person_name;
	}
	/**
	 * 对应的Person name
	 * 与setPerson_id(String person_id)只能选其一
	 * @param person_name the person_name to set
	 */
	public void setPerson_name(String person_name) {
		this.person_name = person_name;
		this.person_id = null;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "VerifyReq [face_id=" + face_id + ", person_id=" + person_id
				+ ", person_name=" + person_name + "]";
	}
	
	
} public class CompareResp extends BaseResponse {
	private String session_id;	//请求的session_id
	private float similarity;	//一个0~100之间的实数，表示两个face的相似性
	private ComponentSimilarity component_similarity;	//包含人脸中各个部位的相似性，目前包含eyebrow(眉毛)、eye(眼睛)、nose(鼻子)与mouth（嘴）的相似性。每一项的值为一个0~100之间的实数，表示相应部位的相似性

	/**
	 * 请求的session_id
	 * @return the session_id
	 */
	public String getSession_id() {
		return session_id;
	}

	/**
	 * 请求的session_id
	 * @param session_id the session_id to set
	 */
	public void setSession_id(String session_id) {
		this.session_id = session_id;
	}

	/**
	 * 一个0~100之间的实数，表示两个face的相似性
	 * @return the similarity
	 */
	public float getSimilarity() {
		return similarity;
	}

	/**
	 * 一个0~100之间的实数，表示两个face的相似性
	 * @param similarity the similarity to set
	 */
	public void setSimilarity(float similarity) {
		this.similarity = similarity;
	}

	/**
	 * 包含人脸中各个部位的相似性，目前包含eyebrow(眉毛)、eye(眼睛)、nose(鼻子)与mouth（嘴）的相似性。每一项的值为一个0~100之间的实数，表示相应部位的相似性
	 * @return the component_similarity
	 */
	public ComponentSimilarity getComponent_similarity() {
		return component_similarity;
	}

	/**
	 * 包含人脸中各个部位的相似性，目前包含eyebrow(眉毛)、eye(眼睛)、nose(鼻子)与mouth（嘴）的相似性。每一项的值为一个0~100之间的实数，表示相应部位的相似性
	 * @param component_similarity the component_similarity to set
	 */
	public void setComponent_similarity(ComponentSimilarity component_similarity) {
		this.component_similarity = component_similarity;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "CompareResp [session_id=" + session_id + ", similarity="
				+ similarity + ", component_similarity=" + component_similarity
				+ ", error=" + error + ", error_code=" + error_code + "]";
	}


	public static class ComponentSimilarity {
		private float eye;		//eye(眼睛)的相似性,值为一个0~100之间的实数
		private float mouth;	//mouth（嘴）的相似性,值为一个0~100之间的实数
		private float nose;		//nose(鼻子)的相似性,值为一个0~100之间的实数
		private float eyebrow;	//eyebrow(眉毛)的相似性,值为一个0~100之间的实数
		/**
		 * eye(眼睛)的相似性,值为一个0~100之间的实数
		 * @return the eye
		 */
		public float getEye() {
			return eye;
		}
		/**
		 * eye(眼睛)的相似性,值为一个0~100之间的实数
		 * @param eye the eye to set
		 */
		public void setEye(float eye) {
			this.eye = eye;
		}
		/**
		 * mouth（嘴）的相似性,值为一个0~100之间的实数
		 * @return the mouth
		 */
		public float getMouth() {
			return mouth;
		}
		/**
		 * mouth（嘴）的相似性,值为一个0~100之间的实数
		 * @param mouth the mouth to set
		 */
		public void setMouth(float mouth) {
			this.mouth = mouth;
		}
		/**
		 * nose(鼻子)的相似性,值为一个0~100之间的实数
		 * @return the nose
		 */
		public float getNose() {
			return nose;
		}
		/**
		 * nose(鼻子)的相似性,值为一个0~100之间的实数
		 * @param nose the nose to set
		 */
		public void setNose(float nose) {
			this.nose = nose;
		}
		/**
		 * eyebrow(眉毛)的相似性,值为一个0~100之间的实数
		 * @return the eyebrow
		 */
		public float getEyebrow() {
			return eyebrow;
		}
		/**
		 * eyebrow(眉毛)的相似性,值为一个0~100之间的实数
		 * @param eyebrow the eyebrow to set
		 */
		public void setEyebrow(float eyebrow) {
			this.eyebrow = eyebrow;
		}
		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			return "ComponetSimilarity [eye=" + eye + ", mouth=" + mouth
					+ ", nose=" + nose + ", eyebrow=" + eyebrow + "]";
		}
		
	}
} public class IdentifyResp extends BaseResponse {

	private String session_id;	//相应请求的session标识符，可用于结果查询
	private List<IdentifyFace> face; //人脸的列表
	
	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @return the session_id
	 */
	public String getSession_id() {
		return session_id;
	}

	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @param session_id the session_id to set
	 */
	public void setSession_id(String session_id) {
		this.session_id = session_id;
	}

	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @return the face
	 */
	public List<IdentifyFace> getFace() {
		return face;
	}

	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @param face the face to set
	 */
	public void setFace(List<IdentifyFace> face) {
		this.face = face;
	}
	
	
	

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "IdentityResp [session_id=" + session_id + ", face=" + face
				+ ", error=" + error + ", error_code=" + error_code + "]";
	}




	/**
	 * 功能：人脸识别返回的人脸信息实体类
	 * @author xiaoying
	 *
	 */
	public static class IdentifyFace {
		private Face face;	//人脸信息
		private List<Candidate> candidates;	//识别结果。candidates包含不超过3个人，包含相应person信息与相应的置信度
		
		/**
		 * 人脸信息
		 * @return
		 */
		public Face getFace() {
			return face;
		}
		
		/**
		 * 人脸信息
		 * @param face
		 */
		public void setFace(Face face) {
			this.face = face;
		}

		/**
		 * 识别结果。candidates包含不超过3个人，包含相应person信息与相应的置信度
		 * @return the candidates
		 */
		public List<Candidate> getCandidates() {
			return candidates;
		}
		/**
		 * 识别结果。candidates包含不超过3个人，包含相应person信息与相应的置信度
		 * @param candidates the candidates to set
		 */
		public void setCandidates(List<Candidate> candidates) {
			this.candidates = candidates;
		}

		@Override
		public String toString() {
			return "IdentityFace [face=" + face + ", candidates=" + candidates
					+ "]";
		}
		
	}
	
	/**
	 * 功能：识别结果实体类
	 * @author xiaoying
	 *
	 */
	public static class Candidate implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = -178216610187842006L;
		private String person_id;	//person的id
		private String person_name;	//person的name
		private String tag;	//person的tag
		private float confidence;	//匹配的置信度
		/**
		 * person的id
		 * @return the person_id
		 */
		public String getPerson_id() {
			return person_id;
		}
		/**
		 * person的id
		 * @param person_id the person_id to set
		 */
		public void setPerson_id(String person_id) {
			this.person_id = person_id;
		}
		/**
		 * person的name
		 * @return the person_name
		 */
		public String getPerson_name() {
			return person_name;
		}
		/**
		 * person的name
		 * @param person_name the person_name to set
		 */
		public void setPerson_name(String person_name) {
			this.person_name = person_name;
		}
		/**
		 * person的tag
		 * @return the tag
		 */
		public String getTag() {
			return tag;
		}
		/**
		 * person的tag
		 * @param tag the tag to set
		 */
		public void setTag(String tag) {
			this.tag = tag;
		}
		/**
		 * 匹配的置信度
		 * @return the confidence
		 */
		public float getConfidence() {
			return confidence;
		}
		/**
		 * 匹配的置信度
		 * @param confidence the confidence to set
		 */
		public void setConfidence(float confidence) {
			this.confidence = confidence;
		}
		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			return "Candidate [person_id=" + person_id + ", person_name="
					+ person_name + ", tag=" + tag + ", confidence="
					+ confidence + "]";
		}
	}
} public class SearchResp extends BaseResponse {
	private String session_id;//相应请求的session标识符，可用于结果查询
	private List<Candidate> candidates;//搜索结果，包含相应face信息与相应的置信度
	
	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @return the session_id
	 */
	public String getSession_id() {
		return session_id;
	}

	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @param session_id the session_id to set
	 */
	public void setSession_id(String session_id) {
		this.session_id = session_id;
	}

	/**
	 * 搜索结果，包含相应face信息与相应的置信度
	 * @return the candidates
	 */
	public List<Candidate> getCandidates() {
		return candidates;
	}

	/**
	 * 搜索结果，包含相应face信息与相应的置信度
	 * @param candidates the candidates to set
	 */
	public void setCandidates(List<Candidate> candidates) {
		this.candidates = candidates;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "SearchResp [session_id=" + session_id + ", candidates="
				+ candidates + ", error=" + error + ", error_code="
				+ error_code + "]";
	}



	public static class Candidate {
		private String face_id;	//匹配的Face id
        private float similarity;	//匹配人脸和key_face的相似度，是0～100之间的实数
        private String tag;	//匹配人脸相关tag
		/**
		 * 匹配的Face id
		 * @return the face_id
		 */
		public String getFace_id() {
			return face_id;
		}
		/**
		 * 匹配的Face id
		 * @param face_id the face_id to set
		 */
		public void setFace_id(String face_id) {
			this.face_id = face_id;
		}
		/**
		 * 匹配人脸和key_face的相似度，是0～100之间的实数
		 * @return the similarity
		 */
		public float getSimilarity() {
			return similarity;
		}
		/**
		 * 匹配人脸和key_face的相似度，是0～100之间的实数
		 * @param similarity the similarity to set
		 */
		public void setSimilarity(float similarity) {
			this.similarity = similarity;
		}
		/**
		 * 匹配人脸相关tag
		 * @return the tag
		 */
		public String getTag() {
			return tag;
		}
		/**
		 * 匹配人脸相关tag
		 * @param tag the tag to set
		 */
		public void setTag(String tag) {
			this.tag = tag;
		}
		/* (non-Javadoc)
		 * @see java.lang.Object#toString()
		 */
		@Override
		public String toString() {
			return "Canditate [face_id=" + face_id + ", similarity="
					+ similarity + ", tag=" + tag + "]";
		}
        
	}
} public class VerifyResp extends BaseResponse {
	private String session_id;	//相应请求的session标识符，可用于结果查询
	private boolean is_same_person;	//两个输入是否为同一人的判断
	private float confidence;	//系统对这个判断的置信度。
	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @return the session_id
	 */
	public String getSession_id() {
		return session_id;
	}
	/**
	 * 相应请求的session标识符，可用于结果查询
	 * @param session_id the session_id to set
	 */
	public void setSession_id(String session_id) {
		this.session_id = session_id;
	}
	/**
	 * 两个输入是否为同一人的判断
	 * @return the is_same_person
	 */
	public boolean isIs_same_person() {
		return is_same_person;
	}
	/**
	 * 两个输入是否为同一人的判断
	 * @param is_same_person the is_same_person to set
	 */
	public void setIs_same_person(boolean is_same_person) {
		this.is_same_person = is_same_person;
	}
	/**
	 * 系统对这个判断的置信度。
	 * @return the confidence
	 */
	public float getConfidence() {
		return confidence;
	}
	/**
	 * 系统对这个判断的置信度。
	 * @param confidence the confidence to set
	 */
	public void setConfidence(float confidence) {
		this.confidence = confidence;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "VerifyResp [session_id=" + session_id + ", is_same_person="
				+ is_same_person + ", confidence=" + confidence + ", error="
				+ error + ", error_code=" + error_code + "]";
	}
	
	
} public class HttpUtil {
	
	
	public static HttpResponse doPost(String actionPath, Map<String, Object> params) throws ClientProtocolException, IOException {
		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost post = new HttpPost(UrlConfig.BASE_URL + actionPath);
		MultipartEntity mulEntity = new MultipartEntity();
		Set<String> keys = params.keySet();
		for (String key : keys) {
			Object obj = params.get(key);
			if (obj instanceof File && obj != null) {
				mulEntity.addPart(key, new FileBody((File) obj));
			} else {
				if(obj != null && !StringUtil.isEmpty(obj.toString())) {
					mulEntity.addPart(key, new StringBody(obj.toString(), Charset.forName(UrlConfig.CHART_SET)));
				}
			}
		}
		post.setEntity(mulEntity);
		return client.execute(post);
	}
} public class Log {
	
	private static boolean isPrint = true;
	
	public static void e(String msg) {
		if(isPrint) {
			System.err.println(msg);
		}
	}
	
	public static void i(String msg) {
		if(isPrint) {
			System.out.println(msg);
		}
	}
} public class StringUtil {
	public static boolean isEmpty(String str) {
		return str == null || str.equals("");
	}
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.xiaoying.faceplusplus.api.cliet.Client;
import com.xiaoying.faceplusplus.api.config.RespConfig;
import com.xiaoying.faceplusplus.api.config.UrlConfig;
import com.xiaoying.faceplusplus.api.entity.Face;
import com.xiaoying.faceplusplus.api.entity.request.recognition.CompareReq;
import com.xiaoying.faceplusplus.api.entity.request.recognition.IdentityReq;
import com.xiaoying.faceplusplus.api.entity.request.recognition.SearchReq;
import com.xiaoying.faceplusplus.api.entity.request.recognition.VerifyReq;
import com.xiaoying.faceplusplus.api.entity.response.recognition.CompareResp;
import com.xiaoying.faceplusplus.api.entity.response.recognition.IdentifyResp;
import com.xiaoying.faceplusplus.api.entity.response.recognition.SearchResp;
import com.xiaoying.faceplusplus.api.entity.response.recognition.VerifyResp;
import com.xiaoying.faceplusplus.api.utils.HttpUtil;
import com.xiaoying.faceplusplus.api.utils.Log;
import com.xiaoying.faceplusplus.api.utils.StringUtil;
/*
 * 文件名：RecognitionService.java
 * 版权：<版权>
 * 描述：<描述>
 * 创建人：xiaoying
 * 创建时间：2013-5-15
 * 修改人：xiaoying
 * 修改时间：2013-5-15
 * 版本：v1.0
 */

package com.xiaoying.faceplusplus.api.service;




/**
 * 功能：人脸匹配相关服务类
 * @author xiaoying
 *
 */
public class RecognitionService extends BaseService {

	/**
	 * @param client
	 */
	public RecognitionService(Client client) {
		super(client);
	}
	
	/**
	 * 计算两个Face的相似性以及五官相似度
	 * @param body
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws JSONException 
	 * @throws ParseException 
	 */
	public CompareResp compare(CompareReq body) throws ClientProtocolException, IOException, ParseException, JSONException {
		if(StringUtil.isEmpty(body.getFace_id1()) || StringUtil.isEmpty(body.getFace_id2())) {
			throw new IllegalArgumentException("face_id1 and face_id2 should not be null");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("api_key", client.getAppKey());
		params.put("api_secret", client.getAppSecret());
		params.put("face_id1", body.getFace_id1());
		params.put("face_id2", body.getFace_id2());
		
		HttpResponse resp = HttpUtil.doPost(UrlConfig.PATH_RECOGNITION_COMPARE, params);