最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

dubbo轉http方式調用方式

 更新時間:2025年10月22日 08:35:42   作者:安之若素^  
當前項目計劃去掉網關層,前端將直接通過HTTP調用后端dubbo服務,為此,后端需新增controller層,實現(xiàn)請求兼容和統(tǒng)一轉發(fā),保證前端調用方式不變

業(yè)務背景

在當前項目下,所有前端請求均通過外層網關轉發(fā)到后端這邊的dubbo服務,現(xiàn)計劃去掉網關層,由前端直接http調用后端dubbo。

解決方案

在前端調用方式不變的前提下,后端服務新建controller層(原后端服務無任何controller),做統(tǒng)一請求兼容轉發(fā):

package cn.***********.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.utils.ReferenceConfigCache;
import org.apache.dubbo.rpc.service.GenericService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;
import java.util.Map;

/**
 * Dubbo調用controller
 * @Version:1.0
 * @Desc
 */
@Slf4j
@RestController
@RequestMapping("/api/test/")
public class GenericController {

    @PostMapping("/{service}/{method}")
    public Object invoke(HttpServletRequest request,
                         @PathVariable("service") String service,
                         @PathVariable("method") String method) {
        Object result;
        try {
            GenericService tarService = this.getTargetService(service);
            if(tarService ==  null){
                throw new RuntimeException("獲取service失敗");
            }
            // 1.解析傳入?yún)?shù)
            String paramStr = this.parseInputStream(request);
            // 獲取目標接口的 Class 對象
            Class<?> serviceInterface = Class.forName(service);

            // 獲取方法的參數(shù)類型
            String[] parameterTypes = this.getMethodParameterTypes(serviceInterface, method);

            // 將 JSON 字符串轉換為目標參數(shù)值
            Object[] parameters = this.convertParameters(paramStr, parameterTypes);

            // 調用方法
            result = tarService.$invoke(method, parameterTypes, parameters);

        } catch (Exception e) {
            log.error("服務調用失敗, service={},method={}",service, method, e);
            throw new ErrorCodeException("000000", "系統(tǒng)異常,請稍后重試");
        }
        return result;
    }

    /**
     * 獲取請求文本
     *
     * @return
     */
    public String parseInputStream(HttpServletRequest request) {
        try {
            ServletInputStream inputStream = request.getInputStream();
            StringBuilder content = new StringBuilder();
            int size = request.getContentLength();
            byte[] b = new byte[size];
            int lens;
            while ((lens = inputStream.read(b)) > 0) {
                content.append(new String(b, 0, lens, "utf-8"));
            }
            return content.toString();
        } catch (IOException e) {
            log.error("請求報文解析失敗", e);
            throw new RuntimeException("請求報文解析異常");
        }
    }

    /**
     * 獲取目標dubbo服務
     * @params [service]
     * @return org.apache.dubbo.rpc.service.GenericService
     * @desc
     */
    private GenericService getTargetService(String service){
        // 應用信息
        ApplicationConfig application = SpringBeanUtils.getBean(ApplicationConfig.class);
        // 注冊中心發(fā)現(xiàn)
        RegistryConfig registry = SpringBeanUtils.getBean(RegistryConfig.class);
        // 引用遠程服務
        ReferenceConfig<GenericService> reference = new ReferenceConfig<>();
        reference.setApplication(application);
        reference.setRegistry(registry);
        reference.setProtocol("dubbo");
        reference.setInterface(service);
        reference.setTimeout(10000);
        reference.setRetries(0);
        // 聲明為泛化接口
        reference.setGeneric(true);
        ReferenceConfigCache cache = ReferenceConfigCache.getCache();
        GenericService genericService = cache.get(reference);
        if(genericService == null){
            genericService = reference.get();
        }
        return genericService;
    }

    /**
     * 將 JSON 字符串轉換為目標參數(shù)值
     * @params [paramStr, parameterTypes]
     * @return java.lang.Object[]
     * @author wu.zeng
     * @date 2025/2/21 13:44
     * @desc
     */
    private Object[] convertParameters(String paramStr, String[] parameterTypes) {
        Object[] parameters = new Object[parameterTypes.length];
        for (int i = 0; i < parameterTypes.length; i++) {
            String paramType = parameterTypes[i];
            switch (paramType) {
                case "java.lang.String":
                    parameters[i] = paramStr;
                    break;
                case "java.lang.Integer":
                    parameters[i] = Integer.parseInt(paramStr);
                    break;
                case "java.lang.Long":
                    parameters[i] = Long.parseLong(paramStr);
                    break;
                case "java.util.Map":
                    parameters[i] = JSON.parseObject(paramStr, new TypeReference<Map<String, Object>>() {});
                    break;
                case "java.util.List":
                    parameters[i] = JSON.parseObject(paramStr, new TypeReference<List<Object>>() {});
                    break;
                default:
                    // 如果是自定義類型,使用反射或 JSON 反序列化
                    try {
                        Class<?> clazz = Class.forName(paramType);
                        parameters[i] = JSON.parseObject(paramStr, clazz);
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException("不支持的類型: " + paramType, e);
                    }
            }
        }
        return parameters;
    }

    /*
     * 獲取目標方法的參數(shù)類型
     * @params [serviceInterface, methodName]
     * @return java.lang.String[]
     * @desc
     */
    public String[] getMethodParameterTypes(Class<?> serviceInterface, String methodName) {
        for (Method method : serviceInterface.getMethods()) {
            // 由于不支持重載,因此這里可以根據(jù) methodName 來匹配方法
            if (method.getName().equals(methodName)) {
                Parameter[] parameters = method.getParameters();
                String[] parameterTypes = new String[parameters.length];
                for (int i = 0; i < parameters.length; i++) {
                    parameterTypes[i] = parameters[i].getType().getName();
                }
                return parameterTypes;
            }
        }
        throw new RuntimeException("方法未找到: " + methodName);
    }
}

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java使用定時器編寫一個簡單的搶紅包小游戲

    Java使用定時器編寫一個簡單的搶紅包小游戲

    這篇文章主要為大家介紹了Java如何使用定時器編寫一個簡單的搶紅包小游戲,文中的示例代碼講解詳細,感興趣的小伙伴可以嘗試一下
    2022-07-07
  • MyBatis分頁插件PageHelper的使用與原理

    MyBatis分頁插件PageHelper的使用與原理

    提到插件相信大家都知道,插件的存在主要是用來改變或者增強原有的功能,MyBatis中也一樣,下面這篇文章主要給大家介紹了關于Mybatis第三方PageHelper分頁插件的使用與原理,需要的朋友可以參考下
    2023-02-02
  • java實現(xiàn)線性表及其算法

    java實現(xiàn)線性表及其算法

    線性表是最簡單和最常用的一種數(shù)據(jù)結構,它是有n個體數(shù)據(jù)元素(節(jié)點)組成的有限序列,這篇文章主要介紹了java實現(xiàn)線性表及其算法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 用Java編程輸出萬年歷的功能實現(xiàn)

    用Java編程輸出萬年歷的功能實現(xiàn)

    這篇文章主要介紹了用Java編程輸出萬年歷的功能實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Java基于棧方式解決漢諾塔問題實例【遞歸與非遞歸算法】

    Java基于棧方式解決漢諾塔問題實例【遞歸與非遞歸算法】

    這篇文章主要介紹了Java基于棧方式解決漢諾塔問題的方法,結合實例形式分析了java棧方式采用遞歸與非遞歸算法解決漢諾塔問題的相關操作技巧,需要的朋友可以參考下
    2017-11-11
  • 使用ObjectMapper解析json不用一直new了

    使用ObjectMapper解析json不用一直new了

    這篇文章主要為大家介紹了使用ObjectMapper解析json不用一直new了的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • mybatis如何在一個update標簽中寫多條update語句

    mybatis如何在一個update標簽中寫多條update語句

    這篇文章主要介紹了mybatis如何在一個update標簽中寫多條update語句問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • tomcat9使用指定的JDK版本完整步驟記錄

    tomcat9使用指定的JDK版本完整步驟記錄

    在服務器部署多個JDK版本的場景下,Tomcat默認讀取系統(tǒng)環(huán)境變量可能導致版本沖突,下面這篇文章主要介紹了tomcat9使用指定的JDK版本的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2026-04-04
  • Java版C語言版簡單使用靜態(tài)語言實現(xiàn)動態(tài)數(shù)組的方法

    Java版C語言版簡單使用靜態(tài)語言實現(xiàn)動態(tài)數(shù)組的方法

    本文給大家分享java版和C語言版簡單使用靜態(tài)語言實現(xiàn)動態(tài)數(shù)組的方法,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-10-10
  • 詳解Java集合中的基本數(shù)據(jù)結構

    詳解Java集合中的基本數(shù)據(jù)結構

    總有小伙伴讓我總結一下Java集合中的基本數(shù)據(jù)結構的相關知識,今天特地整理了本篇文章,文中有非常詳細的介紹,需要的朋友可以參考下
    2021-06-06

最新評論

确山县| 化德县| 蛟河市| 东方市| 扶风县| 全南县| 八宿县| 大方县| 汶上县| 怀集县| 长武县| 武隆县| 盐城市| 衡东县| 射阳县| 苏州市| 内江市| 临潭县| 雷山县| 桐梓县| 定陶县| 怀集县| 繁峙县| 武功县| 泰宁县| 香格里拉县| 武安市| 乌审旗| 北安市| 长汀县| 老河口市| 洛南县| 松阳县| 丹巴县| 大余县| 泊头市| 张家川| 商河县| 于都县| 新沂市| 南郑县|