万字长文讲解调用第三方接口,RestTemplate,urlConnection使用详解,java代码模拟postman发送请求
万字长文讲解调用第三方接口,RestTemplate,urlConnection使用详解,java代码模拟postman发送请求🔊业务场景:📕新建springmvc项目,项目结构图🖥️post方式 x-www-form-urlencoded key-value只能是string🔖get 方式 传递参数拼接在url上📌post 方式 传递参数url拼接📇post 方式 传递参数为json🧣RestTemplate方式📜 post 方式 传递参数为json📘post 方式 传递参数为form-data 并且传递文件并添加请求头📒post 通过流的方式上传文件🖊️最后总结
🔊业务场景:
在日常开发中,经常需要调用第三方接口,例如调用物流接口,此时需要利用urlConnection或者restTemplate模拟postman发送请求,请求支持加header ,设置content-type支持传递json;请求方式get,post,也可以需要传递文件,或者传递文件流;
下面这个例子就包含日常开发中大部分的请求,可以直接运行,觉得有用收藏点赞不迷路。
📕新建springmvc项目,项目结构图
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
</dependencies>
配置文件
server.port=8089
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=1000MB
User类
importlombok.AllArgsConstructor;
importlombok.Data;
importlombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
publicclassUser {
Stringname;
intage;
publicUser(Stringname) {
this.name=name;
}
@Override
publicStringtoString() {
return"User{"+
"name='"+name+'\''+
", age="+age+
'}';
}
}
UserController类
importcom.alibaba.fastjson.JSON;
importorg.springframework.web.bind.annotation.*;
importorg.springframework.web.multipart.MultipartFile;
importjava.util.LinkedHashMap;
importjava.util.Map;
@RestController
@RequestMapping("/user")
publicclassUserController {
@GetMapping("/loginGet")
publicStringloginGet(Stringname,Integerage){
System.out.println(name+""+age);
Useruser=newUser(name,age);
returnJSON.toJSONString(user);
}
@PostMapping("/login")
publicStringlogin(Useruser){
System.out.println(user);
returnJSON.toJSONString(user);
}
@PostMapping("/upload")
publicMap<String, String>login(Useruser, @RequestParam("file") MultipartFilefile){
System.out.println(user);
System.out.println(file.getName());
Map<String, String>fileMetadata=newLinkedHashMap<>();
fileMetadata.put("文件名", file.getOriginalFilename());
fileMetadata.put("文件类型", file.getContentType());
fileMetadata.put("文件大小(byte)", String.valueOf(file.getSize()));
returnfileMetadata;
}
@PostMapping("/loginJson")
publicStringloginJson(@RequestBodyUseruser){
System.out.println(user);
returnJSON.toJSONString(user);
}
}
🖥️post方式 x-www-form-urlencoded key-value只能是string
对应java代码
importlombok.extern.slf4j.Slf4j;
importorg.apache.http.HttpEntity;
importorg.apache.http.NameValuePair;
importorg.apache.http.client.entity.UrlEncodedFormEntity;
importorg.apache.http.client.methods.CloseableHttpResponse;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.impl.client.CloseableHttpClient;
importorg.apache.http.impl.client.HttpClients;
importorg.apache.http.message.BasicNameValuePair;
importorg.apache.http.util.EntityUtils;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Map;
/**
* @ClassName JavaNice
* post x-www-form-urlencoded key-value只能是string
**/
@Slf4j
publicclassPostUtils {
privatestaticfinalStringENCODING="UTF-8";
/**
* post x-www-form-urlencoded key-value只能是string*
* @param url
* @param paramsMap
* @return
*/
publicstaticStringsendPost(Stringurl, Map<String, String>paramsMap) {
CloseableHttpClientclient=HttpClients.createDefault();
StringresponseText="";
CloseableHttpResponseresponse=null;
try {
HttpPostmethod=newHttpPost(url);
if (paramsMap!=null) {
List<NameValuePair>paramList=newArrayList<NameValuePair>();
for (Map.Entry<String, String>param : paramsMap.entrySet()) {
NameValuePairpair=newBasicNameValuePair(param.getKey(), param.getValue());
paramList.add(pair);
}
method.setEntity(newUrlEncodedFormEntity(paramList, ENCODING));
}
response=client.execute(method);
HttpEntityentity=response.getEntity();
if (entity!=null) {
responseText=EntityUtils.toString(entity);
}
} catch (Exceptione) {
log.error("http request failed",e);
} finally {
try {
response.close();
} catch (Exceptione) {
log.error("",e);
}
}
returnresponseText;
}
}
调用代码
@Test
voidpostString() {
//post x-www-form-urlencoded key-value只能是string
Map<String,String>user=newHashMap<>();
user.put("name","javaNice");
Stringjson=JSONObject.toJSONString(user);
Map<String,String>paramsMap=JSONObject.parseObject(json,Map.class);
System.out.println(json);
Stringresp=PostUtils.sendPost("http://localhost:8089/user/login",paramsMap);
System.out.println(resp);
}
🔖get 方式 传递参数拼接在url上
📌post 方式 传递参数url拼接
📇post 方式 传递参数为json
工具类
importcom.alibaba.fastjson.JSONObject;
importorg.springframework.util.StringUtils;
importjava.io.*;
importjava.net.HttpURLConnection;
importjava.net.URL;
importjava.net.URLConnection;
importjava.net.URLEncoder;
importjava.util.List;
importjava.util.Map;
publicclassHttpRequestUtil {
publicstaticStringsendGet(Stringurl, Stringparam) {
Stringresult="";
BufferedReaderin=null;
try {
if (!url.contains("?")) {
url+="?1=1";
}
if (!param.startsWith("&")) {
url+="&";
}
StringurlNameString=url+param;
URLrealUrl=newURL(urlNameString);
// 打开和URL之间的连接
URLConnectionconnection=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=newBufferedReader(newInputStreamReader(
connection.getInputStream()));
Stringline;
while ((line=in.readLine()) !=null) {
result+=line;
}
} catch (Exceptione) {
System.out.println("发送GET请求出现异常!"+e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in!=null) {
in.close();
}
} catch (Exceptione2) {
e2.printStackTrace();
}
}
returnresult;
}
publicstaticStringsendPost(Stringurl, Stringparam) {
HttpURLConnectionhttpURLConnection=null;
OutputStreamout=null; //写
InputStreamin=null; //读
intresponseCode=0; //远程主机响应的HTTP状态码
Stringresult="";
try {
URLsendUrl=newURL(url);
httpURLConnection= (HttpURLConnection) sendUrl.openConnection();
//post方式请求
httpURLConnection.setRequestMethod("POST");
//一定要设置 Content-Type 要不然服务端接收不到参数
httpURLConnection.setRequestProperty("Content-Type", "application/json");
//指示应用程序要将数据写入URL连接,其值默认为false(是否传参)
httpURLConnection.setDoOutput(true);
//httpURLConnection.setDoInput(true);
httpURLConnection.setUseCaches(false);
httpURLConnection.setConnectTimeout(30000); //30秒连接超时
httpURLConnection.setReadTimeout(30000); //30秒读取超时
//获取输出流
out=httpURLConnection.getOutputStream();
//输出流里写入POST参数
out.write(param.getBytes());
out.flush();
out.close();
responseCode=httpURLConnection.getResponseCode();
BufferedReaderbr=newBufferedReader(newInputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
result=br.readLine();
} catch (Exceptione) {
e.printStackTrace();
}
returnresult;
}
publicstaticStringobjectToUrlParam(Objectobject) {
if (object!=null) {
StringBuilderbuilder=newStringBuilder();
// JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));
Map<String, Object>map=JSONObject.parseObject(JSONObject.toJSONString(object), Map.class);
for (Map.Entry<String, Object>entry :
map.entrySet()) {
if (entry.getValue() !=null&&!StringUtils.isEmpty(entry.getValue().toString())) {
builder.append("&").append(entry.getKey()).append("=").append(encode(entry.getValue()));
}
}
returnbuilder.toString();
}
return"";
}
publicstaticStringencode(Objectobject) {
if (object!=null) {
try {
returnURLEncoder.encode(object.toString(), "utf-8");
} catch (UnsupportedEncodingExceptione) {
e.printStackTrace();
thrownewRuntimeException("字符串编码失败");
}
}
return"";
}
}
调用代码
@Test
voidget() {
//get 方式 传递参数拼接在url上
Useruser=newUser("javaNice",666);
StringparamsMap=HttpRequestUtil.objectToUrlParam(user);
Stringresp=HttpRequestUtil.sendGet("http://localhost:8089/user/loginGet",paramsMap);
System.out.println(resp);
}
@Test
voidpostUrl() {
//post 方式 传递参数url拼接
Useruser=newUser("javaNice",666);
StringparamsMap=HttpRequestUtil.objectToUrlParam(user);
System.out.println("传递参数"+paramsMap);
Stringurl="http://localhost:8089/user/login?1=1"+paramsMap;
Stringresp=HttpRequestUtil.sendPost(url,"");
System.out.println("返回参数"+resp);
}
@Test
voidpost() {
//post 方式 传递参数为json
Useruser=newUser("javaNice",666);
StringparamsMap=JSON.toJSONString(user);
System.out.println("传递参数"+paramsMap);
Stringresp=HttpRequestUtil.sendPost("http://localhost:8089/user/loginJson",paramsMap);
System.out.println("返回参数"+resp);
}
🧣RestTemplate方式
📜 post 方式 传递参数为json
@Test
voidpost() {
//post 方式 传递参数为json
RestTemplaterestTemplate=newRestTemplate();
Stringurl="http://localhost:8089/user/loginJson";
Userbody=newUser("javaNice", 666);
Userresult=restTemplate.postForObject(url, body, User.class);
System.out.println("返回参数"+result);
}
📘post 方式 传递参数为form-data 并且传递文件并添加请求头
@Test
voidpostFormFile() {
//post 方式 传递参数为form-data 并且传递文件
RestTemplaterestTemplate=newRestTemplate();
Stringurl="http://localhost:8089/user/upload";
//①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
MultiValueMap<String, Object>body=newLinkedMultiValueMap<>();
//调用add方法放入表单元素(表单名称:值)
//②:文件对应的类型,需要是org.springframework.core.io.Resource类型的,常见的有[FileSystemResource、InputStreamResource、ByteArrayResource]
body.add("file", newFileSystemResource("/java/com/example/springmvc/22c017e48ea445199708dc1d2832dae5.pdf"));
body.add("name", "javaNice");
body.add("age", "666");
//③:头
HttpHeadersheaders=newHttpHeaders();
headers.add("header1", "v1");
headers.add("header2", "v2");
//④:请求实体
RequestEntity<MultiValueMap<String, Object>>requestEntity=newRequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
//⑤:发送请求(请求实体,返回值需要转换的类型)
ResponseEntity<Map<String, String>>responseEntity=restTemplate.exchange(
requestEntity,
newParameterizedTypeReference<Map<String, String>>() {
});
Map<String, String>result=responseEntity.getBody();
System.out.println(result);
}
📒post 通过流的方式上传文件
@Test
voidpostFormFileStream() {
RestTemplaterestTemplate=newRestTemplate();
Stringurl="http://localhost:8089/user/upload";
//①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
MultiValueMap<String, Object>body=newLinkedMultiValueMap<>();
/**
* ②:通过流的方式上传文件,流的方式需要用到InputStreamResource类,需要重写2个方法
* getFilename:文件名称
* contentLength:长度
*/
Filefile=newFile("/java/com/example/springmvc/22c017e48ea445199708dc1d2832dae5.pdf");
//2、建立数据通道
try {
InputStreaminputStream=newFileInputStream(file);
InputStreamResourceinputStreamResource=newInputStreamResource(inputStream) {
@Override
publicStringgetFilename() {
return"22c017e48ea445199708dc1d2832dae5.pdf";
}
@Override
publiclongcontentLength() throwsIOException {
returninputStream.available();
}
};
body.add("file", inputStreamResource);
body.add("name", "javaNice");
body.add("age", "666");
//③:头
HttpHeadersheaders=newHttpHeaders();
headers.add("header1", "v1");
headers.add("header2", "v2");
//④:请求实体
RequestEntity<MultiValueMap<String, Object>>requestEntity=newRequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
//⑤:发送请求(请求实体,返回值需要转换的类型)
ResponseEntity<Map<String, String>>responseEntity=restTemplate.exchange(
requestEntity,
newParameterizedTypeReference<Map<String, String>>() {
});
Map<String, String>result=responseEntity.getBody();
System.out.println(result);
} catch (FileNotFoundExceptione) {
e.printStackTrace();
}
}
🖊️最后总结
🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍。