首先需求是这样的,登陆之后要在页面上展示位置信息以及天气信息,设计到两个api地址,首先是百度的api,如下图:
调用图中圈起来的api,账号申请都比较简单,在这里就不说了。
调用代码如下:
/**
* 调用百度地图的地址
*/
private static final String GET_CITY_URL = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=写你自己的ak&output=json&coordtype=bd09ll&location=";
/**
* 根据经纬度 获取城市名称
*
* @param lat 纬度
* @param lon 经度
* @return
*/
public static String getCityName(String lat, String lon) {
JSONObject jsonObject = JSONObject.parseObject(HttpRequestUtil.sendGet(GET_CITY_URL + lat + "," + lon));
if ("0".equals(jsonObject.get("status").toString())) {
JSONObject resultInfo = JSONObject.parseObject(jsonObject.get("result").toString());
JSONObject addressInfo = JSONObject.parseObject(resultInfo.get("addressComponent").toString());
return addressInfo.get("city").toString();
}
throw new MyException("根据经纬度获取城市信息出现错误");
}
这里用到的http请求工具待会儿粘贴到下边,包的层级比较多,所以解析了好几次,至于解析失败的话可以根据自己的情况去写。
这样城市名称就拿到了。接下来是获取天气信息,我这里用的是和风天气api,每天前1000次免费:
这个百度一搜就可以找到官网,账号申请也是比较简单的,直接上代码:
/**
* 调用和风天气api的地址
*/
private static final String GET_WEATHER_URL = "https://devapi.qweather.com/v7/weather/now?gzip=n&key=写你的key&location=";
/**
* 根据经纬度 获取当地天气信息
*
* @param lon 经度
* @param lat 纬度
* @return
*/
public static Map getCityWeather(String lat, String lon) {
JSONObject jsonObject = JSONObject.parseObject(HttpRequestUtil.sendGet(GET_WEATHER_URL + lon + "," + lat));
if ("200".equals(jsonObject.get("code"))) {
JSONObject weatherInfo = JSONObject.parseObject(jsonObject.get("now").toString());
Map<String, Object> resultMap = new HashMap<>(16);
resultMap.put("date", DateUtil.dateToStr(new Date(), DateUtil.YYYY_MM_DD_HH_MM_SS));
resultMap.put("city", getCityName(lat, lon));
resultMap.put("weather", weatherInfo.get("text").toString());
resultMap.put("temperature", weatherInfo.get("temp").toString());
resultMap.put("humidity", weatherInfo.get("humidity").toString() + "%");
resultMap.put("windDir", weatherInfo.get("windDir").toString());
resultMap.put("windScale", weatherInfo.get("windScale").toString());
return resultMap;
}
throw new MyException("获取天气信息出错");
}
我这里是对应我最开始的需求,直接把所有信息都封装到map中了,根据自己的实际需求来就可以了。
以下是http请求的工具类:
package com.sztf.shidaikeyi.util;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* 发送接口请求工具类
*
* @author ljp
* @date 2020/10/20 15:38
*/
@Slf4j
public class HttpRequestUtil {
/**
* 发送https请求
*
* @param path
* @param method
* @param body
* @return
*/
public static String sendGetHttps(String path, String method, String body) {
if (path == null || method == null) {
return null;
}
String response = null;
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
HttpsURLConnection conn = null;
try {
// 创建SSLConrext对象,并使用我们指定的信任管理器初始化
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
TrustManager[] tm = {new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}};
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上面对象中得到SSLSocketFactory
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(path);
conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(ssf);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
// 设置请求方式(get|post)
conn.setRequestMethod(method);
// 有数据提交时
if (null != body) {
OutputStream outputStream = conn.getOutputStream();
outputStream.write(body.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
inputStream = conn.getInputStream();
inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
StringBuffer buffer = new StringBuffer();
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
response = buffer.toString();
} catch (Exception e) {
} finally {
if (conn != null) {
conn.disconnect();
}
try {
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
} catch (IOException execption) {
}
}
return response;
}
/**
* 向指定URL发送GET方法的请求
*
* @param url 发送请求的URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定URL发送GET方法的请求
*
* @param url 发送请求的URL
* @param
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url) {
String result = "";
BufferedReader in = null;
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
log.error("发送GET请求出现异常:" + e.getMessage());
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception ex) {
log.error(ex.getMessage());
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
log.error("发送 POST 请求出现异常:" + e.getMessage());
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
log.error(ex.getMessage());
}
}
return result;
}
/**
* 发送post请求
*
* @param url
* @param param
* @return
*/
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
/**
* 发送post请求
*
* @param url 请求路径
* @param jsonObject 请求参数
* @return
*/
public static Map post(String url, JSONObject jsonObject) {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForEntity(url, jsonObject, Map.class).getBody();
}
}
需要注意的一点就是百度的api和天气api经纬度是反的,一个是纬度在前,一个是经度在前,输错了是无法正确调取成功的。