坐标如下:
cn.hutool hutool-all 5.8.17
关键代码:
// 携带的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();
commons-httpclient commons-httpclient3.1 org.apache.httpcomponents httpclient4.5.3
添加工具类
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();
}
注意点: Cloud-Feign与parent-SpringBoot的版本冲突问题, 拓展时候使用github的openfeign
8 8 UTF-8 UTF-8 1.8 3.1.0 5.4.5 29.0-jre 8.0.21 3.2.1 2.1.2-RELEASE org.apache.httpcomponents httpclient 4.5.3 io.github.openfeign feign-httpclient 10.1.0 应该只需要上边的就行了,我这边就都贴出来了 org.springframework.cloud spring-cloud-starter-openfeign 2.2.7.RELEASE org.projectlombok lombok RELEASE com.alibaba.fastjson2 fastjson2 2.0.23 cn.hutool hutool-all ${hutool.version} commons-httpclient commons-httpclient 3.1 org.apache.httpcomponents httpclient 4.5.3 org.apache.httpcomponents httpmime 4.5.3 commons-io commons-io 2.3
本项目Boot版本
org.springframework.boot spring-boot-starter-parent 2.3.1.RELEASE
问题:
NoSuchMethodError: feign.Response.create(ILjava/lang/Strin
creating bean with name ‘configurationPropertiesBeans’ de
感觉写不写都可以吧, 反正就是弄个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;
}
}
主要是为了拓展fegin的Get携带Body功能, enabled改成true
logging:
level:
com.hong.feign: DEBUG
feign:
httpclient:
enabled: true
server:
port: 8888
@EnableFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
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;
}
写配置类
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 httpEntity = new HttpEntity<>(JSON.toJSONString(map), headers);
ResponseEntity exchange = restTemplate.exchange(domain+beng, HttpMethod.GET, httpEntity, String.class);
System.out.println(exchange.getBody());
如果配置了第二个配置类, 使用可以试试
HttpHeaders head = new HttpHeaders(); head.setContentType(MediaType.APPLICATION_JSON); HttpEntityentity = new HttpEntity<>(JSON.toJSONString(map), headers); log.info("url:" + url + ",httpEntity:" + JSON.toJSONString(entity)); ResponseEntity
总有写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