首页 > 技术文章 > 接口开发--常规事项

Cszdyz2020 2020-10-09 09:17 原文

接口开发

1.HTTP请求

传递格式按照的严格的Json格式的字符串

{
    "name": "中国",
    "province": [{
        "name": "黑龙江",
        "cities": {
            "city": ["哈尔滨", "大庆"]
        }
    }, {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }, {
        "name": "台湾",
        "cities": {
            "city": ["台北", "高雄"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["乌鲁木齐"]
        }
    }]
}
# 总结:
	List值表示为"":[]
	键值为"":{} 或 "":""
# 一些传递注意事项:
	传值中的汉字用UTF-8编码

2.格式转换

情景一、接收数据

1.请求数据如下(标准json格式,数据类型JSONObject)

{
"head":{
		"username":"test",
		"password":"098f6bcd4621d373cade4e832627b4f6",
		"opusrid":"1726521",
		"opusrname":"张三",
		"opusrorg":"中国建设银行股份有限公司镇江分行",
		"opusrorgid":"91321100772046885B",
		"opusropin":""
	},
"data":	{
		"param": {"ywbh":"234234", "cert_num":"32111", "name":"小三"}
    }
}

2.解析数据

# 1.对请求数据进行指定格式解析(定义接收对象)
@Component
public class RequestRoot {
	private RequestHead head;
	private RequestData data;
	public RequestHead getHead() {
		return head;
	}
	public void setHead(RequestHead head) {
		this.head = head;
	}
	public RequestData getData() {
		return data;
	}
	public void setData(RequestData data) {
		this.data = data;
	}
}
# 2.对于head头信息的处理,键值对形式进行实体类封装(定义一个head实体类)
@Component
public class RequestHead {
	private String username;//授权用户名
	private String password;//授权密码
	private String opusrid;//操作用户编码
	private String opusrname;//操作用户名称
	private String opusrorg;//操作用户所在机构名称
	private String opusrorgid;//操作用户所在机构代码
	private String opusropin;//操作用户意见
	private String manddoc_id;//授权委托书编号
	private String status;
	private String message;
	
	public String getStatus() {
		return status;
	}
	public void setStatus(String status) {
		this.status = status;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getOpusrid() {
		return opusrid;
	}
	public void setOpusrid(String opusrid) {
		this.opusrid = opusrid;
	}
	public String getOpusrname() {
		return opusrname;
	}
	public void setOpusrname(String opusrname) {
		this.opusrname = opusrname;
	}
	public String getOpusrorg() {
		return opusrorg;
	}
	public void setOpusrorg(String opusrorg) {
		this.opusrorg = opusrorg;
	}
	public String getOpusrorgid() {
		return opusrorgid;
	}
	public void setOpusrorgid(String opusrorgid) {
		this.opusrorgid = opusrorgid;
	}
	public String getOpusropin() {
		return opusropin;
	}
	public void setOpusropin(String opusropin) {
		this.opusropin = opusropin;
	}
	public String getManddoc_id() {
		return manddoc_id;
	}
	public void setManddoc_id(String manddoc_id) {
		this.manddoc_id = manddoc_id;
	}
}
# 3.对于请求体data的处理,param=JSONObject对象,所以需要再做封装,首先定义param为JSONObject对象,之后定义所对应的实体类。具体操作如下:
@Component
public class RequestData {
    
    private JSONObject param;

	public JSONObject getParam() {
		return param;
	}

	public void setParam(JSONObject param) {
		this.param = param;
	}
    
}
public class MzbMarriage {

    private String ywbh;
    private String cert_num;
    private String name;

    public String getYwbh() {
        return ywbh;
    }

    public void setYwbh(String ywbh) {
        this.ywbh = ywbh;
    }

    public String getCert_num() {
        return cert_num;
    }

    public void setCert_num(String cert_num) {
        this.cert_num = cert_num;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
}

3.格式转化

JSONObject param
//获取整体数据
RequestRoot root = param.toJavaObject(RequestRoot.class);
//获取param数据
MzbMarriage mzbMarriage = root.getData().getParam().toJavaObject(MzbMarriage.class);
//2.提取请求的数据
String opusrname = root.getHead().getOpusrname();  //操作用户名称
String opusrorg = root.getHead().getOpusrorg();  //操作用户所在机构名称
String ywbh = mzbMarriage.getYwbh();  //业务编号
String cert_num = mzbMarriage.getCert_num(); //用户身份证号
String name = mzbMarriage.getName(); //用户名称

情景二、发送数据

1.发送格式如下(也是标准json格式字符串)

gxData={ 
    "head": {
        "xzqdm": "321100"
    }, 
    "data": 
    { 
        "username": "gx321100", 
        "password": "3ffb45876887977459f7a10d943383b5" 
    } 
}

2.数据封装(使用Map进行封装)

Map<String, String> token_head = new HashMap<String, String>();
token_head.put("xzqdm", xzqdm);

Map<String, String> token_data = new HashMap<String, String>();
token_data.put("username", username);
token_data.put("password", password);

Map<String, Object> map_token = new HashMap<String, Object>();
map_token.put("head", token_head);
map_token.put("data", token_data);

Map<String, Object> gxData = new HashMap<String, Object>();
gxData.put("gxData", JSONUtils.toJSONString(map_token));//注意gxData={}是Map<String,String>

1.发送格式如下(也是标准json格式字符串)

gxData:{ 	
	"head": { 	
        "xzqdm": "321100", 
		"ip": "192.168.8.221", 
		"token": "73E53CF783F9A1E7DB45C3AC90C3D04A43D9AB312995BF74CD171D2268463437",
		 "deptName": "镇江市不动产登记交易中心", 				
		"userName": "刘超", 				
		"cxqqdh": "20200909321100000001", 				
		"businessNumber": "20200909321100000001" 		
	},
 	"data": { 	
        "cxywlb": "civil_marriage_query", 
		"cxywcs": [ 
				{ "cert_num": "321102XXXXXXXXXX", "name": "张三" } 
			] 		
	} 
}

2.数据封装(使用Map进行封装)

String token = "123421423424234";
Map<String, String> userMap = new HashMap<>();
userMap.put("cert_num", cert_num);
userMap.put("name", name);
List<Map> userList = new ArrayList<>();
userList.add(userMap);

Map<String, Object> map_query_data = new HashMap<>();
map_query_data.put("cxywlb", cxywlb);
map_query_data.put("cxywcs", userList);

Map<String, String> map_query_head = new HashMap<>();
map_query_head.put("xzqdm", xzqdm);
map_query_head.put("ip", ip);
map_query_head.put("token", token);
map_query_head.put("deptName", opusrorg);
map_query_head.put("userName", opusrname);
//日期转yyyyMMddHHmmss
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
String time = formatter.format(new Date());
String time_prefix = time.substring(0, 8);
String time_suffix = time.substring(8, 14);
String lsh = time_prefix+xzqdm+time_suffix;
map_query_head.put("cxqqdh", lsh);
map_query_head.put("businessNumber", ywbh);

Map<String, Object> map_query = new HashMap<>();
map_query.put("head", map_query_head);
map_query.put("data", map_query_data);

gxData.put("gxData", JSONUtils.toJSONString(map_query));//注意gxData={}是Map<String,String>

3.HttpClient工具类

/**
 * 远程HTTP接口POST调用
 */
public class MyHttpClient {
	
	/**
    *
    * @param httpUrl  请求的url
    * @param param  form表单的参数(key,value形式)
    * @return
    */
   public static String doPostForm(String httpUrl, Map param) {

       HttpURLConnection connection = null;
       InputStream is = null;
       OutputStream os = null;
       BufferedReader br = null;
       String result = null;
       try {
           URL url = new URL(httpUrl);
           // 通过远程url连接对象打开连接
           connection = (HttpURLConnection) url.openConnection();
           // 设置连接请求方式
           connection.setRequestMethod("POST");
           // 设置连接主机服务器超时时间:15000毫秒
           connection.setConnectTimeout(15000);
           // 设置读取主机服务器返回数据超时时间:60000毫秒
           connection.setReadTimeout(60000);

           // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
           connection.setDoOutput(true);
           // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
           connection.setDoInput(true);
           // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
           connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
           // 设置鉴权信息:Authorization: Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0
           //connection.setRequestProperty("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
           // 通过连接对象获取一个输出流
           os = connection.getOutputStream();
           // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的(form表单形式的参数实质也是key,value值的拼接,类似于get请求参数的拼接)
           os.write(createLinkString(param).getBytes());
           // 通过连接对象获取一个输入流,向远程读取
           /**测试状态 404,实际状态200**/
           if (connection.getResponseCode() == 200) {

               is = connection.getInputStream();
               // 对输入流对象进行包装:charset根据工作项目组的要求来设置
               br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

               StringBuffer sbf = new StringBuffer();
               String temp = null;
               // 循环遍历一行一行读取数据
               while ((temp = br.readLine()) != null) {
                   sbf.append(temp);
                   sbf.append("\r\n");
               }
               result = sbf.toString();
           }
       } catch (MalformedURLException e) {
           e.printStackTrace();
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           // 关闭资源
           if (null != br) {
               try {
                   br.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
           if (null != os) {
               try {
                   os.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
           if (null != is) {
               try {
                   is.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
           // 断开与远程地址url的连接
           connection.disconnect();
       }
       return result;
   }
   
   /**
    * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
    * @param params 需要排序并参与字符拼接的参数组
    * @return 拼接后字符串
    */
   public static String createLinkString(Map<String, String> params) throws UnsupportedEncodingException {
       List<String> keys = new ArrayList<String>(params.keySet());
       Collections.sort(keys);

       StringBuilder prestr = new StringBuilder();
       for (int i = 0; i < keys.size(); i++) {
           String key = keys.get(i);
           String value = params.get(key);
           value = URLEncoder.encode(value, "UTF-8");
           if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
               prestr.append(key).append("=").append(value);
           } else {
               prestr.append(key).append("=").append(value).append("&");
           }
       }

       return prestr.toString();
   }
    
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

}

具体使用

String callbackJson = MyHttpClient.doPostForm(url, gxData);//callbackJson为json格式字符串

3.开发问题解决

1.请求次数过多

情景:当对一组数据进行for循环请求时,服务器会响应中断或者数据返回异常。

解决:使用延迟思想,开启Thread.sleap();

2.time out

情景:在一次请求和另一次请求之间,有数据存入操作,且操作事件过长,比如base64图片转成byte保存记录

解决:将数据库事件过长的去掉,之后在定时任务中进行操作。

推荐阅读