坐标如下:
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"); HttpEntityhttpEntity = 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