首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot系列之实现RestTemplate Get请求传javabean参数

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

作者头像
SmileNicky
发布2022-07-28 08:46:27
1.7K0
发布2022-07-28 08:46:27
举报
文章被收录于专栏:Nicky's blogNicky's blog

项目场景:

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);

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

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

问题描述

但是参数一多,我们每个都写占位符,那不是很麻烦,直接丢一个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);
    }
}

使用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);

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

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

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

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-07-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目场景:
  • 问题描述
  • 原因分析:
  • 解决方案:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档