使用FeignClient调用POST表单Body内没有参数问题

目录
  • FeignClient调用POST表单Body没有参数
  • FeignClient参数问题
    • 使用Get方式调用服务提供者
    • 使用Post方式调用服务提供者
    • 三种情况(无参、单参、多参)
    • @RequestBody和@RequestParam的区别

FeignClient调用POST表单Body没有参数

1、问题:在使用FeignClient调用第三方接口,对方是普通POST接口,但是调用返回400,后发现请求体没有携带需要的参数。

2、查找资料发现,FeignClient默认POST请求发送参数为JSON格式,如需要使用表单形式,必须自定义设置。

3、附代码

import com.lenovo.mt.config.FormFeignConfiguration;
import com.lenovo.mt.remote.eservice.vo.EServiceToken;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
 * @Description
 * @Author zhaoke
 * @Date 2019/12/16 10:42
 **/
@FeignClient(name = "***", url = "${***}",configuration = FormFeignConfiguration.class, fallback = TokenFail.class)
public interface ITokenRemote {
    @PostMapping(value = "***",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    EServiceToken getToken(@RequestParam("client_id")String clientId,@RequestParam("client_secret")String clientSecret,@RequestParam("grant_type")String grantType);
}

其中主要设置在FormFeignConfiguration这个类中

import feign.codec.Encoder;
import feign.form.FormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
 * @Description
 * @Author zhaoke
 * @Date 2019/12/17 13:05
 **/
@Configuration
public class FormFeignConfiguration {
    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;
    @Bean
    @Primary
    @Scope(SCOPE_PROTOTYPE)
    Encoder feignFormEncoder() {
        return new FormEncoder(new SpringEncoder(this.messageConverters));
    }
}

FeignClient参数问题

使用Get方式调用服务提供者

服务消费者,需要在所有参数前加上@RequestParam注解

服务消费者,指明是Get方式,如果不指明那么在满足条件1 的情况下默认使用get方式

1和2都满足才使用Get方式

使用Post方式调用服务提供者

在所有参数前面加上@RequestParam注解,并且指明使用的Post方式

在参数前面加上@RequestBody注解(有且只有一个@ RequestBody)或者什么也没有(有多个参数其余参数前面都要加上@RequestParam)

1和2满足一个就使用Post方式

三种情况(无参、单参、多参)

无参Get

如果发送无参的Get请求,可以不指定method,默认就是Get请求

无参Post

指定method是Post方式,否则就是Get请求

单参Get

指定该参数是@RequestParam修饰,这时候method默认是Get,也可以自己指定Get方式

单参Post

该参数前面加@RequestParam修饰,并且使用Post方式

或者

使用@RequestBody修饰该参数,或者没使用@RequestParam和@RequestBody修饰该参数,再这个使用不论指定Post还是Get都会使用Post进行请求

注意:

在使用fegin消费服务的时候,如果参数前面什么也没写,默认是@RequestBody来修饰的

@RequestBody修饰的参数需要以Post方式来传递

在服务提供者的Controller中:

1.如果要接收@RequestBody指明的参数,那么对应方法的对应参数前一定要有@RequestBody;(如果没有的话,收到的参数值就为null;如果写成@RequestParam的话,那么feign调用会失败)

2.如果接收@ RequestParam指明的参数,那么可以写@ RequestParam也可以不写,如果参数名称一致不用,不一致需要写

多参Get

需要在所有参数前面添加@ RequestParam注解,这时候可以加Get也可以不加Get

多参Post

服务消费者中,最多只能有一个参数是@RequestBody指明的,其余的参数必须使用@RequestParam指明

也可以在第一个参数前面什么也不写(默认使用@RequestBody修饰)其余的参数都需要加@RequestParam

如果所有参数都是以@RequestParam修饰,并且使用的是Post方式,那么也是以Post方式来请求

在服务提供者的Controller中:

1.如果服务消费者传过来参数时,全都用的是@RequestParam的话,那么服务提供者的Controller中对应参数前可以写@RequestParam,也可以不写(当两边参数名字一致时,可以省略不写)

2. 如果服务消费者传过来参数时,有@RequestBody的话,那么服务提供者的Controller中对应参数前必须要写@RequestBody(如果是多参数的话,其余参数前视情况可以写@RequestParam,也可以不写)

@RequestBody和@RequestParam的区别

@RequestParam用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,在Http中如果不指定Content-Type则默认使用application/x-www-form-urlencoded类型

@ RequestBody,处理HttpEntity传递过来的数据,用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据

Get请求没有HttpEntity所以不用@ RequestBody

POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上

总结:Get不能使用表单,只能在url中传参,传参方式只有这一种。 Post可以使用表单,也可以在url中传参。使用表单时有几种数据类型(表现为数据的存储位置不同):

1、x-www-form-urlencoded 参数存储在query中 用@RequestParam接收。

2、formdata 参数存储在body中,用@RequestBody接收,文件类型用@RequestPart接收。

3、raw(josn,xml) 参数存储在body中 用@RequetBody接收。

总结一下: 凡是放在body中的都可以用@RequestBody接收,文件类型的数据可以用@RequestPart接收。 凡是放在query中的都可以用@RequestParam接收,包括Get方式提交和Post(x-www-form-urlencoded)方式提交的

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

(0)

相关推荐

  • 解决FeignClient发送post请求异常的问题

    FeignClient发送post请求异常 这个问题其实很基础.但是却难倒了我.记录一下 在发送post请求的时候要指定消息格式 正确的写法是这样 @PostMapping(value = "/test/post", consumes = "application/json") String test(@RequestBody String name); 不生效的写法 @PostMapping(value = "/test/post", prod

  • feign post参数对象不加@RequestBody的使用说明

    目录 feign post参数对象不加@RequestBody 使用@RequestParam.@RequestBody 的正确姿势 背景 详细情况 小结一下 feign post参数对象不加@RequestBody 最近在做小程序调支付服务接口的一个功能,这个feign接口传参真的太费事. 代码我就改造了下,不直接上真实代码. 比如小程序调支付服务的订单查询接口,支付服务那边的controller的订单查询方法是: @ResponseBody @RequestMapping(value = "

  • SpringCloud Feign参数问题及解决方法

    这篇文章主要介绍了SpringCloud Feign参数问题及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天遇到使用Feign调用微服务,传递参数时遇到几个问题 1.无参数 以GET方式请求 服务提供者 @RequestMapping("/hello") public String Hello(){ return "hello,provider"; } 服务消费者 @GetMapping("

  • 关于feign调用的参数传递问题(@RequestBody和@RequestParam)

    目录 feign调用的参数传递问题 错误写法 正确写法 body的正确形式 feign传参总结 返回实体对象服务提供者 restful传参服务提供者 传实体对象服务提供者 feign调用的参数传递问题 SpringCloud Feign报错: java.lang.IllegalStateException: Method has too many Body parameters 上边的报错提示为body太多了,feign调用的方法里只能有一个body但是requestparam可以多个 错误写法

  • 使用FeignClient调用POST表单Body内没有参数问题

    目录 FeignClient调用POST表单Body没有参数 FeignClient参数问题 使用Get方式调用服务提供者 使用Post方式调用服务提供者 三种情况(无参.单参.多参) @RequestBody和@RequestParam的区别 FeignClient调用POST表单Body没有参数 1.问题:在使用FeignClient调用第三方接口,对方是普通POST接口,但是调用返回400,后发现请求体没有携带需要的参数. 2.查找资料发现,FeignClient默认POST请求发送参数为

  • bootstrap为水平排列的表单和内联表单设置可选的图标

    说明 为水平排列的表单和内联表单设置可选的图标. 示例 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" co

  • js的form表单提交url传参数(包含+等特殊字符)的两种解决方法

    方法一:(伪装form表单提交) linkredwin = function(A,B,C,D,E,F,G){ var formredwin = document.createElement("form"); formredwin.method = 'POST'; document.body.appendChild(formredwin); formredwin.action = "http://www.A.com/A.wiki?A=" +encodeURI(A) +

  • 在Python的Flask中使用WTForms表单框架的基础教程

    下载和安装 安装 WTForms 最简单的方式是使用 easy_install 和 pip: easy_install WTForms # or pip install WTForms 你可以从 PyPI 手动 下载 WTForms 然后运行 python setup.py install . 如果你是那种喜欢这一切风险的人, 就运行来自 Git 的最新版本, 你能够获取最新变更集的 打包版本, 或者前往 项目主页 克隆代码仓库. 主要概念 Forms 类是 WTForms 的核心容器. 表单(

  • Mvc提交表单的四种方法全程详解

    一,MVC HtmlHelper方法 1. Html.BeginForm(actionName,controllerName,method,htmlAttributes){} 2. BeginRouteForm 方法 (HtmlHelper, String, Object, FormMethod) 二,传统Form表单Aciton属性提交 三,Jquery+Ajax 提交表单 四,MVC Controller控制器和表单参数传递 MVC HtmlHelper方法 一,Html.BeginForm

  • vue2实现封装动态表单组件

    目录 封装组件注意点 动态表单动态控制的是什么? 动态表单封装 风格一 风格二 (推荐优先采用此风格) 封装组件注意点 不要为了封装而封装 只封装不变的部分,将变化的部分通过slot或其他方式,暴露出去,交给调用者实现 为了提供封装组件的复用率,优先封装为UI组件,而不是封装为业务组件(即:封装组件内部使用到的数据,都通过prop获取,而不是直接通过ajax请求或vuex中获取) 动态表单动态控制的是什么? 已知的需要动态控制的场景: 在A界面显示:A, B, C三个表单项,B界面显示:A,B,

  • Element Plus组件Form表单Table表格二次封装的完整过程

    目录 前言 Form表单的封装 简述 正常的使用 开始封装① 开始封装② 开始封装③ 开始封装④ 完整封装代码⑤ 配置项类型文件 配置项文件 form表单组件文件 page-search组件文件 role页面组件文件 结语 Table表格的封装 简述 正常使用 开始封装① 开始封装② 开始封装③ 完整封装代码④ 配置项类型文件 配置项文件 table表单组件文件 page-table组件文件 user页面组件文件 结语 前言 直至今天,看了一下别人写的代码,才发现以前自己写的代码太垃圾,所以在这

  • 详解Angular Reactive Form 表单验证

    本文我们将介绍 Reactive Form 表单验证的相关知识,具体内容如下: 使用内建的验证规则 动态调整验证规则 自定义验证器 自定义验证器 (支持参数) 跨字段验证 基础知识 内建验证规则 Angular 提供了一些内建的 validators,我们可以在 Template-Driven 或 Reactive 表单中使用它们. 目前 Angular 支持的内建 validators 如下: required - 设置表单控件值是非空的. email - 设置表单控件值的格式是 email.

  • javascript表单控件实例讲解

    本文实例为大家分享js表单控件多个实例讲解,供大家参考,具体内容如下 实例一:遍历表单的所有控件 <script type="text/javascript"> //遍历表单的所有控件 function getValues(){ var f = document.forms[0]; //获取表单DOM var elements = f.elements; //获取所有的控件数组 var str = ''; //拼接字符串 //循环遍历 for(var i=0; i<e

  • 如何修改被表单引用的ASP页面?

    formhandler.asp<html><body><%Dim RequestMethod RequestMethod = Request.ServerVariables("REQUEST_ METHOD") ' 获取REQUEST_METHOD的数值,并把它存入本地的变量中.当Web页面被表单标记的Action参数调用时,REQUESTMETHOD的数值为Post.其他时候, 用户直接向浏览器中键入地址,刷新页面,或单击页面的一个链接而调用页面,REQ

随机推荐