JsonRpc源码--处理http请求源码刨析

从jsonRpc接入http请求直至开始业务逻辑处理总体层级如下:

JsonServiceExporter->handleRequest-> handle -> handleRequest0 ->handleRequest -> handleJsonNodeRequest -> handleObject -> methodInvoke

  • google的jsonrpc4j通过实现springframework中的httpRequestHandler来对请求进行处理;源码如下:
package com.googlecode.jsonrpc4j.spring;

import com.googlecode.jsonrpc4j.JsonRpcServer;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.HttpRequestHandler;

class JsonServiceExporter extends AbstractJsonServiceExporter implements HttpRequestHandler {
    private JsonRpcServer jsonRpcServer;

    JsonServiceExporter() {
    }

    protected void exportService() {
        this.jsonRpcServer = this.getJsonRpcServer();
    }

    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.jsonRpcServer.handle(request, response);
        response.getOutputStream().flush();
    }
}
  • 进入handle可以看到在此层会对捕获http请求中出现的所有异常,并进行异常处理,回显jsonrpc中自定义的错误代码以及结构;源码如下:

/**
 * Handles a servlet request.
 *
 * @param request  the {@link HttpServletRequest}
 * @param response the {@link HttpServletResponse}
 * @throws IOException on error
 */
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
	logger.debug("Handling HttpServletRequest {}", request);
	response.setContentType(contentType);
	OutputStream output = response.getOutputStream();
	InputStream input = getRequestStream(request);
	int result = ErrorResolver.JsonError.PARSE_ERROR.code;
	int contentLength = 0;
	ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
	try {
		String acceptEncoding = request.getHeader(ACCEPT_ENCODING);
		result = handleRequest0(input, output, acceptEncoding, response, byteOutput);

		contentLength = byteOutput.size();
	} catch (Throwable t) {
		if (StreamEndedException.class.isInstance(t)) {
			logger.debug("Bad request: empty contents!");
		} else {
			logger.error(t.getMessage(), t);
		}
	}
	int httpStatusCode = httpStatusCodeProvider == null ? DefaultHttpStatusCodeProvider.INSTANCE.getHttpStatusCode(result)
			: httpStatusCodeProvider.getHttpStatusCode(result);
	response.setStatus(httpStatusCode);
	response.setContentLength(contentLength);
	byteOutput.writeTo(output);
	output.flush();
}
  • 进入handleRequest0 ->handleRequest -> handleJsonNodeRequest,这一步从输入流中读取对应的请求并归属为jsonrpc请求、处理对应请求,并返回结果代码;源码如下:
/**
 * Handles a single request from the given {@link InputStream},
 * that is to say that a single {@link JsonNode} is read from
 * the stream and treated as a JSON-RPC request.  All responses
 * are written to the given {@link OutputStream}.
 *
 * @param input  the {@link InputStream}
 * @param output the {@link OutputStream}
 * @return the error code, or {@code 0} if none
 * @throws IOException on error
 */
public int handleRequest(final InputStream input, final OutputStream output) throws IOException {
	final ReadContext readContext = ReadContext.getReadContext(input, mapper);
	try {
		readContext.assertReadable();
		final JsonNode jsonNode = readContext.nextValue();
		for (JsonRpcInterceptor interceptor : interceptorList) {
			interceptor.preHandleJson(jsonNode);
		}
		JsonResponse jsonResponse = handleJsonNodeRequest(jsonNode);
		writeAndFlushValue(output, jsonResponse.getResponse());
		if (jsonResponse.getExceptionToRethrow() != null) {
			throw jsonResponse.getExceptionToRethrow();
		}
		return jsonResponse.getCode();
	} catch (JsonParseException | JsonMappingException e) {
		JsonResponse responseError = createResponseError(VERSION, NULL, JsonError.PARSE_ERROR);
		writeAndFlushValue(output, responseError.getResponse());
		return responseError.getCode();
	}
}
  • 进入handleJsonNodeRequest,这里会对请求体中的json对象进行判别并进行对应处理;源码如下:
/**
 * Handles the given {@link JsonNode} and creates {@link JsonResponse}
 *
 * @param node the {@link JsonNode}
 * @return the {@link JsonResponse} instance
 */
protected JsonResponse handleJsonNodeRequest(final JsonNode node)
		throws JsonParseException, JsonMappingException {
	if (node.isArray()) {
		return handleArray((ArrayNode) node);
	}
	if (node.isObject()) {
		return handleObject((ObjectNode) node);
	}
	return createResponseError(VERSION, NULL, JsonError.INVALID_REQUEST);
}
REQUEST);
    }

  • 这里以handleObject为例,进来后其实就是对json的结构进行验证并调用对应方法;部分解析我会写道下面源码里边;

	/**
	 * Handles the given {@link ObjectNode} and creates {@link JsonResponse}
	 *
	 * @param node   the {@link JsonNode}
	 * @return the {@link JsonResponse} instance
	 */
	private JsonResponse handleObject(final ObjectNode node)
			throws JsonParseException, JsonMappingException {
		logger.debug("Request: {}", node);
		// 验证请求中是否存在"jsonRpc" 以及 "method"
		if (!isValidRequest(node)) {
			return createResponseError(VERSION, NULL, JsonError.INVALID_REQUEST);
		}
		// 获取对应请求id
		Object id = parseId(node.get(ID));
		// 验证参数是否为空
		String jsonRpc = hasNonNullData(node, JSONRPC) ? node.get(JSONRPC).asText() : VERSION;
		if (!hasNonNullData(node, METHOD)) {
			return createResponseError(jsonRpc, id, JsonError.METHOD_NOT_FOUND);
		}
		// 获取方法路径信息
		final String fullMethodName = node.get(METHOD).asText();
		final String partialMethodName = getMethodName(fullMethodName);
		final String serviceName = getServiceName(fullMethodName);
		
		Set<Method> methods = findCandidateMethods(getHandlerInterfaces(serviceName), partialMethodName);
		if (methods.isEmpty()) {
			return createResponseError(jsonRpc, id, JsonError.METHOD_NOT_FOUND);
		}
		// 验证方法参数是否齐全
		AMethodWithItsArgs methodArgs = findBestMethodByParamsNode(methods, node.get(PARAMS));
		if (methodArgs == null) {
			return createResponseError(jsonRpc, id, JsonError.METHOD_PARAMS_INVALID);
		}
		try (InvokeListenerHandler handler = new InvokeListenerHandler(methodArgs, invocationListener)) {
			try {
				// 若设置预处理拦截器则会在此处拦截请求
				if (this.requestInterceptor != null) {
					this.requestInterceptor.interceptRequest(node);
				}
				// serviceName 其实就是我们通过@JsonRpcService设置的层级,在程序启动时会自动加载到内存当中
				Object target = getHandler(serviceName);
				// interceptors preHandle
				for (JsonRpcInterceptor interceptor : interceptorList) {
					interceptor.preHandle(target, methodArgs.method, methodArgs.arguments);
				}
				// invocation 做内部方法调用执行业务逻辑
				JsonNode result = invoke(target, methodArgs.method, methodArgs.arguments);
				handler.result = result;
				// interceptors postHandle 若设置post拦截器则会在此处拦截请求
				for (JsonRpcInterceptor interceptor : interceptorList) {
					interceptor.postHandle(target, methodArgs.method, methodArgs.arguments, result);
				}
				// 验证id不为空
				if (!isNotificationRequest(id)) {
					return createResponseSuccess(jsonRpc, id, handler.result);
				}
				return new JsonResponse(null, JsonError.OK.code);
			} catch (JsonParseException | JsonMappingException e) {
				throw e; // rethrow this, it will be handled as PARSE_ERROR later
			} catch (Throwable e) {
				handler.error = e;
				return handleError(id, jsonRpc, methodArgs, e);
			}
		}
	}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值