万字长文讲解调用第三方接口,RestTemplate,urlConnection 使用详解,java 代码模拟 postman 发送请求
作者:javaNice
- 2023-11-20 四川
本文字数:7802 字
阅读完需:约 26 分钟
万字长文讲解调用第三方接口,RestTemplate,urlConnection 使用详解,java 代码模拟 postman 发送请求
🔊业务场景:
在日常开发中,经常需要调用第三方接口,例如调用物流接口,此时需要利用 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 类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
int age;
public User(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
复制代码
UserController 类
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.LinkedHashMap;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/loginGet")
public String loginGet(String name,Integer age){
System.out.println(name+""+age);
User user=new User(name,age);
return JSON.toJSONString(user);
}
@PostMapping("/login")
public String login(User user){
System.out.println(user);
return JSON.toJSONString(user);
}
@PostMapping("/upload")
public Map<String, String> login(User user, @RequestParam("file") MultipartFile file){
System.out.println(user);
System.out.println(file.getName());
Map<String, String> fileMetadata = new LinkedHashMap<>();
fileMetadata.put("文件名", file.getOriginalFilename());
fileMetadata.put("文件类型", file.getContentType());
fileMetadata.put("文件大小(byte)", String.valueOf(file.getSize()));
return fileMetadata;
}
@PostMapping("/loginJson")
public String loginJson(@RequestBody User user){
System.out.println(user);
return JSON.toJSONString(user);
}
}
复制代码
🖥️post 方式 x-www-form-urlencoded key-value 只能是 string
对应 java 代码
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
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 java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @ClassName JavaNice
* post x-www-form-urlencoded key-value只能是string
**/
@Slf4j
public class PostUtils {
private static final String ENCODING = "UTF-8";
/**
* post x-www-form-urlencoded key-value只能是string*
* @param url
* @param paramsMap
* @return
*/
public static String sendPost(String url, Map<String, String> paramsMap) {
CloseableHttpClient client = HttpClients.createDefault();
String responseText = "";
CloseableHttpResponse response = null;
try {
HttpPost method = new HttpPost(url);
if (paramsMap != null) {
List<NameValuePair> paramList = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> param : paramsMap.entrySet()) {
NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
paramList.add(pair);
}
method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING));
}
response = client.execute(method);
HttpEntity entity = response.getEntity();
if (entity != null) {
responseText = EntityUtils.toString(entity);
}
} catch (Exception e) {
log.error("http request failed",e);
} finally {
try {
response.close();
} catch (Exception e) {
log.error("",e);
}
}
return responseText;
}
}
复制代码
调用代码
@Test
void postString() {
//post x-www-form-urlencoded key-value只能是string
Map<String,String> user=new HashMap<>();
user.put("name","javaNice");
String json = JSONObject.toJSONString(user);
Map<String,String> paramsMap = JSONObject.parseObject(json,Map.class);
System.out.println(json);
String resp = PostUtils.sendPost("http://localhost:8089/user/login",paramsMap);
System.out.println(resp);
}
复制代码
🔖get 方式 传递参数拼接在 url 上
📌post 方式 传递参数 url 拼接
📇post 方式 传递参数为 json
工具类
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StringUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
public class HttpRequestUtil {
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
if (!url.contains("?")) {
url += "?1=1";
}
if (!param.startsWith("&")) {
url += "&";
}
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;
}
public static String sendPost(String url, String param) {
HttpURLConnection httpURLConnection = null;
OutputStream out = null; //写
InputStream in = null; //读
int responseCode = 0; //远程主机响应的HTTP状态码
String result = "";
try {
URL sendUrl = new URL(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();
BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
result = br.readLine();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String objectToUrlParam(Object object) {
if (object != null) {
StringBuilder builder = new StringBuilder();
// 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()));
}
}
return builder.toString();
}
return "";
}
public static String encode(Object object) {
if (object != null) {
try {
return URLEncoder.encode(object.toString(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException("字符串编码失败");
}
}
return "";
}
}
复制代码
调用代码
@Test
void get() {
//get 方式 传递参数拼接在url上
User user=new User("javaNice",666);
String paramsMap = HttpRequestUtil.objectToUrlParam(user);
String resp = HttpRequestUtil.sendGet("http://localhost:8089/user/loginGet",paramsMap);
System.out.println(resp);
}
@Test
void postUrl() {
//post 方式 传递参数url拼接
User user=new User("javaNice",666);
String paramsMap = HttpRequestUtil.objectToUrlParam(user);
System.out.println("传递参数"+paramsMap);
String url="http://localhost:8089/user/login?1=1"+paramsMap;
String resp = HttpRequestUtil.sendPost(url,"");
System.out.println("返回参数"+resp);
}
@Test
void post() {
//post 方式 传递参数为json
User user=new User("javaNice",666);
String paramsMap = JSON.toJSONString(user);
System.out.println("传递参数"+paramsMap);
String resp = HttpRequestUtil.sendPost("http://localhost:8089/user/loginJson",paramsMap);
System.out.println("返回参数"+resp);
}
复制代码
🧣RestTemplate 方式
📜 post 方式 传递参数为 json
@Test
void post() {
//post 方式 传递参数为json
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8089/user/loginJson";
User body = new User("javaNice", 666);
User result = restTemplate.postForObject(url, body, User.class);
System.out.println("返回参数" + result);
}
复制代码
📘post 方式 传递参数为 form-data 并且传递文件并添加请求头
@Test
void postFormFile() {
//post 方式 传递参数为form-data 并且传递文件
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8089/user/upload";
//①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
//调用add方法放入表单元素(表单名称:值)
//②:文件对应的类型,需要是org.springframework.core.io.Resource类型的,常见的有[FileSystemResource、InputStreamResource、ByteArrayResource]
body.add("file", new FileSystemResource("/java/com/example/springmvc/22c017e48ea445199708dc1d2832dae5.pdf"));
body.add("name", "javaNice");
body.add("age", "666");
//③:头
HttpHeaders headers = new HttpHeaders();
headers.add("header1", "v1");
headers.add("header2", "v2");
//④:请求实体
RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
//⑤:发送请求(请求实体,返回值需要转换的类型)
ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
requestEntity,
new ParameterizedTypeReference<Map<String, String>>() {
});
Map<String, String> result = responseEntity.getBody();
System.out.println(result);
}
复制代码
📒post 通过流的方式上传文件
@Test
void postFormFileStream() {
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8089/user/upload";
//①:表单信息,需要放在MultiValueMap中,MultiValueMap相当于Map<String,List<String>>
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
/**
* ②:通过流的方式上传文件,流的方式需要用到InputStreamResource类,需要重写2个方法
* getFilename:文件名称
* contentLength:长度
*/
File file = new File("/java/com/example/springmvc/22c017e48ea445199708dc1d2832dae5.pdf");
//2、建立数据通道
try {
InputStream inputStream = new FileInputStream(file);
InputStreamResource inputStreamResource = new InputStreamResource(inputStream) {
@Override
public String getFilename() {
return "22c017e48ea445199708dc1d2832dae5.pdf";
}
@Override
public long contentLength() throws IOException {
return inputStream.available();
}
};
body.add("file", inputStreamResource);
body.add("name", "javaNice");
body.add("age", "666");
//③:头
HttpHeaders headers = new HttpHeaders();
headers.add("header1", "v1");
headers.add("header2", "v2");
//④:请求实体
RequestEntity<MultiValueMap<String, Object>> requestEntity = new RequestEntity<>(body, headers, HttpMethod.POST, URI.create(url));
//⑤:发送请求(请求实体,返回值需要转换的类型)
ResponseEntity<Map<String, String>> responseEntity = restTemplate.exchange(
requestEntity,
new ParameterizedTypeReference<Map<String, String>>() {
});
Map<String, String> result = responseEntity.getBody();
System.out.println(result);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
复制代码
🖊️最后总结
🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍。
划线
评论
复制
发布于: 刚刚阅读数: 4
javaNice
关注
还未添加个人签名 2023-11-02 加入
还未添加个人简介
评论