返回顶部
首页 > 资讯 > 后端开发 > Python >feign调用中文参数被encode编译的问题
  • 781
分享到

feign调用中文参数被encode编译的问题

2024-04-02 19:04:59 781人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录Feign调用中文参数被encode编译原因记录今天遇到的feign多参数问题1.Post方式2.Get方式Feign调用中文参数被encode编译 原因 在实现一个feign调

Feign调用中文参数被encode编译

原因

在实现一个feign调用时使用了Post请求,并且拼接url参数,name传值为中文时被encode转译,且最终接取数据之前未被decode转译回,问题探索:

feign:

@FeignClient(name = "service-test")
public interface TestServiceapi {
    @PostMapping("/test/abc")
    public String getTestNo(@RequestParam("code") String code, @RequestParam("name") String name);
}

controller:

@RequestMapping("/test")
public interface TestController {
    @Autowired
    private TestService testService;
    @PostMapping("/abc")
    public String getTestNo(@RequestParam("code") String code, @RequestParam("name") String name) {
        return testService.query(code, name); 
    }    
}

在controller中接到的中文参数被URIEncode转译了

测试 被转译成:%E6%B5%8B%E8%AF%95

找到feign的入口类ReflectiveFeign中拼装RequestTemplate的方法:

    @Override
    public RequestTemplate create(Object[] argv) {
      RequestTemplate mutable = new RequestTemplate(metadata.template());
      if (metadata.urlIndex() != null) {
        int urlIndex = metadata.urlIndex();
        checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
        mutable.insert(0, String.valueOf(argv[urlIndex]));
      }
      Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
      for (Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
        int i = entry.geTKEy();
        Object value = argv[entry.getKey()];
        if (value != null) { // Null values are skipped.
          if (indexToExpander.containsKey(i)) {
            value = expandElements(indexToExpander.get(i), value);
          }
          for (String name : entry.getValue()) {
            varBuilder.put(name, value);
          }
        }
      }
      // 组装template的方法
      RequestTemplate template = resolve(argv, mutable, varBuilder);
      if (metadata.queryMapIndex() != null) {
        // add query map parameters after initial resolve so that they take
        // precedence over any predefined values
        template = addQueryMapQueryParameters(argv, template);
      }
      if (metadata.headerMapIndex() != null) {
        template = addHeaderMapHeaders(argv, template);
      }
      return template;
    }

在RequestTemplate类中如果是拼接在url后的param那么会被使用encodeValueIfNotEncoded都encode转译,但是不会走decode的方法 

 
  RequestTemplate resolve(Map<String, ?> unencoded, Map<String, Boolean> alreadyEncoded) {
    replaceQueryValues(unencoded, alreadyEncoded);
    Map<String, String> encoded = new LinkedHashMap<String, String>();
    for (Entry<String, ?> entry : unencoded.entrySet()) {
      final String key = entry.getKey();
      final Object objectValue = entry.getValue();
      String encodedValue = encodeValueIfNotEncoded(key, objectValue, alreadyEncoded);
      encoded.put(key, encodedValue);
    }
    String resolvedUrl = expand(url.toString(), encoded).replace("+", "%20");
    if (decodeSlash) {
      resolvedUrl = resolvedUrl.replace("%2F", "/");
    }
    url = new StringBuilder(resolvedUrl);
    Map<String, Collection<String>> resolvedHeaders = new LinkedHashMap<String, Collection<String>>();
    for (String field : headers.keySet()) {
      Collection<String> resolvedValues = new ArrayList<String>();
      for (String value : valuesOrEmpty(headers, field)) {
        String resolved = expand(value, unencoded);
        resolvedValues.add(resolved);
      }
      resolvedHeaders.put(field, resolvedValues);
    }
    headers.clear();
    headers.putAll(resolvedHeaders);
    if (bodyTemplate != null) {
      body(urlDecode(expand(bodyTemplate, encoded)));
    }
    return this;
  }

如果传入的值在requestBody中,则不会被encode转译

    @Override
    public void encode(Object requestBody, Type bodyType, RequestTemplate request)
            throws EncodeException {
        // template.body(conversionService.convert(object, String.class));
        if (requestBody != null) {
            Class<?> requestType = requestBody.getClass();
            Collection<String> contentTypes = request.headers().get("Content-Type");
            MediaType requestContentType = null;
            if (contentTypes != null && !contentTypes.isEmpty()) {
                String type = contentTypes.iterator().next();
                requestContentType = MediaType.valueOf(type);
            }
            for (HttpMessageConverter<?> messageConverter : this.messageConverters
                    .getObject().getConverters()) {
                if (messageConverter.canWrite(requestType, requestContentType)) {
                    if (log.isDebugEnabled()) {
                        if (requestContentType != null) {
                            log.debug("Writing [" + requestBody + "] as \""
                                    + requestContentType + "\" using ["
                                    + messageConverter + "]");
                        }
                        else {
                            log.debug("Writing [" + requestBody + "] using ["
                                    + messageConverter + "]");
                        }
                    }
                    FeignOutputMessage outputMessage = new FeignOutputMessage(request);
                    try {
                        @SuppressWarnings("unchecked")
                        HttpMessageConverter<Object> copy = (HttpMessageConverter<Object>) messageConverter;
                        copy.write(requestBody, requestContentType, outputMessage);
                    }
                    catch (IOException ex) {
                        throw new EncodeException("Error converting request body", ex);
                    }
                    // clear headers
                    request.headers(null);
                    // converters can modify headers, so update the request
                    // with the modified headers
                    request.headers(getHeaders(outputMessage.getHeaders()));
                    // do not use charset for binary data
                    if (messageConverter instanceof ByteArrayHttpMessageConverter) {
                        request.body(outputMessage.getOutputStream().toByteArray(), null);
                    } else {
                        request.body(outputMessage.getOutputStream().toByteArray(), Charset.forName("UTF-8"));
                    }
                    return;
                }
            }
            String message = "Could not write request: no suitable HttpMessageConverter "
                    + "found for request type [" + requestType.getName() + "]";
            if (requestContentType != null) {
                message += " and content type [" + requestContentType + "]";
            }
            throw new EncodeException(message);
        }
    }

综合上述的调试,如果在Post中拼接参数那么会被encode转译,且不会被decode转译,如果使用body传参,那么不会出现转译问题,如果必须使用拼接传参,那么可以使用方法

1. @RequestLine的注解自定义参数的格式,具体参考该注解的使用方式。

2.在Feign的RequestInterceptor将传递的值decode的扩展方法。

记录今天遇到的feign多参数问题

1.Post方式

错误写法示例如下:

public int save(@RequestBody final User u, @RequestBody final School s);

错误原因:

fegin中可以有多个@RequestParam,但只能有不超过一个@RequestBody,@RequestBody用来修饰对象,但是既有@RequestBody也有@RequestParam,

那么参数就要放在请求的Url中,@RequestBody修饰的就要放在提交对象中。

注意!!! 用来处理@RequestBody Content-Type 为 application/JSON,application/xml编码的内容

正确写法示例如下:

public int save(@RequestBody final Person p,@RequestParam("userId") String userId,@RequestParam("userTel") String userTel);

2.Get方式

错误写法示例如下:

@RequestMapping(value="/test", method=RequestMethod.GET)  
Model test(final String name,  final int age); 

错误原因:

异常原因:当使用Feign时,如果发送的是get请求,那么需要在请求参数前加上@RequestParam注解修饰,Controller里面可以不加该注解修饰,@RequestParam可以修饰多个,@RequestParam是用来修饰参数,不能用来修饰整个对象。

注意:@RequestParam Content-Type 为 application/x-www-fORM-urlencoded 而这种是默认的

正确写法示例如下:

@GetMapping("/getSchoolDetail")
    public ResultMap getSchoolDetail(@RequestParam("kSchoolId") LongkSchoolId,
     @RequestParam("kSchoolYearId") Long kSchoolYearId);

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: feign调用中文参数被encode编译的问题

本文链接: https://lsjlt.com/news/141486.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • feign调用中文参数被encode编译的问题
    目录Feign调用中文参数被encode编译原因记录今天遇到的feign多参数问题1.Post方式2.Get方式Feign调用中文参数被encode编译 原因 在实现一个feign调...
    99+
    2024-04-02
  • 如何解决feign调用中文参数被encode编译的问题
    这篇文章主要介绍如何解决feign调用中文参数被encode编译的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Feign调用中文参数被encode编译原因在实现一个feign调用时使用了Post请求,并且拼接u...
    99+
    2023-06-29
  • 解决Feign调用的GET参数传递的问题
    目录需求思考GET方式请求①GET方式请求②GET方式请求③需求 ​ 在消费方服务通过GET方式,访问服务提供方的接口,需要传递多参数,拆分成多个参数的方式访问,不太适合用在该场景,...
    99+
    2024-04-02
  • 关于feign调用的参数传递问题(@RequestBody和@RequestParam)
    目录feign调用的参数传递问题错误写法正确写法body的正确形式feign传参总结返回实体对象 服务提供者 restful传参 服务提供者传实体对象 服务提供者feign...
    99+
    2024-04-02
  • 如何解决Feign调用的GET参数传递的问题
    这篇文章主要介绍了如何解决Feign调用的GET参数传递的问题的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何解决Feign调用的GET参数传递的问题文章都会有所收获,下面我们一起来看看吧。需求在消费方服务通...
    99+
    2023-06-29
  • 解决SpringCloud Feign传对象参数调用失败的问题
    SpringCloud Feign传对象参数调用失败 不支持GET请求方式 使用Apache HttpClient替换Feign原生httpclient @...
    99+
    2024-04-02
  • SpringCloud中的Feign远程调用接口传参失败问题
    目录Feign远程调用接口传参失败这是调用者这是feign的client这是被调者Feign远程调用的注意点定义的做远程调用的api接口service微服务中的Controller的...
    99+
    2024-04-02
  • springcloud使用feign调用服务时参数内容过大问题
    目录feign调用服务时参数内容过大场景解决方法feign消费时,如果传入参数过长导致feign.FeignException: status 400 reading错误解决办法fe...
    99+
    2024-04-02
  • 使用feign传递参数类型为MultipartFile的问题
    目录feign传递参数类型为MultipartFile引入maven依赖加入配置类在feign客户端进行配置feign传参MultipartFile问题解决首先引入依赖新建feign...
    99+
    2024-04-02
  • informix的esql编译参数避免//注释引起的SQL中断问题
    在EXEC SQL中,如果SQL语句出现了“//”符号,那么会导致后面一直到“;”结尾的SQL语句都被忽略,而不止当前行。这样往往会出乎程序员的意料。 例如以下例子程序t1.ec。 ...
    99+
    2024-04-02
  • 如何解决css3中calc在less编译时被计算的问题
    这篇文章将为大家详细讲解有关如何解决css3中calc在less编译时被计算的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。对于前端er来说,Less或Sass已经是...
    99+
    2024-04-02
  • 如何解决使用feign传递参数类型为MultipartFile的问题
    这篇文章主要介绍如何解决使用feign传递参数类型为MultipartFile的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!feign传递参数类型为MultipartFilefeign默认是不支持多媒体文件类型...
    99+
    2023-06-29
  • Go 中调用的函数如何访问调用函数的参数?
    Go 中调用的函数可以通过函数参数来获取调用函数的参数。在 Go 中,参数可以通过传值或传引用的方式传递给函数,函数可以通过参数来获取调用者传递的值或指针。如果参数是值类型,函数内部的...
    99+
    2024-02-09
  • 浅析C++调用Java的Jar包(带参数)问题
    JarAppCall.h #include <atlstr.h> class CJarAppCall { public: CJarAppCal...
    99+
    2024-04-02
  • 关于使用rust调用c++静态库并编译nodejs包的问题
    目录一、创建项目二、Cargo.toml三、package.json四、代码分析在项目上经常要用到身份证阅读器、护照阅读仪、指纹仪等各种品牌硬件,假如每套系统的都做集成开发那代码的维...
    99+
    2022-11-13
    rust调用c++静态库 c++编译nodejs包
  • 解决pyqt中ui编译成窗体.py中文乱码的问题
    我在Eric工具下编译的 解决办法: 1、打开 C:Python27Libsite-packageseric4i18n,将中文资源包的名称"GB2312."去掉,变成eric4_zh_CN.qm; 2、 启...
    99+
    2022-06-04
    窗体 乱码 中文
  • 如何调试 C++ 函数中默认参数和可变参数相关的问题
    调试 c++++ 函数中默认参数和可变参数的问题可以通过以下方法:使用调试器查看函数中实际使用的参数值。在代码中添加日志语句,记录传给函数的实际参数。使用调试器查看可变参数列表的内容。在...
    99+
    2024-04-22
    调试 c++ 函数参数
  • vue项目中created()被调用多次的问题怎么解决
    本文小编为大家详细介绍“vue项目中created()被调用多次的问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue项目中created()被调用多次的问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
    99+
    2023-07-05
  • shift妙用之解决shell编程中的入参问题
    我说过了,shell是我的常规武器,目前虽然还不纯熟,但是我爱shell这门语言,在Linux下面混,总要写脚本。程序员是有基因,对编程语言是有偏好的,你让我写C代码,我会觉得很爽,会有困难,会有痛苦的摸索...
    99+
    2022-06-04
    妙用 shift shell
  • URL中文参数乱码问题的PHP解决方案
    URL参数乱码问题一直是开发者面临的一个棘手问题,尤其是在处理中文参数时更为显著。在PHP编程中,如果URL中的中文参数出现乱码,不仅会影响用户体验,还可能导致程序出现异常行为。本文将...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作