万字长文讲解调用第三方接口,RestTemplate,urlConnection使用详解,java代码模拟postman发送请求

简介: 万字长文讲解调用第三方接口,RestTemplate,urlConnection使用详解,java代码模拟postman发送请求

万字长文讲解调用第三方接口,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();

   }

}

🖊️最后总结

🖲要熟练掌握技巧,一定多多坚持练习:骐骥一跃,不能十步;驽马十驾,功在不舍


目录
相关文章
|
21天前
|
JSON Java 数据格式
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
74 25
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
|
3天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
19 3
|
11天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
43 6
|
29天前
|
Java
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
java小工具util系列4:基础工具代码(Msg、PageResult、Response、常量、枚举)
51 24
|
11天前
|
前端开发 Java 测试技术
java日常开发中如何写出优雅的好维护的代码
代码可读性太差,实际是给团队后续开发中埋坑,优化在平时,没有那个团队会说我专门给你一个月来优化之前的代码,所以在日常开发中就要多注意可读性问题,不要写出几天之后自己都看不懂的代码。
49 2
|
25天前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
65 5
|
25天前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
49 5
|
27天前
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####
|
24天前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
1天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者