解决Feign调用的GET参数传递的问题

网友投稿 734 2022-08-23


解决Feign调用的GET参数传递的问题

目录需求思考GET方式请求①GET方式请求②GET方式请求③

需求

​ 在消费方服务通过GET方式,访问服务提供方的接口,需要传递多参数,拆分成多个参数的方式访问,不太适合用在该场景,需要改造成合适的方式调用服务方的接口

思考

拆分成多个参数时,若GET请求的参数超过3个及以上时,便不适用该种方式请求服务,因为这样传递参数过于臃肿,可读性也比较差;

若改造成POST请求的方式,虽然解决参数过多的问题,但是也带来了其他的开销,参数被放到了body里面,然后请求到服务方提供的接口,服务方的接口也改造成了POST方式,改变了原来的GET方式调用的初衷,不太友好;

​ 可以在消费方调用Feign接口时,参数封装到body中,在组装Feign接口请求时,将body里面的参数取出来,转换为GET方式请求的参数,请求body的参数,然后发起请求,实现了GET方式访问服务方提供的接口;

以下是这三种调用方式的具体实现,可以根据适合自己的业务场景去使用,选择不同的方式请求调用:

GET方式请求①

请求DTO对象:

package com.springcloud.pojo;

import java.util.Date;

public class Requets01DTO {

private Date startTime;

private Date endTime;

private String message;

@Override

public String toString() {

return "Requets01DTO{" +

"startTime=" + startTime +

", endTime=" + endTime +

", message='" + message + '\'' +

'}';

}

public Date getStartTime() {

return startTime;

}

public void setStartTime(Date startTime) {

this.startTime = startTime;

}

public Date getEndTime() {

return endTime;

}

public void setEndTime(Date endTime) {

this.endTime = endTime;

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

}

消费方的请求:

@Autowired

GetClient01 getClient01;

@GetMapping("/request/get/01")

public String requestGetOne(Requets01DTO requets01DTO) {

return getClient01.queryDataByGetRequest(requets01DTO.getStartTime(), requets01DTO.getEndTime(), requets01DTO.getMessage());

}

Feign接口:

package com.springcloud.service;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestParam;

import java.util.Date;

@FeignClient(value = "provider-8762", contextId = "GetClient01")

public interface GetClient01 {

/**

* GET方式请求①

*

* @param startTime

* @param endTime

* @param message

* @return

*/

@GetMapping("/get/01")

String queryDataByGetRequest(@RequestParam("startTime") Date startTime, @RequestParam("endTime") Date endTime,

@RequestParam("message") String message);

}

服务提供方:

@RestController

public class RequestProviderController {

@GetMapping("/get/01")

public String queryDataByGetRequest(@RequestParam("startTime") Date startTime, @RequestParam("endTime") Date endTime,

@RequestParam("message") String message) {

Requets01DTO requets01DTO = new Requets01DTO();

requets01DTO.setStartTime(startTime);

requets01DTO.setEndTime(endTime);

requets01DTO.setMessage(message);

return requets01DTO.toString();

}

}

请求结果截图:

GET方式请求②

Feign调用的请求改为POST方式

消费方的请求:

@Autowired

GetClient02 getClient02;

@GetMapping("/request/get/02")

public String requestGetTwo(Requets01DTO requets01DTO) {

return getClient02.queryDataByGetRequest(requets01DTO);

}

Feign接口:

package com.springcloud.service;

import com.springcloud.pojo.Requets01DTO;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.PostMapping;

@FeignClient(value = "provider-8762", contextId = "GetClient02")

public interface GetClient02 {

/**

* GET方式请求②(Feign调用的请求改为POST方式)

*

* @param requets01DTO

* @return

*/

@PostMapping("/post/02")

String queryDataByGetRequest(Requets01DTO requets0http://1DTO);

}

服务提供方:

@PostMapping("/post/02")

public String queryDataByGetRequest(@RequestBody Requets01DTO requets01DTO) {

return requets01DTO.toString();

}

请求结果截图:

GET方式请求③

组装Feign接口请求时,将body里面的参数取出来,转换为GET方式请求的参数

添加Feign请求的配置类:

package com.springcloud.config;

import com.alibaba.fastjson.JSON;

import feign.Request;

import feign.RequestInterceptor;

import feign.RequestTemplate;

import org.springframework.context.annotation.Configuration;

import org.springframework.http.HttpMethod;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

import java.lang.reflect.Field;

import java.util.*;

@Configuration

public class FeignConfiguration implements RequestInterceptor {

@Override

public void apply(RequestTemplate requestTemplate) {

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

HttpServletRequest request = attributes.getRequest();

//填充get中的body数据转化成query数据

if (requestTemplate.method().equals(HttpMethod.GET.name()) && Objects.nonNull(requestTemplate.body())) {

String json = requestTemplate.requestBody().asString();

Map mapgPKRGf = JSON.parseObject(json);

Set set = map.keySet();

Iterator it = set.iterator();

while (it.hasNext()) {

String key = it.next();

Object values = map.get(key);

if (Objects.nonNull(values)) {

// 将body的参数写入queries

requestTemplate.query(key, values.toString());

}

}

try{

Class requestClass = requestTemplate.getClass();

Field field = requestClass.getDeclaredField("body");

field.setAccessible(true);

//修改body为空。

field.set(requestTemplate, Request.Body.empty());

} catch (Exception ex) {

System.out.println(ex.fillInStackTrace());

}

}

Enumeration headerNames = request.getHeaderNames();

if (headerNames != null) {

while (headerNames.hasMoreElements()) {

String name = headerNames.nextElement();

String values = request.getHeader(name);

// 跳过 content-length

if (name.equals("content-length")){

continue;

}

requestTemplate.header(name, values);

}

} else {

System.out.println(String.format("feign interceptor error header:%s", requestTemplate));

}

}

}

添加fastJson的maven依赖:

com.alibaba

fastjson

1.2.74

消费方的请求:

@Autowired

GetClient03 getClient03;

@GetMapping("/request/get/03")

public String requestGetThree(Requets01DTO requets01DTO) {

return getClient03.queryDataByGetRequest(requets01DTO);

}

Feign接口:

package com.springcloud.service;

import com.springcloud.config.FeignConfiguration;

import com.springcloud.pojo.Requets01DTO;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(value = "provider-8762", contextId = "GetClient03", configuration = FeignConfiguration.class)

public interface GetClient03 {

/**

* GET方式请求③(组装Feign接口请求时,将body里面的参数取出来,转换为GET方式请求的参数)

*

* @param requets01DTO

* @return

*/

@GetMapping("/get/03")

String queryDataByGetRequest(Requets01DTO requets01DTO);

}

服务提供方:

@GetMapping("/get/03")

public String queryDataByGetRequest03(Requets01DTO requets01DTO) {

return requets01DTO.toString();

}

请求结果截图:

Feign调用传递的GET参数日期,要指定jsonFormat注解,body转GET参数时,日期参数会变为字符串,需要指定日期格式

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

private Date startTime;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

private Date endTime;

**结果截图:**


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:云服务器stmp协议端口25被禁用(connect timeout),使用465端口发送邮件
下一篇:使用supervisor实现后台管理进程(supervisor监控进程状态)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~