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"] }