spring boot使用hutool实现调用外部接口

一:依赖安装

复制代码
<!--Hutool Java工具包-->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.46</version>
</dependency>

二:增加自定义异常类

复制代码
package com.example.demo.exception;
 
/**
 * 自定义异常处理类型
 */
public class BusinessException extends RuntimeException {
    // 错误码
    private Integer code;
 
    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }
 
    // 只传消息,默认500
    public BusinessException(String message) {
        super(message);
        this.code = 500;
    }
 
    public Integer getCode() {
        return code;
    }
}

三:增加全局异常处理器

复制代码
package com.example.demo.exception;
 
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
 
import java.util.LinkedHashMap;
import java.util.Map;
 
@RestControllerAdvice
public class GlobalExceptionHandler {
 
    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<Map<String, Object>> handleBusiness(BusinessException e) {
        Map<String, Object> body = new LinkedHashMap<>();
        body.put("code", e.getCode());
        body.put("message", e.getMessage());
        int status = e.getCode() != null && e.getCode() >= 400 && e.getCode() < 600
                ? e.getCode()
                : HttpStatus.INTERNAL_SERVER_ERROR.value();
        return ResponseEntity.status(status).body(body);
    }
}

四:增加http调用工具类

复制代码
package com.example.demo.util;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.example.demo.exception.BusinessException;
import org.springframework.stereotype.Component;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.ObjectMapper;

import java.util.Map;

@Component
public class HttpUtil {

    private final ObjectMapper objectMapper;

    public HttpUtil(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    /**
     * GET请求
     * @param url 地址
     * @param params query参数
     * @param headers 请求头
     * @param clazz 返回实体类
     */
    public Map<String, Object> get(String url, Map<String, Object> params, Map<String, String> headers)
    {
        HttpRequest request = HttpRequest.get(url)
                .form(params)
                .timeout(5000);
        // 设置headers
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(request::header);
        }
        try (HttpResponse response = request.execute()) {
            checkResp(response);
            String body = response.body();
            return objectMapper.readValue(body, new TypeReference<Map<String, Object>>() {});
        } catch (Exception e) {
            throw new BusinessException(500, "调用接口失败:" + e.getMessage());
        }
    }
    /**
     * post json请求
     * @param url 接口地址
     * @param reqBody 请求体对象
     * @param headers 请求头
     */
    public Map<String, Object> postJson(String url, Object reqBody, Map<String, String> headers) {
        String json = JSON.toJSONString(reqBody);
        HttpRequest request = HttpRequest.post(url)
                .body(json)
                .header("Content-Type", "application/json")
                .timeout(5000);
        // 设置自定义请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(request::header);
        }
        try (HttpResponse response = request.execute()) {
            checkResp(response);
            return objectMapper.readValue(response.body(), new TypeReference<Map<String, Object>>() {});
        } catch (Exception e) {
            throw new BusinessException(500, "调用接口失败:" + e.getMessage());
        }
    }

    /**
     * POST form表单提交 【application/x-www-form-urlencoded】
     * @param url 请求地址
     * @param formParams 表单参数
     * @param headers 请求头
     */
    public Map<String, Object> postForm(String url, Map<String, Object> formParams, Map<String, String> headers) {
        HttpRequest request = HttpRequest.post(url)
                .form(formParams) // form表单参数,hutool自动编码,自动设置Content-Type
                .timeout(5000);
        // 追加自定义请求头
        if (headers != null && !headers.isEmpty()) {
            headers.forEach(request::header);
        }
        try (HttpResponse response = request.execute()) {
            checkResp(response);
            String body = response.body();
            return objectMapper.readValue(body, new TypeReference<Map<String, Object>>() {});
        } catch (Exception e) {
            throw new BusinessException(500, "调用接口失败:" + e.getMessage());
        }
    }

    /**
     * 校验响应
     */
    private static void checkResp(HttpResponse response) {
        if (!response.isOk()) {
            throw new BusinessException(500, "调用第三方接口异常,状态码:" + response.getStatus() + ",响应:" + response.body());
        }
        String body = response.body();
        if (StrUtil.isBlank(body)) {
            throw new BusinessException(500, "第三方接口返回空");
        }
    }
}

注意:如果找不到com.alibaba.fastjson2.JSON这个类,增加如下依赖

复制代码
<!--JSON 序列化、反序列化-->
<dependency>
    <groupId>com.alibaba.fastjson2</groupId>
    <artifactId>fastjson2</artifactId>
    <version>2.0.58</version>
</dependency>

五:增加工具类调用示例

复制代码
package com.example.demo.controller;

import com.example.demo.util.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/http")
public class HttpController {

    @Autowired
    private HttpUtil httpUtil;

    @GetMapping("/get")
    public Map<String, Object> get(){
        //get调用
        //组装header
        Map<String,String> headers = new HashMap<>();
        headers.put("token","xxx");
        //请求体
        Map<String,Object> queryParam = new HashMap<>();
        queryParam.put("id",1);

        return httpUtil.get("http://xxxx/test", queryParam, headers);
    }



    static class ReqBody
    {
        private String username;

        private String phone;

        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }

    }

    @GetMapping("/postJson")
    public Map<String, Object> jsonPost()
    {
        //json post调用
        //组装header
        Map<String,String> headers = new HashMap<>();
        headers.put("Authorization","Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9");
        headers.put("appId","TEST001");
        headers.put("sign","20260916xxxx");

        //请求体
        ReqBody req = new ReqBody();
        req.setUsername("zhangsan");
        req.setPhone("13333333333");
        return httpUtil.postJson("http://xxx/test1", req, headers);
    }

    @GetMapping("/formPost")
    public Map<String, Object> formPost()
    {
        //form post调用

        //组装header
        Map<String,String> headers = new HashMap<>();
        headers.put("token","abc123456");
        headers.put("appId","DEMO001");

        //请求体
        Map<String,Object> formParam = new HashMap<>();
        formParam.put("username","zhangsan");
        formParam.put("phone","13333333333");
        formParam.put("type",1);

        return httpUtil.postForm("http://xxx/test2", formParam, headers);
    }
}
相关推荐
泡海椒1 小时前
Java 后端最优 PDF 导出方案:jquick-pdf 项目引入与快速测试
java·开发语言·pdf
阿飞7662 小时前
订单超时自动关单:RabbitMQ 延迟队列 + 定时任务"双保险"实践
java
二炮手亮子2 小时前
使用云服务+hermes+mino模型 我用微信操控服务器自己编程并部署实操
java·语言模型·ai编程
dkbnull2 小时前
Spring Boot配置文件敏感信息加密解密
spring boot·后端
她的男孩2 小时前
安全同事找我要"上周所有登录失败记录",我查完数据库:一条都没有
java·后端·架构
白宇横流学长2 小时前
图书个性化推荐系统的设计与实现【源码+文档】
spring boot
m0_587383002 小时前
本地同城无人机作业接单系统源码:架构拆解与抢单调度实现
java·小程序·架构·需求分析
RuoyiOffice2 小时前
SpringBoot3+Vue3+Flowable 企业审批平台全链路:从表单设计、节点权限到移动审批怎么落地
spring boot·vue3·uniapp·springboot3·flowable·审批系统·ruoyi office
FantanLee2 小时前
面试级「分布式 ID 设计方案」
java