欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析

程序员文章站 2022-07-10 19:50:52
背景在rpc的服务化调用中,如果客户端使用多种调用姿势,比如jsonrpc的标准调用、jsonrpc的泛化调用同时存在,那么服务端必须能够同时对这两种典型的调用的方式进行兼容。好在jsonrpc和spring的web框架可以完美集成。比如服务端使用jsonrpc+springboot进行集成。这里解释一下什么是jsonrpc的泛化调用?一句话,就是对jsonrpc的传输协议进行改造并进行http调用,让服务端以传统webController的方式接收请求。jsonrpc的标准调用是什么?可以参看下文档...

背景

在rpc的服务化调用中,如果客户端使用多种调用姿势,比如jsonrpc的标准调用、jsonrpc的泛化调用同时存在,那么服务端必须能够同时对这两种典型的调用的方式进行兼容。好在jsonrpc和spring的web框架可以完美集成。比如服务端使用jsonrpc+springboot进行集成。
这里解释一下什么是jsonrpc的泛化调用?一句话,就是对jsonrpc的传输协议进行改造并进行http调用,让服务端以传统webController的方式接收请求。
jsonrpc的标准调用是什么?可以参看下文档:https://github.com/briandilley/jsonrpc4j
这里不对jsonrpc的基础使用姿势进行说明,可以自己补一下。jsonrpc的基本协议格式是:
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析

具体可以看下官方文档相关协议说明:https://www.jsonrpc.org/specification

思路分析

那么,jsonrpc泛化请求如:/demo2/genericService/genericCall在服务端是怎么处理的?
通过抓包可以看到请求报文如下:
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析跟普通的http的web请求没啥两样。
前边说过,服务端我们是springboot+jsonrpc的框架,所以会由DispatcherServlet的doDispatch方法为入口。

  • 关键代码:
mappedHandler = getHandler(processedRequest);

首先,DispatcherServlet里getHandler方法就可以通过request对象从以下handlerMappings中找到合适的handler。
代码如下:

/**
 * Return the HandlerExecutionChain for this request.
 * <p>Tries all handler mappings in order.
 * @param request current HTTP request
 * @return the HandlerExecutionChain, or {@code null} if no handler could be found
 */
@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   if (this.handlerMappings != null) {
      for (HandlerMapping mapping : this.handlerMappings) {
         HandlerExecutionChain handler = mapping.getHandler(request);
         if (handler != null) {
            return handler;
         }
      }
   }
   return null;
}

Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
比如这里找到的就是具体Controller的目标调用method,同时这里匹配到的是RequestMappingHandlerMapping:
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析但是对于jsonrpc的标准调用,这里有了变化。这里匹配到的是BeanNameHandlerMapping,得到的handler是JsonServiceExporter。
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
JsonServiceExporter是jsonrpc的类,继承了AbstractJsonServiceExporter,实现了org.springframework.web.HttpRequestHandler。JsonServiceExporter是被spring容器实例化的时候调用AbstractJsonServiceExporter的afterProperties方法来完成jsonrpcServer的创建。
代码如下:

  • JsonServiceExporter
public class JsonServiceExporter extends AbstractJsonServiceExporter implements HttpRequestHandler {

   private JsonRpcServer jsonRpcServer;

   /**
    * {@inheritDoc}
    */
   @Override
   protected void exportService() {
      jsonRpcServer = getJsonRpcServer();
   }

   /**
    * {@inheritDoc}
    */
   public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      jsonRpcServer.handle(request, response);
      response.getOutputStream().flush();
   }

}
  • AbstractJsonServiceExporter:
abstract class AbstractJsonServiceExporter extends RemoteExporter implements InitializingBean, ApplicationContextAware {

    public void afterPropertiesSet() throws Exception {
        ...
        jsonRpcServer = new JsonRpcServer(objectMapper,
      null == getServiceInterface() ? getService() : getProxyForService(),
      getServiceInterface());
        .....
    }
     .....
}

然后,根据handler查找HandlerAdapter,关键代码如下:

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

具体如下:

/**
 * Return the HandlerAdapter for this handler object.
 * @param handler the handler object to find an adapter for
 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
 */
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
   if (this.handlerAdapters != null) {
      for (HandlerAdapter adapter : this.handlerAdapters) {
         if (adapter.supports(handler)) {
            return adapter;
         }
      }
   }
   throw new ServletException("No adapter for handler [" + handler +
         "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
}

这里的handlerAdapters是:
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
这里handler最终找到的是RequestMappingHandlerAdapter。
但同样如果是jsonrpc的标准调用,这里就不一样了。由于JsonServiceExporter实现了HttpRequestHandler接口,所以这里支持的适配器就是HttpRequestHandlerAdapter。

public class JsonServiceExporter extends AbstractJsonServiceExporter implements HttpRequestHandler{......}

Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
然后,就是执行具体的方法返回modeAndView视图了。关键代码:

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

但RequestMappingHandlerAdapter也没有实现AbstractHandlerMethodAdapter的handle方法。所以使用抽象类中的方法。

/**
 * This implementation expects the handler to be an {@link HandlerMethod}.
 */
@Override
@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {

   return handleInternal(request, response, (HandlerMethod) handler);
}

最终执行到业务Controller中的方法。
不过jsonrpc的标准调用返回的适配器是HttpRequestHandlerAdapter,自然也就是执行其hanle方法了。

package org.springframework.web.servlet.mvc;

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

import org.springframework.lang.Nullable;
import org.springframework.web.HttpRequestHandler;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;

/**
 * Adapter to use the plain {@link org.springframework.web.HttpRequestHandler}
 * interface with the generic {@link org.springframework.web.servlet.DispatcherServlet}.
 * Supports handlers that implement the {@link LastModified} interface.
 *
 * <p>This is an SPI class, not used directly by application code.
 *
 * @author Juergen Hoeller
 * @since 2.0
 * @see org.springframework.web.servlet.DispatcherServlet
 * @see org.springframework.web.HttpRequestHandler
 * @see LastModified
 * @see SimpleControllerHandlerAdapter
 */
public class HttpRequestHandlerAdapter implements HandlerAdapter {

   @Override
   public boolean supports(Object handler) {
      return (handler instanceof HttpRequestHandler);
   }

   @Override
   @Nullable
   public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
         throws Exception {

      ((HttpRequestHandler) handler).handleRequest(request, response);
      return null;
   }

   @Override
   public long getLastModified(HttpServletRequest request, Object handler) {
      if (handler instanceof LastModified) {
         return ((LastModified) handler).getLastModified(request);
      }
      return -1L;
   }

}

这里hanle传进来的handler也就是JsonServiceExporter,也就是说最终会执行其hanleRequest方法。
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
后在jsonRpcServer中进行一系列的反射调用,执行到最后的标注有@AutoJsonRpcServiceImpl的Service方法上。

本文地址:https://blog.csdn.net/shengqianfeng/article/details/109640865