首頁 > 軟體

SpringBoot Http遠端呼叫的方法

2022-08-14 14:02:06

本文範例為大家分享了SpringBoot Http遠端呼叫的具體程式碼,供大家參考,具體內容如下

一、在實現遠端呼叫時可以使用feign與http遠端呼叫,兩者的關係有一下幾點:

feign、http,有時候在呼叫第三方api的時候、使用httpclient,別人的介面不可能提供它的設定,自己專案框架是spring的,使用feign相互設定,都是okhttpclient的方式。Feign是一個介面宣告式呼叫框架,實現了一個抽象層的邏輯,沒有真正實現底層http請求,提供了一個client介面用於實現底層http操作,預設提供的實現是基於httpurlconnection,也有基於apachehttpclient的實現,且feign具有分散式負載均衡功能。

二、使用案例

需求是在本服務中呼叫另外一個服務中的裝置上線的功能,有feign、http等可以選擇,這裡選擇的是http呼叫。

 /**
     * 超級管理員授權
     * @param userName
     * @param clientid
     * @return
     */
    @PostMapping("/mqtt/superuser")
    @Transactional
    public Integer loginCheck2(@RequestParam("username") String userName,
                              @RequestParam("clientid") String clientid){
        System.out.println(userName);
        System.out.println("超級管理員");
        userName = "6217XXXXXXXXXXXd85/3XXXX3";
        //拼接實體類跳轉ibms-iot平臺,上線
        publishConnected(clientid, userName);

        return 400;
    }
/**
     * 遠端呼叫另一個服務中的裝置上線功能
     * @param clientid
     * @param userName
     */
    private void publishConnected(String clientid, String userName) {
        Connected connected = new Connected();
        connected.setAction(ACTION);
        connected.setClientid(clientid);
        connected.setUsername(userName);
        Date date = new Date();
        connected.setConnected_at(date.getTime());
        Map<String, Object> param = BeanUtil.beanToMap(connected, false, true);
        String url = IotPropertiesConfig.HTTP_PREFIX + IotPropertiesConfig.IP_PORT+ UrlConstant.webHook_path;
        String result = HttpUtils.postByRetry(url, param, IotPropertiesConfig.HTTP_TIMEOUT);
        log.info("裝置:{}上線內容的通知結果:{}",connected.getUsername(),result);
    }

httpUtil工具類:

package com.setch.crodigy.utils;

import cn.hutool.http.HttpRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.rholder.retry.*;
import com.google.common.base.Predicates;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.*;

/**
 * 介面客製化工具類
 */

@Slf4j
public class HttpUtils {


    private static final String CONTENT_TYPE = "Content-Type";
    private static final String AUTHORIZATION = "Authorization";
    private static final String CONTENT_TYPE_VALUE = "application/x-www-form-urlencoded";
    private static final String CONTENT_TYPE_VALUE_JSON = "application/json";
    private static ObjectMapper json = new ObjectMapper();
    private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    //重試間隔
    private static long sleepTime = 1L;
    //重試次數
    private static int attemptNumber = 5;
    //設定重試機制
    private final static Retryer<String> retryer = RetryerBuilder.<String>newBuilder()
            .retryIfResult(Predicates.<String>isNull())    // 設定自定義段元重試源
            .retryIfExceptionOfType(Exception.class)        // 設定異常重試源
            .retryIfRuntimeException()                      // 設定異常重試源
            .withStopStrategy(StopStrategies.stopAfterAttempt(attemptNumber))   // 設定重試次數    設定重試超時時間????
            .withWaitStrategy(WaitStrategies.fixedWait(sleepTime, TimeUnit.SECONDS)) // 設定每次重試間隔
            .build();


    /**
     * 裝置上線使用
     * @param url
     * @param paramMap
     * @param timeout
     */
    public static void deviceOnline(String url, Map<String, Object> paramMap, int timeout) {

        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                 postByRetry("",null,1);
            }
        });

    }
    /**
     *
     * @param url 存取路徑
     * @param paramMap 請求體
     * @param timeout 超時時間  單位: 秒
     * @return
     * @throws JsonProcessingException
     */
    public static String postByRetry(String url, Map<String, Object> paramMap, int timeout) {


        Callable<String> task = new Callable<String>() {
            int i = 0;
            @Override
            public String call() throws Exception {
                i++;
                if(i > 1){
                    log.info("請求初次執行失敗,開始第{}次執行!", i);
                }
                String result = post(url, paramMap, timeout);
                return result;
            }
        };

        String res = "";
        try {
            //執行任務的重試,得到返回結果
             res = retryer.call(task);
        } catch (ExecutionException e) {
            log.error("Post ExecutionException", e);
        } catch (RetryException e) {
            log.error("Post RetryException", e);
        }
        return res;
    }

    /**
     *
     * @param url 存取路徑
     * @param paramMap 請求體
     * @param timeout 超時時間  單位: 秒
     * @return
     * @throws JsonProcessingException
     */
    public static String post(String url, Map<String, Object> paramMap, int timeout) throws JsonProcessingException {
        String map = json.writeValueAsString(paramMap);
        String result = HttpRequest
                .post(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE).timeout(timeout * 1000)
                .body(map).execute().body();

        return result;
    }


    /**
     *
     * @param url 存取路徑
     * @param map 請求體
     * @param timeout 超時時間  單位: 秒
     * @return
     */
    public static String post(String url, String map, int timeout)  {

        String result = HttpRequest
                .post(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE).timeout(timeout * 1000)
                .body(map).execute().body();

        return result;
    }

    /**
     *
     * @param url 存取路徑
     * @param map 請求體
     * @param timeout 超時時間  單位: 秒
     * @return
     */
    public static String post(String url, String map, int timeout,String authorization)  {

        String result = HttpRequest
                .post(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE).header(AUTHORIZATION,authorization)
                        .timeout(timeout * 1000)
                .body(map).execute().body();

        return result;
    }


    /**
     *
     * @param url 存取路徑
     * @param timeout 超時時間  單位: 秒
     * @param authorization 認證token
     */
    public static String get(String url, int timeout,String authorization)  {

        String result = HttpRequest.get(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE_JSON).header(AUTHORIZATION,authorization)
                .timeout(timeout * 1000).execute().body();

        return result;
    }


    /**
     *
     * @param url 存取路徑
     * @param timeout 超時時間  單位: 秒
     * @param authorization 認證token
     */
    public static String delete(String url, int timeout,String authorization ,String map)  {

        String result = HttpRequest.delete(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE_JSON).header(AUTHORIZATION,authorization)
                .timeout(timeout * 1000).body(map).execute().body();

        return result;
    }

    /**
     *
     * @param url 存取路徑
     * @param timeout 超時時間  單位: 秒
     * @param authorization 認證token
     */
    public static String delete(String url, int timeout,String authorization )  {

        String result = HttpRequest.delete(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE_JSON).header(AUTHORIZATION,authorization)
                .timeout(timeout * 1000).execute().body();

        return result;
    }
}

這裡的publishConnectEd(clientid,userName);使用http遠端呼叫另外一個服務中的裝置上線的介面。
String url : 需要跳轉的介面路徑。(如:http://localhost:8080/user/login)
param: 遠端呼叫時,所需引數。
HttpUtils.postByRetry() 實現http遠端呼叫。

下面是需要被遠端呼叫的介面

import antlr.StringUtils;
import com.setch.crodigy.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RequestMapping("/testDemo")
@RestController
public class ProductController {

    @Autowired
    private ProductService productService;

    @PostMapping("/save")
    @Transactional
    public boolean saveProduct(@RequestBody Product product){

        Product result = productService.save(product);
        if (result != null){
            return true;
        }else {
            return false;
        }
    }
}

以上是本人個人使用案例,測試成功,初次使用,若有問題歡迎大家提出指正。

希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com