IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> FeignClient调用接口接收不到参数问题 -> 正文阅读

[Java知识库]FeignClient调用接口接收不到参数问题

1. 问题描述

问题就是通过FeignClient调用某个接口的时候,请求参数明明有值,服务端拿到的请求对象却为null。

2. 问题分析

FeignClient接收不到参数可能会存在以下原因,
1.客户端没有传值。
2.客户端与服务端参数类型不一致导致服务端接收不到。
3.请求对象中含有以is开头的参数,FeignClient框架序列化会过滤掉。
4.FeignClient框架问题,考虑其他框架如httpclient,hutool的httpUtil等。

3. 测试验证

3.1 环境依赖

spring-boot是2.3.2.RELEASE版本,openfeign是2.2.5.RELEASE。


    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>

3.2 代码实现

FeignClientReqDTO

package com.jerry.market.entity;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * 客户端请求对象
 *
 * @author zrj
 * @since 2022/4/24
 **/
@Data
public class FeignClientReqDTO implements Serializable {
    private static final long serialVersionUID = 4804236268827809329L;
    private String tenantId;
    private String bizId;

    //布尔类型,不以is开头,可以
    private boolean mark;
    //布尔类型,以is开头,客户端包装类型,服务端包装,可以
    private Boolean isFilterMark;
    //布尔类型,以is开头,客户端基本类型,服务端包装,但是通过JsonProperty注解处理,可以
    @JsonProperty("isFilterMarkJson")
    private boolean isFilterMarkJson;
    //布尔类型,以is开头,客户端基本类型,服务端包装,不可以
    private boolean isFilterMarkSimple;

    //String类型,不以is开头,客户端包装类型,服务端包装,可以
    private String start;
    //String类型,以is开头,客户端包装类型,服务端包装,可以
    private String isDeleted;
    //String类型,以is开头,客户端包装类型,服务端包装,但是通过JsonProperty注解处理,可以
    @JsonProperty("isDeletedJson")
    private String isDeletedJson;

    //int类型,不以is开头,客户端包装类型,服务端包装,可以
    private Integer tools;
    //int类型,不以is开头,客户端基本类型,服务端包装,可以
    private int toolCount;
    //int类型,以is开头,客户端包装类型,服务端包装,可以
    private int isToolNumber;
    //int类型,以is开头,客户端基本类型,服务端包装,但是通过JsonProperty注解处理,可以
    @JsonProperty("isToolNumberJson")
    private int isToolNumberJson;

}

FeignClientServerDTO

package com.jerry.market.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * 服务端请求对象
 *
 * @author zrj
 * @since 2022/4/24
 **/
@Data
public class FeignClientServerDTO implements Serializable {
    private static final long serialVersionUID = 4804236268827809329L;
    private String tenantId;
    private String bizId;

    //布尔类型
    private Boolean mark;
    private Boolean isFilterMark;
    private Boolean isFilterMarkJson;
    private Boolean isFilterMarkSimple;

    //String类型
    private String start;
    private String isDeleted;
    private String isDeletedJson;

    //int类型
    private Integer tools;
    private Integer toolCount;
    private Integer isToolNumber;
    private Integer isToolNumberJson;
}

FeignController

package com.jerry.market.controller;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jerry.market.entity.*;
import com.jerry.market.integration.FeignClientService;
import com.jerry.market.integration.TemplateClientService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * Feign控制器
 *
 * @author makejava
 * @since 2022-04-22 15:31:00
 */
@RestController
@RequestMapping("/feign")
@Api(tags = "FeignController", description = "Feign控制器")
public class FeignController {

    @Resource
    private FeignClientService feignClientService;

    /**
     * FeignClient服务端
     * 1.客户端请求 isFilterUsemark Boolean,服务端请求 isFilterUsemark boolean,通过Feign可以接收到值
     * 2.客户端请求 isFilterUsemark Boolean,服务端请求 isFilterUsemark Boolean,通过Feign可以接收到值
     * 3.客户端请求 isFilterUsemark boolean,服务端请求 isFilterUsemark boolean,通过Feign可以接收到值
     * 4.客户端请求 isFilterUsemark boolean,服务端请求 isFilterUsemark Boolean,通过Feign不可以接收到值
     * <p>
     * 通过Feign调用接口,请求参数接收不到值问题
     * 1.使用Feign与hutool的httpUtil调用,且请求对象含有以is开头的命名的布尔类型参数,且请求基本类型,服务端包装类型,接收不到值。
     * 2.通过集合不存在这种问题,即使请求参数中含有以is开头的命名的参数。
     * 3.通过给以is开头的参数添加序列化注解@JsonProperty("isDeletedJson")
     * 4.其他类型即使含有以is开头的参数也不会受影响
     */
    @PostMapping("/getFeignServer")
    @ApiOperation(value = "FeignClient服务端")
    public Response getFeignServer(@RequestBody FeignClientServerDTO feignClientServerDTO) {
        System.out.println("【FeignClient服务端】请求参数:" + feignClientServerDTO);
        return Response.success(feignClientServerDTO);
    }

    /**
     * FeignClient根据请求对象查询客户端
     */
    @GetMapping("/getFeignClientByObject")
    @ApiOperation(value = "FeignClient根据请求对象查询客户端")
    public Response getFeignClientByObject() {
        //构建请求对象
        FeignClientReqDTO dto = buildFeignClientReqDTO();

        System.out.println("【FeignClientObject客户端】请求参数:" + dto);
        JSONObject ret = feignClientService.getFeignClientByObject(dto);
        System.out.println("【FeignClientObject客户端】响应参数:" + ret);

        return Response.success(ret);
    }

    /**
     * FeignClient根据请求集合查询客户端
     */
    @GetMapping("/getFeignClientByMap")
    @ApiOperation(value = "FeignClient根据请求集合查询客户端")
    public Response getFeignClientByMap() {
        //构建请求对象
        Map<String, Object> map = buildFeignClientReqMap();

        System.out.println("【FeignClientMap客户端】请求参数:" + map);
        JSONObject ret = feignClientService.getFeignClientByMap(map);
        System.out.println("【FeignClientMap客户端】响应参数:" + ret);

        return Response.success(ret);
    }


    /**
     * HttpClient根据请求对象查询客户端
     */
    @GetMapping("/getHttpClientByObject")
    @ApiOperation("查询模板通过HttpClient")
    public Response<JSONObject> getHttpClientByObject() {
        //创建头信息
        HttpRequest post = HttpUtil.createPost("http://localhost:8090/feign/getFeignServer");

        //构建请求对象
        FeignClientReqDTO dto = buildFeignClientReqDTO();
        post.body(JSON.toJSONString(dto));

        //集合参数,isFilterUsemark可以接收参数
        //Map<String, Object> map = buildFeignClientReqMap();
        //post.body(JSON.toJSONString(map));

        System.out.println("【查询模板通过HttpClient】请求参数:" + dto);
        HttpResponse response = post.execute();
        System.out.println("【查询模板通过HttpClient】响应参数:" + response.body());

        return Response.success(JSON.parseObject(response.body()));
    }

    /**
     * 构建请求对象
     *
     * @return FeignClientReqDTO
     */
    private FeignClientReqDTO buildFeignClientReqDTO() {
        //构建请求对象
        FeignClientReqDTO dto = new FeignClientReqDTO();
        dto.setTenantId("123456789");
        dto.setBizId("helloWorld");

        //布尔类型
        dto.setIsFilterMark(false);
        dto.setFilterMarkJson(false);
        dto.setFilterMarkSimple(false);
        dto.setMark(false);

        //String类型
        dto.setStart("1");
        dto.setIsDeleted("2");
        dto.setIsDeletedJson("3");

        //整数类型
        dto.setTools(4);
        dto.setToolCount(5);
        dto.setIsToolNumber(6);
        dto.setIsToolNumberJson(7);

        return dto;
    }

    /**
     * 构建请求Map
     *
     * @return Map
     */
    private Map<String, Object> buildFeignClientReqMap() {
        //构建请求对象
        Map<String, Object> map = new HashMap<>(9);
        map.put("tenantId", "123456789");
        map.put("bizId", "helloWorld");

        //布尔类型
        map.put("isFilterMark", false);
        map.put("isFilterMarkJson", false);
        map.put("isFilterMarkSimple", false);
        map.put("mark", false);

        //String类型
        map.put("start", "1");
        map.put("isDeleted", "2");
        map.put("isDeletedJson", "3");

        //整数类型
        map.put("tools", "4");
        map.put("toolCount", "5");
        map.put("isToolNumber", "6");
        map.put("isToolNumberJson", "7");
        return map;
    }
}



FeignClientService

package com.jerry.market.integration;

import com.alibaba.fastjson.JSONObject;
import com.jerry.market.entity.FeignClientReqDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Map;

/**
 * FeignClientService
 *
 * @author zrj
 * @since 2022/4/25
 **/
@Component
@FeignClient(url = "http://localhost:8090/feign", name = "FeignClientService")
public interface FeignClientService {

    /**
     * 通过对象查询模板
     *
     * @param dto FeignClientReqDTO
     * @return JSONObject
     */
    @PostMapping(value = "/getFeignServer")
    JSONObject getFeignClientByObject(@RequestBody FeignClientReqDTO dto);

    /**
     * 通过集合查询模板
     *
     * @param map
     * @return JSONObject
     */
    @PostMapping(value = "/getFeignServer")
    JSONObject getFeignClientByMap(@RequestBody Map<String, Object> map);
    
}

4. 结论总结

通过Feign调用接口,请求参数接收不到值问题
1.使用Feign与hutool的httpUtil调用,且请求对象含有以is开头的命名的布尔类型参数,且请求基本类型,服务端包装类型,接收不到值。
2.客户端通过集合作为请求对象不存在这种问题,即使请求参数中含有以is开头的命名的参数。
3.客户端通过给以is开头的参数添加序列化注解@JsonProperty(“isDeletedJson”)
4.客户端对于除了布尔类型以外其他类型即使含有以is开头的参数也不会受影响

5. 阿里开发手册

阿里开发手册-泰山版,命名规范第8条。

8.【强制】POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。
说明:在本文 MySQL 规约中的建表约定第一条,表达是与否的值采用 is_xxx 的命名方式,所以,需要在设置从 is_xxx 到 xxx 的映射关系。

反例:定义为基本数据类型 Boolean isDeleted 的属性,它的方法也是 isDeleted(),框架在反向解析的时候,“误以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:28:38  更:2022-04-26 11:30:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:16:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码