Jsonrpc标准+泛化调用,服务端DispatcherServlet源码思路分析
背景
在rpc的服务化调用中,如果客户端使用多种调用姿势,比如jsonrpc的标准调用、jsonrpc的泛化调用同时存在,那么服务端必须能够同时对这两种典型的调用的方式进行兼容。好在jsonrpc和spring的web框架可以完美集成。比如服务端使用jsonrpc+springboot进行集成。
这里解释一下什么是jsonrpc的泛化调用?一句话,就是对jsonrpc的传输协议进行改造并进行http调用,让服务端以传统webController的方式接收请求。
jsonrpc的标准调用是什么?可以参看下文档:https://github.com/briandilley/jsonrpc4j
这里不对jsonrpc的基础使用姿势进行说明,可以自己补一下。jsonrpc的基本协议格式是:
具体可以看下官方文档相关协议说明:https://www.jsonrpc.org/specification
思路分析
那么,jsonrpc泛化请求如:/demo2/genericService/genericCall在服务端是怎么处理的?
通过抓包可以看到请求报文如下:
跟普通的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;
}
比如这里找到的就是具体Controller的目标调用method,同时这里匹配到的是RequestMappingHandlerMapping:
但是对于jsonrpc的标准调用,这里有了变化。这里匹配到的是BeanNameHandlerMapping,得到的handler是JsonServiceExporter。
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是:
这里handler最终找到的是RequestMappingHandlerAdapter。
但同样如果是jsonrpc的标准调用,这里就不一样了。由于JsonServiceExporter实现了HttpRequestHandler接口,所以这里支持的适配器就是HttpRequestHandlerAdapter。
public class JsonServiceExporter extends AbstractJsonServiceExporter implements HttpRequestHandler{......}
然后,就是执行具体的方法返回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方法。
后在jsonRpcServer中进行一系列的反射调用,执行到最后的标注有@AutoJsonRpcServiceImpl的Service方法上。
本文地址:https://blog.csdn.net/shengqianfeng/article/details/109640865
上一篇: Java高级:鼠标监听的代码文字图片说明
下一篇: 如何用自己的手机拍出好看的照片?