对接HTTP接口主要有两种方式
当前方式主要是通过构造HTTP请求进行对第三方接口进行调用,返回JSON数据,为了方便起见可以使用HTTPUtil对常用的请求方式进行封装,在进行调用时直接传参构造请求即可。
@Test
void test() throws IOException {
String url;
String requestUrl = UrlConstant.WeatherUrl;
String appid = "57847229";
String appsecret = "jN4fUx1a";
String lng = "114.302953";
String lat = "30.585411";
url = String.format("%s?appid=%s&appsecret=%s&lng=%s&lat=%s&version=v11",
requestUrl,
appid,
appsecret,
lng,
lat);
//这里构造了url,也可直接使用String类型直接定义url
//String url = "https://v0.yiketianqi.com/api?appid=57847229&appsecret=jN4fUx1a&lng=114.302953&lat=30.585411&version=v11";
log.warn(url);
//使用httpUtil方式
String s = HttpUtil.get(url);
log.info(s);
}
输出格式化后的JSON数据:得到的JSON数据可以使用FastJson或者GSON进行格式化解析,该技术非本篇主要内容,若使用FastJson有问题请自行Google/百度
{
"errcode":0,
"time":"2020-10-05 15:10:00",
"update_time":"2020-10-05 15:05:00",
"msg":"30分钟后开始下小雨,不过100分钟后雨就停了",
"data":[
{
"time":"2020-10-05 15:20:00",
"level":"",
"value":"0"
},
{
"time":"2020-10-05 15:25:00",
"level":"",
"value":"0"
},
{
"time":"2020-10-05 15:30:00",
"level":"",
"value":"0"
},
{
"time":"2020-10-05 15:35:00",
"level":"",
"value":"0"
},
{
"time":"2020-10-05 15:40:00",
"level":"",
"value":"0"
},
{
"time":"2020-10-05 15:45:00",
"level":"",
"value":"0"
},
{
"time":"2020-10-05 15:50:00",
"level":"小雨",
"value":"0.03"
},
{
"time":"2020-10-05 15:55:00",
"level":"小雨",
"value":"0.06"
},
{
"time":"2020-10-05 16:00:00",
"level":"小雨",
"value":"0.09"
},
{
"time":"2020-10-05 16:05:00",
"level":"小雨",
"value":"0.11"
},
{
"time":"2020-10-05 16:10:00",
"level":"小雨",
"value":"0.13"
},
{
"time":"2020-10-05 16:15:00",
"level":"小雨",
"value":"0.14"
},
{
"time":"2020-10-05 16:20:00",
"level":"小雨",
"value":"0.13"
},
{
"time":"2020-10-05 16:25:00",
"level":"小雨",
"value":"0.13"
},
{
"time":"2020-10-05 16:30:00",
"level":"小雨",
"value":"0.1"
},
{
"time":"2020-10-05 16:35:00",
"level":"小雨",
"value":"0.07"
},
{
"time":"2020-10-05 16:40:00",
"level":"小雨",
"value":"0.05"
},
{
"time":"2020-10-05 16:45:00",
"level":"小雨",
"value":"0.05"
},
{
"time":"2020-10-05 16:50:00",
"level":"小雨",
"value":"0.04"
},
{
"time":"2020-10-05 16:55:00",
"level":"小雨",
"value":"0.06"
},
{
"time":"2020-10-05 17:00:00",
"level":"",
"value":"0"
}
]
}
当前使用的案例是调用一个天气的api,获取天气信息
文档地址:https://www.tianqiapi.com/index/doc
字符串拼接详见:
https://www.cnblogs.com/Dhouse/p/7776780.html
我们首先启动一个Post接口的demo,并启动该demo
本地配置文件没有任何配置,所以请求的地址是:
http://localhost:8080/post/post
@org.springframework.web.bind.annotation.RestController
@RequestMapping("/post")
public class RestController {
@PostMapping("/post")
public String post(HttpServletRequest request,
@RequestParam(value = "email", required = false) String email,
@RequestParam(value = "nick", required = false) String nick) {
Map<String, Object> map = new HashMap<>();
map.put("code", "200");
map.put("result", "add " + email + " # " + nick + " success!");
return JSON.toJSONString(map);
}
}
使用HTTPUtils以Post方式请求
@Test
void testByPostUtils() throws Exception{
String url = "http://localhost:8080/post/post";
String email = "http://49.232.21.180:8090/";
String nick = "关忆北_Blog";
Map request = new HashMap<>();
request.put("email", email);
request.put("nick", nick);
String postForm = HttpUtil.postForm(url, request);
//输出打印:
{"result":"add http://49.232.21.180:8090/ # null success!","code":"200"}
}
RestTempalate 简介:
SpringRestTemplate是Spring 提供的用于访问 Rest 服务的客端**(用于发起HTTP请求)**, RestTemplate交由Spring管理,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,所以很多客户端比如Android或者第三方服务商都是使用RestTemplate 请求 restful服务。
借用网络中的整理的API表格
详情可以查看Spring官网
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
API | 说明 |
---|---|
getForEntity() | 发送一个HTTP GET请求,返回的ResponseEntity包含了响应体所映射成的对象 |
getForObject() | 发送一个HTTP GET请求,返回的请求体将映射为一个对象 |
postForEntity() | POST 数据到一个URL,返回包含一个对象的ResponseEntity,这个对象是从响应体中映射得到的 |
postForObject() | POST 数据到一个URL,返回根据响应体匹配形成的对象 |
headForHeaders() | 发送HTTP HEAD请求,返回包含特定资源URL的HTTP头 |
optionsForAllow() | 发送HTTP OPTIONS请求,返回对特定URL的Allow头信息 |
postForLocation() | POST 数据到一个URL,返回新创建资源的URL |
put() | PUT 资源到特定的URL |
delete() | 在特定的URL上对资源执行HTTP DELETE操作 |
exchange() | 在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的 |
execute() | 在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象 |
getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject。
RestTempalate 配置:
使用RestTempalate之前需要对其进行配置,否则会无法注入到Spring中,即使用时,restTempalate是null;将RestTemplate使用@Configuration注解配置:
@Configuration
public class RestTemplateConfig {
//最好是用不注释的方法,在注入的同时设置连接时间,这种注释的也可以,但是没有设置超时时间
/*@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}*/
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
return new RestTemplate(factory);
}
@Bean
public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000);//单位为ms
factory.setConnectTimeout(5000);//单位为ms
return factory;
}
}
更为详尽的配置请参考以下方式:
https://www.jianshu.com/p/2cc999c0b99d
RestTempalate引入使用:
@Autowired
public RestTemplate restTemplate;
@Test
void test() throws IOException {
String url;
String requestUrl = UrlConstant.WeatherUrl;
String appid = "57847229";
String appsecret = "jN4fUx1a";
String lng = "114.302953";
String lat = "30.585411";
url = String.format("%s?appid=%s&appsecret=%s&lng=%s&lat=%s&version=v11",
requestUrl,
appid,
appsecret,
lng,
lat);
log.warn(url);
//使用RestTempalate方式
Weather weather = restTemplate.getForObject(url, Weather.class);
log.info(weather.toString());
log.info(s);
}
输出:
Weather(errcode=0, time=2020-10-05 16:11:00, update_time=2020-10-05 16:05:00, msg=10分钟后雨渐停,不过30分钟后又开始下小雨, data=[WeatherData(time=2020-10-05 16:20:00, level=小雨, value=0.12), WeatherData(time=2020-10-05 16:25:00, level=小雨, value=0.06), WeatherData(time=2020-10-05 16:30:00, level=, value=0), WeatherData(time=2020-10-05 16:35:00, level=, value=0), WeatherData(time=2020-10-05 16:40:00, level=, value=0), WeatherData(time=2020-10-05 16:45:00, level=, value=0), WeatherData(time=2020-10-05 16:50:00, level=小雨, value=0.04), WeatherData(time=2020-10-05 16:55:00, level=小雨, value=0.06), WeatherData(time=2020-10-05 17:00:00, level=小雨, value=0.06), WeatherData(time=2020-10-05 17:05:00, level=小雨, value=0.01), WeatherData(time=2020-10-05 17:10:00, level=, value=0), WeatherData(time=2020-10-05 17:15:00, level=, value=0), WeatherData(time=2020-10-05 17:20:00, level=, value=0), WeatherData(time=2020-10-05 17:25:00, level=, value=0), WeatherData(time=2020-10-05 17:30:00, level=, value=0), WeatherData(time=2020-10-05 17:35:00, level=, value=0), WeatherData(time=2020-10-05 17:40:00, level=, value=0), WeatherData(time=2020-10-05 17:45:00, level=小雨, value=0.02), WeatherData(time=2020-10-05 17:50:00, level=小雨, value=0.04), WeatherData(time=2020-10-05 17:55:00, level=小雨, value=0.05), WeatherData(time=2020-10-05 18:00:00, level=小雨, value=0.08)])
可以发现,使用RestTempalate返回的数据是已经解析到对象中的,在入参中,Weather.class可以理解为是一个Json转换器,把JSON数据转换成(序列化)对象。
注:返回的JSON数据必须与转换器实体类的字段一一对应,否则会无法转义。
@lombok.Data
public class Weather implements Serializable {
private String errcode;
private String time;
private String update_time;
private String msg;
private List<WeatherData> data;
}
与之对比,使用RestTempalate发起HTTP请求,无需再使用FastJson或GSON进行解析返回的数据,当获取对象中的变量时可以直接使用getXXX的方式进行获取。
@Test
public void testPostLocation() {
String url = "http://localhost:8080/post/post";
String email = "http://49.232.21.180:8090/";
String nick = "关忆北_Blog";
MultiValueMap<String, String> request = new LinkedMultiValueMap<>();
request.add("email", email);
request.add("nick", nick);
// 使用方法三
URI uri = restTemplate.postForLocation(url, request);
System.out.println(uri);
}
输出:
{"result":"add http://49.232.21.180:8090/ # 关忆北_Blog success!","code":"200"}
MultiValueMap
封装,同样是kv结构https://github.com/FirstMrRight/abutment
个人网站已同步更新,阅读效果更佳