Java便携开发,调用第三方接口工具封装,可直接复制粘贴使用

2023-10-28

引语

在Java开发中,我们需要应用第三方服务,spring-boot框架其实已经封装了一个调用工具,但是调用十分生硬,让代码灵活起来,以下分享是一个工具类,针对调用第三方服务,这样可以免去你再去写 feign,open-feign 或者其他 HttpConnection 之类的原始代码,因为看似很简化,实际emmm,不评论。

先分享工具类,感兴趣的大佬可以直接复制粘贴到你的工具类中

package com.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Configuration
public class RestTemplateUtils {

    private static final int DEFAULT_TIMEOUT = 5000;

    private static RestTemplate instanceRestTemplate;

    @Bean("restTemplate")
    public RestTemplate restTemplate() {
        instanceRestTemplate = getInstance();
        return instanceRestTemplate;
    }

    public static RestTemplate getInstance() {
        return getRestTemplateByTimeout(DEFAULT_TIMEOUT);
    }

    public static RestTemplate getRestTemplateByTimeout(int timeout) {
        return getRestTemplateByTimeout(timeout, timeout);
    }

    public static RestTemplate getRestTemplateByTimeout(int connectTimeout, int readTimeout) {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(connectTimeout);
        httpRequestFactory.setConnectTimeout(connectTimeout);
        httpRequestFactory.setReadTimeout(readTimeout);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);

        List<HttpMessageConverter<?>> httpMessageConverters = restTemplate.getMessageConverters();
        httpMessageConverters.forEach(httpMessageConverter -> {
            if (httpMessageConverter instanceof StringHttpMessageConverter) {
                StringHttpMessageConverter messageConverter = (StringHttpMessageConverter)httpMessageConverter;
                messageConverter.setDefaultCharset(StandardCharsets.UTF_8);
            }
        });

        restTemplate.setErrorHandler(new RestTemplateResponseErrorHandler());
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new LoggingRequestInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }

    /**
     * 无参数方式post
     *
     * @param restTemplate
     * @param url
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T post(RestTemplate restTemplate, String url, Class<T> clazz) {
        return post(restTemplate, url, null, null, null, clazz);
    }

    /**
     * 只有query参数方式post
     *
     * @param restTemplate
     * @param url
     * @param queryParamMap
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T post(RestTemplate restTemplate, String url, LinkedMultiValueMap<String, String> queryParamMap, Class<T> clazz) {
        return post(restTemplate, url, null, queryParamMap, null, clazz);
    }

    /**
     * body参数方式post
     *
     * @param restTemplate
     * @param url
     * @param body
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T post(RestTemplate restTemplate, String url, Object body, Class<T> clazz) {
        return post(restTemplate, url, body, null, null, clazz);
    }

    /**
     * body header参数方式post
     *
     * @param restTemplate
     * @param url
     * @param body
     * @param httpHeaders
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T post(RestTemplate restTemplate, String url, Object body, HttpHeaders httpHeaders, Class<T> clazz) {
        return post(restTemplate, url, body, null, httpHeaders, clazz);
    }

    /**
     * 文件方式
     *
     * @param restTemplate
     * @param url
     * @param map
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T postFile(RestTemplate restTemplate, String url, LinkedMultiValueMap<String, Object> map, Class<T> clazz) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        return postFile(restTemplate, url, map, headers, clazz);
    }

    /**
     * 可带query参数
     *
     * @param restTemplate
     * @param url
     * @param body
     * @param queryParamMap query参数
     * @param headers
     * @param clazz
     * @param <T>
     * @return
     * @param <E>
     */
    public static <T, E> T post(RestTemplate restTemplate, String url, E body, LinkedMultiValueMap<String, String> queryParamMap, HttpHeaders headers, Class<T> clazz) {
        String requestUrl = url;
        if (MapUtils.isNotEmpty(queryParamMap)) {
            requestUrl = UriComponentsBuilder.fromUriString(url).queryParams(queryParamMap).build().encode(StandardCharsets.UTF_8).toUriString();
        }
        if (null == headers) {
            headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        }
        HttpEntity<E> entity = new HttpEntity<>(body, headers);
        ResponseEntity<T> exchange = exchangePost(restTemplate, requestUrl, entity, clazz);
        return exchange.getBody();
    }

    /**
     * 文件方式FileSystemResource
     *
     * @param restTemplate
     * @param url
     * @param map
     * @param headers
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T postFile(RestTemplate restTemplate, String url, LinkedMultiValueMap<String, Object> map, HttpHeaders headers, Class<T> clazz) {
        if (null == headers) {
            headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        }
        HttpEntity<LinkedMultiValueMap<String, Object>> entity = new HttpEntity<>(map, headers);
        ResponseEntity<T> exchange = exchangePost(restTemplate, url, entity, clazz);
        return exchange.getBody();
    }

    private static <E, T> ResponseEntity<T> exchangePost(RestTemplate restTemplate, String requestUrl, HttpEntity<E> entity, Class<T> targetClazz) {
        RestTemplate restTemplate$;
        if (null == restTemplate) {
            restTemplate$ = instanceRestTemplate;
        } else {
            restTemplate$ = restTemplate;
        }
        return restTemplate$.exchange(requestUrl, HttpMethod.POST, entity, targetClazz);
    }

}


这里的注解都是在spring-boot项目下自带的,所以需要你Alt + Enter,Import class即可,日志注解的话,根据项目规定添加就行。这里缺少2个类,一个是RestTemplateResponseErrorHandler,LoggingRequestInterceptor。继续添加:

@Slf4j
public class RestTemplateResponseErrorHandler extends DefaultResponseErrorHandler {

    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return false;
    }

}

第二个类:

@Slf4j
public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        traceRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        traceResponse(response);
        return response;
    }

    private void traceRequest(HttpRequest request, byte[] body) {
        if (log.isDebugEnabled()) {
            log.debug("===========================request begin================================================");
            log.debug("URI         : {}", request.getURI());
            log.debug("Method      : {}", request.getMethod());
            log.debug("Headers     : {}", request.getHeaders());
            log.debug("Request body: {}", new String(body, StandardCharsets.UTF_8));
            log.debug("==========================request end================================================");
        }
    }

    private void traceResponse(ClientHttpResponse response) throws IOException {
        if (log.isDebugEnabled()) {
            StringBuilder inputStringBuilder = new StringBuilder();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), StandardCharsets.UTF_8));
            String line = bufferedReader.readLine();
            while (line != null) {
                inputStringBuilder.append(line);
                inputStringBuilder.append('\n');
                line = bufferedReader.readLine();
            }
            log.debug("============================response begin==========================================");
            log.debug("Status code  : {}", response.getStatusCode());
            log.debug("Status text  : {}", response.getStatusText());
            log.debug("Headers      : {}", response.getHeaders());
            log.debug("Response body: {}", inputStringBuilder);
            log.debug("=======================response end=================================================");
        }

    }

}

当你添加完成,这个工具就可以任你使用了,首先你的代码非常的简洁,其次还是先举例子吧

String url = "www.baidu.com";
String thirdResult = RestTemplateUtils.post(null, url , dto, String.class);

这里解说一下,第一个参数传null即可,第二个是第三方链接,无论你丢在配置文件或者丢在程序中都行,第三个就是body参数,第四呢就是返回的结果。

建议都用String,因为够万能,而且巨方便。

其他使用方式,若用到了有不理解的可以留言,我会不定期回复。但是很多情况下,我更希望大家多多尝试,当然也希望各位大佬不吝赐教。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java便携开发,调用第三方接口工具封装,可直接复制粘贴使用 的相关文章

  • Java中ArrayList的交集和并集

    有什么方法可以做到这一点吗 我正在寻找 但没有找到 另一个问题 我需要这些方法 以便我可以过滤文件 有些是AND过滤器 有些是OR过滤器 就像集合论中的那样 所以我需要根据所有文件和保存这些文件的联合 相交 ArrayList 进行过滤 我
  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • Spring AspectJ 在双代理接口时失败:无法生成类的 CGLIB 子类

    我正在使用Spring的
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • 没有 Spring 的自定义 Prometheus 指标

    我需要为 Web 应用程序提供自定义指标 问题是我不能使用 Spring 但我必须使用 jax rs 端点 要求非常简单 想象一下 您有一个包含键值对的映射 其中键是指标名称 值是一个简单的整数 它是一个计数器 代码会是这样的 public
  • 内部类的构造函数引用在运行时失败并出现VerifyError

    我正在使用 lambda 为内部类构造函数创建供应商ctx gt new SpectatorSwitcher ctx IntelliJ建议我将其更改为SpectatorSwitcher new反而 SpectatorSwitcher 是我正
  • 当 OnFocusChangeListener 应用于包装的 EditText 时,TextInputLayout 没有动画

    不能比标题说得更清楚了 我有一个由文本输入布局包裹的 EditText 我试图在 EditText 失去焦点时触发一个事件 但是 一旦应用了事件侦听器 TextInputLayout 就不再对文本进行动画处理 它只是位于 editText
  • tomcat 中受密码保护的应用程序

    我正在使用 JSP Servlet 开发一个Web应用程序 并且我使用了Tomcat 7 0 33 as a web container 所以我的要求是tomcat中的每个应用程序都会password像受保护的manager applica
  • 如何对不同的参数类型使用相同的java方法?

    我的问题 我有 2 个已定义的记录 创建对象请求 更新对象请求 必须通过实用方法进行验证 由于这两个对象具有相同的字段 因此可以对这两种类型应用相同的验证方法 现在我只是使用两种方法进行重载 但它很冗长 public record Crea
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐