前言:这是我的第一篇博文,是我对现在一些接口调用的梳理,写的不好,请见谅。
序:接口无非就是“你调用别人的接口”和“别人调用你的接口”,我会对这两种情况分别的理一下我的思路。
准备:我使用的是HttpClient,它的特性是实现了Http全部的方法和支持HTTPS协议,是一种比较纯净的JAVA语言。
一、“你调用别人的接口”:
我这里提供的方法是POST和GET的方法.
使用HttpClient发送请求、接收响应很简单,一般需要如下几步即可。
1. 创建HttpClient对象。
2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3. 如果需要发送请求参数,我使用的是List<NameValuePair>,采用键值对的形式
4. 释放连接。无论执行方法是否成功,都必须释放连接
来个代码进行讨论把,我会在代码里面进行详细的讲解,这里主要是post和get的方法.
1.先来一个常量类:
/*************************************************接口部分**************************************************/ /** * 请求正常 */ public static final int SUCCESS = 200; /** * 请求参数有误 */ public static final int PARAMETER_EXCEPTION = 400; /** * 认证失败 */ public static final int AUTHENTICATION_FAILED = 401; /** * 请求地址错误或不存在 */ public static final int ADDRESS_EXCEPTION = 404; /** * 请求地址错误或不存在 */ public static final int SERVER_EXCEPTION = 500; /** * 接口状态码判断 */ public static String putThrowException(int statusCode) { String e = ""; if(PARAMETER_EXCEPTION == statusCode) { e = "请求参数有误"; }else if(AUTHENTICATION_FAILED == statusCode) { e = "认证失败"; }else if(ADDRESS_EXCEPTION == statusCode) { e = "请求地址错误或不存在"; }else if(SERVER_EXCEPTION == statusCode) { e = "服务器状态异常"; } return e; } /** * Token元素 */ public static final String USERNAME = "tianxun"; public static final String PASSWORD = "123456"; public static final String token = "dGlhbnh1biUzQTEyMzQ1Ng==";
2.接口类:
package cn.tisson.bycs.utils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.net.ssl.SSLException; import org.apache.commons.httpclient.HttpException; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpRequest; import org.apache.http.NameValuePair; import org.apache.http.NoHttpResponseException; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIUtils; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.codec.binary.Base64; import cn.tisson.bycs.cst.Constants; /** * 接口常用工具类 * @author zahngrh * */ public class serviceUtils { private static final Logger logger = LoggerFactory.getLogger(serviceUtils.class); /** * Base64加密Token * @return * @throws UnsupportedEncodingException */ public static String getBase64() throws UnsupportedEncodingException { String str = Constants.USERNAME+":"+Constants.PASSWORD; final byte[] textByte = str.getBytes("UTF-8"); String result= Base64.encodeBase64String(textByte); return result; } public static void main(String[] args) throws UnsupportedEncodingException { System.out.println(getBase64()); } /** * 设置超时重试 */ public static HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { @Override public boolean retryRequest(IOException exception,int executionCount,HttpContext context) { System.out.println("............................第"+executionCount+"次重试"); if (executionCount >= 3) { return false; }else if(exception instanceof UnknownHostException || exception instanceof ConnectTimeoutException || !(exception instanceof SSLException) || exception instanceof NoHttpResponseException) { return true; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) { //如果请求被认为是等幂,则重试 return true; } return false; } }; /** * 接口请求工具类 */ public static Map<String,String> requestResult(Map<String,String> map,String putType,String url) throws HttpException, IOException { CloseableHttpResponse response = null; int statusCode = 0; // 状态码 String content =""; // 返回结果 Map<String,String> resultMap = new HashMap(); // 创建httpclient对象 CloseableHttpClient httpClient = HttpClients.createDefault(); // 设置参数 List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); for(String key:map.keySet()) { nameValuePairs.add(new BasicNameValuePair(key,map.get(key).toString())); } String str = EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairs,Consts.UTF_8)); // 设置超时时间 RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(5000) .setConnectTimeout(5000) .setConnectionRequestTimeout(5000) .build(); if(putType != null && "post".equals(putType)){ // 请求URL地址 HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs,Consts.UTF_8)); // 设置Token httpPost.setHeader("token",Constants.token); httpPost.setConfig(requestConfig); httpClient = HttpClients.custom().setRetryHandler(serviceUtils.myRetryHandler).build(); try { response = httpClient.execute(httpPost); // 接收状态码 statusCode = response.getStatusLine().getStatusCode(); } catch (Exception e) { e.printStackTrace(); } }else if(putType != null && "get".equals(putType)) { // 请求URL地址 HttpGet httpGet = new HttpGet(url+"?"+str); // 设置Token httpGet.setHeader("token",Constants.token); httpGet.setConfig(requestConfig); httpClient = HttpClients.custom().setRetryHandler(serviceUtils.myRetryHandler).build(); try { response = httpClient.execute(httpGet); // 接收状态码 statusCode = response.getStatusLine().getStatusCode(); } catch (Exception e) { e.printStackTrace(); } } // 判断状态码 if (Constants.SUCCESS == statusCode) { HttpEntity entity = response.getEntity(); content = EntityUtils.toString(entity, "utf-8"); logger.info(content); } else { //logger.error("状态码:"+Constants.putThrowException(statusCode)); } resultMap.put("statusCode", String.valueOf(statusCode)); resultMap.put("result", content); try { // 释放client httpClient.close(); } catch (IOException e) { logger.error("http接口调用异常:url is::" + url, e); } return resultMap; } }
3.对于接口类的调用:
/**
*根据业务使用接口,对返回值进行自我的调整
**/
public static void main(String[] args) throws HttpException, IOException { Map<String,String> paraMap = new HashMap(); paraMap.put("type", "1"); System.out.println(serviceUtils.requestResult(paraMap, "post", "https://api.apiopen.top/musicRankingsDetails")); }
一、“别人调用你的接口”:
别人调用你的接口,你需要:
1.token的验证(业务需求)的返回
2.参数的验证的返回
3.内部错误的返回
4.正确结果的返回
这时候你需要先写一个"情况返回的类"对各种错误信息和正确信息的返回
1.处理类
package cn.tisson.bycs.utils.exception; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; @ControllerAdvice public class GlobalExceptionHandler { private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); /** * <p>判断参数是否为空</p></br> * <p>如果为空,返回resultCode=400和具体信息,</p></br> * <p>如果不为空,则返回resultCode=0。</p> * @Title: isEmpty * @Description: TODO * @param @param param * @param @return * @return Hashtable<String,Object> * @throws * @author zhangrh */ public Hashtable<String, Object> isEmpty(Map<String, Map<String, String>> param) { Hashtable<String, Object> resultHt = new Hashtable<String, Object>(); int resultCode = 0; List<Map<String, String>> list = new ArrayList<>(); Set<String> set = param.keySet(); Iterator<String> iterator = set.iterator(); while(iterator.hasNext()) { String paramName = iterator.next(); Map<String, String> m = param.get(paramName); Set<String> s = m.keySet(); Iterator<String> iter = s.iterator(); while(iter.hasNext()) { String describe = iter.next(); if(m.get(describe) == null || "".equals(m.get(describe))) { resultCode = 400; Map<String, String> detail = new HashMap<>(); detail.put("objectName", paramName); detail.put("defaultMessage", describe); detail.put("error", describe + "不能为空"); list.add(detail); } } } if(resultCode == 400) { resultHt.put("resultMsg", "请求参数有误"); resultHt.put("detail", list); } resultHt.put("resultCode", resultCode); return resultHt; } /** * 接口有参数未传 */ @ExceptionHandler(value = MissingServletRequestParameterException.class) @ResponseBody public JSONObject missActionParam(HttpServletRequest req, List<Map<String, Object>> list) throws Exception { return makeErrorObj("参数异常", "400", req, null, list); } /** * 服务器内部错误 */ @ExceptionHandler(value = NullPointerException.class) @ResponseBody public JSONObject error(HttpServletRequest req) throws Exception { Map<String,Object> resultMap = new HashMap<>(); return makeErrorObj("服务器内部错误", "500",req, resultMap, null); } /** * token验证错误 */ @ExceptionHandler(value = NullPointerException.class) @ResponseBody public JSONObject tokenException(HttpServletRequest req,Map<String,Object> resultMap) throws Exception { return makeErrorObj("token验证失败","401", req,resultMap, null); } /** * 正常执行 */ @ResponseBody public JSONObject success(HttpServletRequest req,Map<String,Object> resultMap){ return makeErrorObj("执行成功","200", req,resultMap, null); } /** * 构造错误信息 * * @param msg 错误描述 * @param e 异常信息 * @return */ @ResponseBody private JSONObject makeErrorObj(String msg,String status, HttpServletRequest req,Map<String,Object> resultMap, List<Map<String, Object>> list) { JSONObject obj = new JSONObject(); // 日期格式化 SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ); String timestamp = sdf.format(new Date()); if("200".equals(status)) { for(String key : resultMap.keySet()) { obj.put(key,resultMap.get(key)); } }else { obj.put("errors", list); obj.put("status", status); obj.put("msg", msg); obj.put("path", req.getRequestURL()); obj.put("timestamp", timestamp); } return obj; } }
2.写一个Controller方法,让别人调用我的接口
@SuppressWarnings({ "unchecked" }) @RequestMapping(value = "/queryCheckPassengers", method = { RequestMethod.GET }) //这个一个get请求的方法,如果是post== RequestMethod.POST @ResponseBody public JSONObject queryCheckPassengers(HttpServletRequest request,HttpServletResponse response,Map<String, String> resultMap)throws Exception{ // 验证token String tokenStr = request.getHeader("token"); if(!Constants.token.equals(tokenStr)) { response.setStatus(401); return new GlobalExceptionHandler().tokenException(request, new HashMap<String, Object>()); } try{ Map<String, Map<String, String>> pMap = new HashMap<>(); Map<String, String> m = new HashMap<>(); //数据 String flightNum = request.getParameter("flightNum"); //航班号 String flightDate = request.getParameter("flightDate"); //航班日期,格式YYYY-MM-DD String passengerCheckInNumber = request.getParameter("passengerCheckInNumber"); //值机序号 String flightBoardingCode = request.getParameter("flightBoardingCode"); //始发地(城市名称、3字码) m.put("航班号", flightNum); pMap.put("flightNum", m); m = new HashMap<>(); m.put("航班日期", flightDate); pMap.put("flightDate", m); m = new HashMap<>(); m.put("值机序号", passengerCheckInNumber); pMap.put("passengerCheckInNumber", m); m = new HashMap<>(); m.put("始发地", flightBoardingCode); pMap.put("flightBoardingCode", m); Hashtable<String, Object> ht = new GlobalExceptionHandler().isEmpty(pMap); if(ht.get("resultCode").toString().equals("400")) { response.setStatus(400); return new GlobalExceptionHandler().missActionParam(request, (List<Map<String, Object>>)ht.get("detail")); }else {
//这里是你需要返回的信息 Map<String, Object> result = checkActionTypeStub.queryCheckPassengers(flightNum, flightDate, passengerCheckInNumber, flightBoardingCode); response.setStatus(200); return new GlobalExceptionHandler().success(request, result); } }catch (Exception e) { response.setStatus(500); e.printStackTrace(); return new GlobalExceptionHandler().error(request); } }
说明:别人调用你的接口,有提供一个api的和提供一个controller的方式,这里是提供一个controller的方式,你需要的是提供IP和端口,加上你的类名和方法名
例:http://172.16.31.199:8080/passton/queryCheckPassengers
总结:在这里就是对我的一些对接口的应用了,初次写作,还很潦草,就当是我的一次记录吧。