http转dubbo调用

来源:互联网 发布:淘宝上怎么搜dj香烟 编辑:程序博客网 时间:2024/06/02 03:28

        dubbo服务是现在互联网公司比较流行的服务,一般用于内部系统间的调用。正常情况下服务消费方需要导入服务提供skeleton的jar包。因此需要对测试dubbo服务接口的人员需要一定的代码编写能力,需要写对应的消费方代码。当然这个很简单,但是为了更加简便和通用的使用dubbo接口,下面将把dubbo接口转成http接口暴露出去,这样测试人员可以直接使用postman等测试工具进行测试了。闲话不多说 开搞吧~~

      思路:我们要接收http协议同时转化http成dubbo接口调用 并将返回结果再转成http返回给客户端。因此需要一个HttpServlet,主要作用是接收http请求,调用、转化。如下直接贴上 参考公司大神的代码

看下实现代码:

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

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.dubbo.common.utils.IOUtils;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class DubboToHttpServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    private static Logger logger = LoggerFactory.getLogger(DubboToHttpServlet.class);

    private ApplicationConfig application = new ApplicationConfig("dubbo-to-http");
    private Map<String, GenericService> serviceCache = new HashMap<String, GenericService>();

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.info("servlet start");

        // 1. 解析请求体
        logger.info("parsing request body");
        JSONObject requestJson = JSON.parseObject(IOUtils.read(new InputStreamReader(request.getInputStream())));
        logger.info("parsed request body. body json: {}", requestJson);

        // 2. 获取泛化服务接口
        logger.info("fetching generic service");
        GenericService service = this.fetchGenericService(requestJson);
        logger.info("fetched generic service. service: {}", service);

        // 3. 组装调用参数
        String method = requestJson.getString("method");
        String[] parameterTypes = this.toArray(requestJson.getJSONArray("paramTypes"));
        Object[] args = requestJson.getJSONArray("paramValues").toArray(new Object[] {});

        // 4. 调用接口
        logger.info("invoking remote service");
        String result = JSON.toJSONString(service.$invoke(method, parameterTypes, args));
        logger.info("invoked remote service. return: {}", result);

        // 5. 返回
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.append(result).flush();
        out.close();

        logger.info("servlet end");
    }

    @Override
    public void destroy() {
        RegistryConfig.destroyAll();
    }

    // 获取泛化服务接口. 如有缓存, 从缓存取
    private GenericService fetchGenericService(JSONObject requestJson) {
        String serviceInterface = requestJson.getString("interface");
        String serviceGroup = requestJson.getString("group");
        String serviceVersion = requestJson.getString("version");

        String serviceCacheKey = serviceInterface + serviceGroup + serviceVersion;
        GenericService service = serviceCache.get(serviceCacheKey);
        if (service != null) {
            logger.info("fetched generic service from cache");
            return service;
        }

        logger.info("initing generic service");
        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
        reference.setApplication(application);
        reference.setInterface(serviceInterface);
        reference.setGroup(serviceGroup);
        reference.setVersion(serviceVersion);
        reference.setGeneric(true);
        service = reference.get();
        serviceCache.put(serviceCacheKey, service);

        return service;
    }

    // List<Object> -> String[]
    private String[] toArray(List<Object> list) {
        String[] array = new String[list.size()];
        for (int i = 0; i < array.length; i++) {
            array[i] = list.get(i).toString();
        }
        return array;
    }
}


客户端http调用消息格式:
{
    "registry": "zookeeper://***.**.***:2181",
    "interface": "com.ihome.basicbiz.*****Service",
    "version": "",
    "group": "",
    "method": "payout",
    "paramTypes": ["com.ihome.basicbiz****.TrustaccPayoutParam", "java.lang.String"],
    "paramValues": [{
        "payeeBankObProvinceName": "",
        "payeeBankObCity": "",
        "payeeBankObCityName": "",
        "payeeBankObSubbranch": "",
        "trustaccSource": "CASHIER",
        "tradeType": 2,
        "transcoreTradeType": 2,
        "useDesc": "",
        "remark": "",
        "payinPayeeBankcardNo": "",
        "transType": "",
        "detailList": [{
            "customerId": 222001,
            "amount": 100,
            "projectCode": "1101000010438",
            "outPayNo": "OUT_PAY_NO_001",
            "outFreezeNo": ""
        }],
        "productNo": "",
     
    }, "123"]
}

原创粉丝点击