GET携带Body发送请求的各种方式
1. 使用Hutool工具类, 最方便
坐标如下:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.17</version>
</dependency>
关键代码:
// 携带的body数据构造
Map body = new HashMap<>();
Map head = new HashMap<>();
head.put("username","username");
head.put("password","password");
body.put("head",head);
String bodyStr = JSON.toJSONString(body);
String reponse = "";
HttpResponse result = HttpUtil.createGet(url)
.header(Header.ACCEPT_ENCODING,"gzip, deflate, br")
.header(Header.ACCEPT,"*/*")
.header(Header.CONTENT_TYPE,"application/json")
.header(Header.CONNECTION,"keep-alive")
.body(bodyStr) //携带数据
.execute();
response = result.body();
2. 使用HttpComponent
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
添加工具类
package com.hong.util;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.GzipDecompressingEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class SendGet {
public static String sendJsonByGetReq(String url,String param,String encoding)throws Exception{
String body = "";
CloseableHttpClient client = HttpClients.createDefault();
HttpGetWithEntity myGet = new HttpGetWithEntity(url);
//String tmp = "{ \"head\": {\"password\":\"Sczh!2021\",\"username\":\"sczh\"} }";
HttpEntity httpEntity = new StringEntity(param, ContentType.APPLICATION_JSON);
myGet.setEntity(httpEntity);
myGet.setHeader("Content-Type","application/json");
myGet.setHeader("Accept","*/*");
myGet.setHeader("Accept-Encoding","gzip, deflate, br");
myGet.setHeader("Connection","keep-alive");
CloseableHttpResponse response = client.execute(myGet);
HttpEntity entity = response.getEntity();
if(entity!= null){
body = EntityUtils.toString(entity,encoding);
System.out.println("直接接收到的数据:"+body);
}
response.close();
return body;
}
}
使用
// 携带的body数据构造
Map body = new HashMap<>();
Map head = new HashMap<>();
head.put("username","username");
head.put("password","password");
body.put("head",head);
String respJson = "";
try {
//使用Http
respJson = SendGet.sendJsonByGetReq(url, JSON.toJSONString(body), "utf-8");
}catch (Exception e) {
e.printStackTrace();
}
SpringBoot整合Fegin
注意点: Cloud-Feign与parent-SpringBoot的版本冲突问题, 拓展时候使用github的openfeign
3. 使用Fegin调用 Get携带Body参数
<1> 导入坐标
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatis.plus.version>3.1.0</mybatis.plus.version>
<hutool.version>5.4.5</hutool.version>
<guava.version>29.0-jre</guava.version>
<mysql.version>8.0.21</mysql.version>
<easyexcel.version>3.2.1</easyexcel.version>
<battcn.swagger.version>2.1.2-RELEASE</battcn.swagger.version>
</properties>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>10.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.7.RELEASE</version>
</dependency>
应该只需要上边的就行了,我这边就都贴出来了
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.23</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
本项目Boot版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/>
</parent>
问题:
Cloud-OpenFeign 的版本和SpringBoot的版本冲突问题
, 有冲突会会报如下错误, 届时需要自行找自己的Boot版本对应的Cloud-OpenFeign 版本
NoSuchMethodError: feign.Response.create(ILjava/lang/Strin
creating bean with name ‘configurationPropertiesBeans’ deFeign拓展Get携带Body
时, 需要导入io.github.openfeign和org.apache.httpcomponents
, 注意导入的是github的openfeign
, 当时找资源的时候, 有的导入的是netflix的, 结果不行;
<2> 写配置类
感觉写不写都可以吧, 反正就是弄个debug级别, 方便看调用, 贴tm一下吧
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CcusFeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
<3> 写配置
主要是为了拓展fegin的Get携带Body功能, enabled改成true
logging:
level:
com.hong.feign: DEBUG
feign:
httpclient:
enabled: true
server:
port: 8888
<4> 启动类开启功能
@EnableFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
<5> 试试好用不
feign包的远程接口类
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@FeignClient(name = "TestFegin", url = "http://localhost:8082")
public interface TestFeign {
@GetMapping("/body")
String test(@RequestBody Map map);
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello(@RequestParam String name);
}
使用feign调用
@Slf4j
@RestController
public class HelloController {
@Autowired
private TestFeign testFeign;
@GetMapping("test/fegin")
public String testFegin(){
Map map = new HashMap();
map.put("aa","bbb");
//String test = testFeign.hello("张三");
//System.out.println("result --> "+test);
String test2 = testFeign.test(map);
System.out.println("resutl -> "+ test2);
return "ok-feign";
}
@GetMapping("/body")
public String body(@RequestBody Map map){
return "body";
}
@GetMapping("/hello")
public String hello(String name){
return "hello"+name;
}
4. 使用RestTemplate发送Get请求携带Body参数
写配置类
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import java.net.URI;
public class HttpComponentsClientRestfulHttpRequestFactory extends HttpComponentsClientHttpRequestFactory {
@Override
protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
if (httpMethod == HttpMethod.GET) {
return new HttpGetRequestWithEntity(uri);
}
return super.createHttpUriRequest(httpMethod, uri);
}
/**
* 定义HttpGetRequestWithEntity实现HttpEntityEnclosingRequestBase抽象类,以支持GET请求携带body数据
*/
private static final class HttpGetRequestWithEntity extends HttpEntityEnclosingRequestBase {
public HttpGetRequestWithEntity(final URI uri) {
super.setURI(uri);
}
@Override
public String getMethod() {
return HttpMethod.GET.name();
}
}
}
后续为了拓展成一个可以继续加配置类
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
return restTemplate;
}
// 设置超时时间
private SimpleClientHttpRequestFactory getClientHttpRequestFactory() {
SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
// Connect timeout 3s
clientHttpRequestFactory.setConnectTimeout(60000);
// Read timeout 3s
clientHttpRequestFactory.setReadTimeout(60000);
return clientHttpRequestFactory;
}
}
开始使用
Map map = new HashMap();
Map header = new HashMap();
header.put("password","password");
header.put("username","username");
map.put("header",header);
RestTemplate restTemplate = new RestTemplate();
//修改restTemplate的RequestFactory使其支持Get携带body参数
restTemplate.setRequestFactory(new HttpComponentsClientRestfulHttpRequestFactory());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Accept-Encoding","gzip,deflate,br");
headers.set("Accept-Encoding","deflate");
HttpEntity<String> httpEntity = new HttpEntity<>(JSON.toJSONString(map), headers);
ResponseEntity<String> exchange = restTemplate.exchange(domain+beng, HttpMethod.GET, httpEntity, String.class);
System.out.println(exchange.getBody());
如果配置了第二个配置类, 使用可以试试
HttpHeaders head = new HttpHeaders();
head.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(map), headers);
log.info("url:" + url + ",httpEntity:" + JSON.toJSONString(entity));
ResponseEntity<Object> response = restTemplate.exchange(domain+beng, HttpMethod.GET, httpEntity, Object.class);
log.info("{}请求的返回内容:{}", url, JSON.parseObject(JSON.toJSONString(response.getBody())));
写个B文章真NM累, 还NM找不到工作, CTMD
总有写B崽子, 搞些奇奇怪怪的东西, Get请求?传参不就行了, 非搞点新花样
这篇文章的诞生就是由于领导无能, 团队不合作, NM累死ND, 场景就是, 第三方搞了个Get+Body, Response用Gzip压缩响应, 搞他妈半天
-
一开始, 寻思直接拓展一个GET+Body完事, 结果拓展完了调用第三方一直乱码, 我擦嘞, 这什么情况, 以为是工具类不行, 公司站着说话不腰疼的B, 说你用RestTemplate, 这个好, 我寻思不也是http请求嘛, 整, 然后不行, 又说, 你用Feign调用, 这个B更叼, 我寻思不还是Ribbon+RestTemplate嘛, 整, 结果还不行;Response还是乱码
-
我擦嘞, 搞了半天, 怎么都是乱码, 后来一看, 大哥tm写的账号密码写反了, 账号成密码, 密码成账号, 我擦嘞
-
改完以后结果发现还不行, 但是发现不能太相信大哥了, 然后仔细对各种参数, 发现, header携带参数不对, 对象都是用fastjson2转的, 我tm怀疑过fastjson2不行, 都没怀疑过公司的dm大哥, 后来发现, 他特么不知道在啥时候已经把对象转成字符串了, 然后我处理Get拓展的时候, 又进行了转换, 变成双引号+引号, 出现了双引号转义, 我擦嘞…DisuNM