通过HttpClient实现远程调用
如果在不同的服务要实现服务与服务之间的调用,有众多选择,如Httpclient,Okhttp,
HttpURLConnection,RestTemplate这几种,当然还有那些封装好的框架,如feign等。这里主要讲解一下这个HttpClient的使用。
1,通过get方式实现
public static String get(String url,String tokenName,String tokenValue,Map<String,String> map) { //构建客户端对象 CloseableHttpClient httpClient = HttpClientBuilder.create().build(); //设置参数 if (CollectionUtils.isNotEmpty(map)) { //添加参数 String paramData = addParamByGet(map); //拼接参数 url = url + "?" + paramData ; } //String url = ""http://127.0.0.1:8080/user" HttpGet httpGet = new HttpGet(url); //响应体 CloseableHttpResponse response; try { //添加请求头,添加token //httpGet.addHeader("token", "eyJ0eXAiOiJKc29uV2ViVG9rZW4iLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOi"); httpGet.addHeader(tokenName, tokenValue); //添加请求配置,设置响应时间等 RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(2000) //服务器响应超时时间 .setConnectionRequestTimeout(2000) //连接服务器超时时间 .build(); //将配置信息添加到 httpGet 中 httpGet.setConfig(requestConfig); //调用接口,获取响应 response = httpClient.execute(httpGet); //将响应转化为一个结果集 HttpEntity entity = response.getEntity(); //将内容转化为字符串,并且设定指定字符集 String result= EntityUtils.toString(entity, "UTF-8"); //最终将结果集返回 return result; } catch (IOException e) { e.printStackTrace(); } finally { //资源释放 if (httpGet != null) { try { httpGet.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } if (httpClient != null) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } }
get请求添加参数
/** * get添加参数 */ public static StringBuilder addParamByGet(Map<String,String> map){ StringBuilder param = new StringBuilder(); //遍历参数 for (Map.Entry<String, String> m :map.entrySet()) { param.append(m.getKey()).append("=").append(m.getValue()).append("&"); } return param; }
2,通过post的方式实现
里面有一些token,参数之类的,如果不用,直接将代码注释即可
public static String post(String url, String tokenName,String tokenValue, Map<String,String> map) throws IOException { //构建客户端对象 CloseableHttpClient httpClient = HttpClientBuilder.create().build(); CloseableHttpResponse response = null; try { //创建http post请求对象 这个url可以手动封装一个 HttpPost post = new HttpPost("http://127.0.0.1:8080/user/addUser"); //设置请求头 //post.setHeader("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwidXN" + // "lckluZm8iOnsidXNlcklkIjoxNTg5ODIxMzMwNTY1NjQ0Mjg5fSwiZXhwIjoxNjY4MDU5MzQ3LCJpYXQiOjE2N" + // "jc5NzI5NDd9.mcmgzc0yEyTyfeo-2D5vpaYhdyD9LFBwCwP8s30r0Hs"); post.addHeader(tokenName, tokenValue); //设置文本类型 post.setHeader("Content-Type", "application/json"); //如果只有一两个参数的话,也可以通过这个反转义字符手动传参变成json格式,反正最终是要转成json的形式的 //post.setEntity(new StringEntity("{\"type\":\"1\"}", "UTF-8")); //构建参数 if (CollectionUtils.isNotEmpty(map)){ JSONObject jo = new JSONObject(); //增加参数 addParam(map,jo); post.setEntity(new StringEntity(jo.toString(), ContentType.APPLICATION_JSON)); }else { post.setEntity(new StringEntity(null, ContentType.APPLICATION_JSON)); } //创建响应对象 response = httpClient.execute(post); /** * 由于响应接口返回的是一个字符串,因此需要转换 * 响应体数据封装在HttpEntity对象中 */ String result = EntityUtils.toString(response.getEntity(), "utf-8"); return result; } catch (Exception e) { e.printStackTrace(); } finally { //关闭资源 response.close(); httpClient.close(); } }
post请求添加参数
/** * post添加参数 */ public static JSONObject addParam(Map < String, String > map, JSONObject jsonObject) { for (Map.Entry < String, String > entry: map.entrySet()) { jsonObject.put(entry.getKey(), entry.getValue()); } return jsonObject; }
3,解析返回数据
上面两种方式都是返回一个json格式的字符串,因此可以将这个字符串解析,或者直接在方法里面解析,我这里选择在外面解析
public static vois mian(String Args[]) { //调用get请求,可以将里面的url,token等作为参数传入 String url = "localhost:8080/user/message"; String tokenName = "token"; String tokenValue = "xxx"; String message = get(url,tokenName,tokenValue,null); //如果里面有多条数据,那么可以用数组方式解析,即使一条数据,也是可以通过这个解析的 JSONArray jsonArray = JSONArray.parseArray(message); //遍历 List<User> list = new ArrayList<>(); jsonArray.stream().forEach(json - > { JSONObject jsonObject = JSONArray.parseObject(json.toString()); User user = JSON.toJavaObject(jsonObject, User.class); list.add(user); }); //遍历全部的用户 list.stream.forEach(e->{System.out.println(e)}); }