• SpringBoot系列之实现RestTemplate Get请求传javabean参数


    项目场景:

    Spring 的 RestTemplate 是一个健壮的、流行的基于 Java 的 Http客户端。

    RestTemplate实现request param参数传送,如果如下所示,直接传一个map对象,调试之后是不会接收到参数的

    Map<String,Object> param = new HashMap<String,Object>();
    param.put("since",10);
    restTemplate.getForObject("https://api.github.com/users" , UserDto.class, param);
    
    • 1
    • 2
    • 3

    所以,正确的用法是使用占位符:

    Map<String,Object> param = new HashMap<String,Object>();
    param.put("since",10);
    restTemplate.getForObject("https://api.github.com/users?since={since}" , UserDto.class, param);
    
    • 1
    • 2
    • 3

    问题描述

    但是参数一多,我们每个都写占位符,那不是很麻烦,直接丢一个javabean不可以?直接丢个javabean,或者转为map参数都不能直接传过来
    在这里插入图片描述


    原因分析:

    通过查看RestTemplate源码:org.springframework.web.client.RestTemplate#initUriTemplateHandler

    在这里插入图片描述
    DefaultUriBuilderFactory是RestTemplateURL处理的工厂类,基层接口是UriTemplateHandler,所以可以重新定义一下UriTemplateHandler


    解决方案:

    下面介绍一种方法,可以重写UriTemplateHandler 接口,在RestTemplate源码里找到这个接口是对接口参数进行处理的

    package com.example.resttemplate.configuration;
    
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.util.LinkedMultiValueMap;
    import org.springframework.util.MultiValueMap;
    import org.springframework.web.util.DefaultUriBuilderFactory;
    import org.springframework.web.util.UriComponentsBuilder;
    import org.springframework.web.util.UriTemplateHandler;
    
    import java.net.URI;
    import java.util.Map;
    
    @Slf4j
    public class RestGetUriTemplateHandler implements UriTemplateHandler {
    
        private UriTemplateHandler uriTemplateHandler = new DefaultUriBuilderFactory();
    
    
        @Override
        public URI expand(String uriTemplate, Map<String, ?> uriVariables) {
        	// 使用UriComponentsBuilder 构建请求的链接,也是拼参数的方法
            UriComponentsBuilder builder = UriComponentsBuilder
                    .fromHttpUrl(uriTemplate);
            for (Map.Entry<String, ?> entry : uriVariables.entrySet()) {
                builder.queryParam(entry.getKey(), entry.getValue());
            }
            String uriString = builder.toUriString();
            log.info("uriString:[{}]" , uriString);
            return uriTemplateHandler.expand(uriString , uriVariables);
        }
    
        @Override
        public URI expand(String uriTemplate, Object... uriVariables) {
            return uriTemplateHandler.expand(uriTemplate, uriVariables);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    使用Hutool的工具类,转换bean类为map对象,import cn.hutool.core.bean.BeanUtil;

    restTemplate.setUriTemplateHandler(new RestGetUriTemplateHandler());
    Map<String,Object> param = BeanUtil.beanToMap(queryDto);
    restTemplate.getForObject("https://api.github.com/users/mojombo", UserDto.class , param);
    
    • 1
    • 2
    • 3

    也可以借助apache-commont的工具类进行转换,import org.apache.commons.beanutils.BeanUtilsBean;

    Map<String, String> paramMap = BeanUtilsBean.getInstance().describe(bean);
    
    • 1

    运行之后,可以发现参数带上去了,之后调第三方接口,直接传个javabean就可以,方便很多,也可以对javabean转map的操作进行封装,之后直接调用
    在这里插入图片描述

  • 相关阅读:
    聚焦云原生安全|如何为5G边缘云和工业互联网应用筑牢安全防线
    Discuz开发之HTML转Discuz代码(bbcode)函数html2bbcode()
    Vue.js核心技术解析与uni-app跨平台实战开发学习笔记 第7章 Vue.js高级进阶 7.2 vue-cli目录结构
    CSS 快速实现水平垂直居中
    达梦安装目录各个文件夹解析
    kafka 使用thrift序列化对象
    [C/C++]_[中级]_[static_cast的详细解析]
    2019年Java面试题汇总
    [Pytorch] 保存模型与加载模型
    LightDB版本发布 13.8-23.3
  • 原文地址:https://blog.csdn.net/u014427391/article/details/126002964