2021SC@SDUSC
分析前言
对于APIJSON的代码分析首先就是,看一下该项目的作用以及如何进行,看一下原来不部署这个项目的正常流程:
再来看一下部署上APIJSON后项目的流程走向:
接下来开始按照这个流程对相应的代码进行分析。
AbstractParser类(解析器)
将request解析为JSON对象
此次我们分析一下APIJSON的代码解析器——对应的项目类为AbstractParser
在 说明文档 中此类描述为 parser for parsing request to JSONObject,意思就是将request请求解析成为JSON对象,来看一下关键核心代码:
@Override
public String parse(String request) {
return JSON.toJSONString(parseResponse(request));
}
/*
*解析请求json并获取对应结果
*/
@NotNull
@Override
public String parse(JSONObject request) {
return JSON.toJSONString(parseResponse(request));
}
关键就是一个parse函数的调用将request转为固定的JSON类型的字符串,其中调用了parseResponse函数:
对于所用parseResponse函数:
public JSONObject parseResponse(String request) {
Log.d(TAG, "\n\n\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"
+ requestMethod + "/parseResponse request = \n" + request + "\n\n");
try {
requestObject = parseRequest(request); //解析为JSON对象,方便构造
} catch (Exception e) {
return newErrorResult(e);
}
return parseResponse(requestObject);//根据JSON请求对象,返回装配好的JSON响应对象
}
而parseResponse(String)函数则是将request通过parseRequest转化为JOSNObject,这个是为了以后方便构造,然后再返回调用parseResponse(JSONObject)方法得到的JSON响应对象
对于所用函数parseRequest:
/**解析请求JSONObject
* @param request => URLDecoder.decode(request, UTF_8);
*/
public static JSONObject parseRequest(String request) throws Exception {
JSONObject obj = JSON.parseObject(request);
if (obj == null) {
throw new UnsupportedEncodingException("JSON格式不合法!");
}
return obj;
}
就是调用了parseObject将String的request转化为JSONObject,并进行了异常处理
parseResponse(JSONObject)方法
而对于parseResponse(JSONObject)方法:这个方法就是去解析请求json并获取对应结果,什么意思呢?就是我现在已经经过前面的一系列操作获得了可以进行我们操作的request请求,然后我们的parseResponse就可以通过这个request从数据库中获取到所对应的内容返回了,如果还不理解的话,我直接举个例子,比如我们前端的请求是下面这样子:
"[]":{
"page":0,
"count":2,
"Moment":{
"content$":"%a%"
},
"User":{
"id@":"/Moment/userId", //User.id = Moment.userId 缺省引用赋值路径,从所处容器的父容器路径开始
"@column":"id,name,head" //指定返回字段
}
}
}
那么我们的结果就应该是
{
"[]":[
{
"Moment":{
"id":15,
"userId":70793,
"date":1486541171000,
"content":"APIJSON is a JSON Transmission Structure Protocol…",
"praiseUserIdList":[
82055,
82002,
82001
],
"pictureList":[
"http://static.oschina.net/uploads/user/1218/2437072_100.jpg?t=1461076033000",
"http://common.cnblogs.com/images/icon_weibo_24.png"
]
},
"User":{
"id":70793,
"name":"Strong",
"head":"http://static.oschina.net/uploads/user/585/1170143_50.jpg?t=1390226446000"
},
"Comment[]":[
{
"id":176,
"toId":166,
"userId":38710,
"momentId":15,
"date":1490444883000,
"content":"thank you"
},
{
"id":1490863469638,
"toId":0,
"userId":82002,
"momentId":15,
"date":1490863469000,
"content":"Just do it"
}
]
}
]
"code":200,
"msg":"success"
}
那么我们通过前面的一系列解析已经获得了这个请求的具体数据,然后我们接下来就是获取到数据库的中的request所请求的数据,这个例子中,首先就是"[]"表示就是去请求一个数组,然后是“page=0”和count=2是数组的条件,然后Moment代表//请求一个名为Moment的对象,括号里面代表的是moment对象的条件,根据这些条件,然后就把它转成相关的sql去执行获取到对应的数据。
然后来看一下这个方法具体的执行时是如何进行的:
/**
* @param request
* @return requestObject
*/
@NotNull
@Override
public JSONObject parseResponse(JSONObject request) {
requestObject = request;
verifier = createVerifier().setVisitor(getVisitor());
if (isNeedVerifyRole() && globleRole == null) {
try {
setGlobleRole(RequestRole.get(requestObject.getString(JSONRequest.KEY_ROLE)));
requestObject.remove(JSONRequest.KEY_ROLE);
} catch (Exception e) {
return extendErrorResult(requestObject, e);
}
}
final String requestString = JSON.toJSONString(request);//request传进去解析后已经变了
queryResultMap = new HashMap<String, Object>();
Exception error = null;
sqlExecutor = createSQLExecutor();
onBegin();
try {
queryDepth = 0;
requestObject = onObjectParse(request, null, null, null, false);
onCommit();
} catch (Exception e) {
e.printStackTrace();
error = e;
onRollback();
}
requestObject = error == null ? extendSuccessResult(requestObject) : extendErrorResult(requestObject, error);
JSONObject res = (globleFormat != null && globleFormat) && JSONResponse.isSuccess(requestObject) ? new JSONResponse(requestObject) : requestObject;
onClose();
return res;
}
首先就是进行了一个权限的判定,然后就直接调用了sqlconfig里面的方法,直接执行获取到了结果并且放入到JSONObject里面。
而JSON类的parseRequest函数最终是通过com.alibaba.fastjson的库函数最终将String转化为JSON类型的对象,而这个是涉及到了另外的项目,这也同时就让我们产生了一个疑问–不属于本项目但是和本项目息息相关的代码应该去分析吗?在我和我们小组进行讨论后,我们整个组觉得既然要分析整个项目,那么关联到本项目的一些额外的代码也应该去做一下合适的分析,以便于将我们的代码的上下文搞清楚,这个接下来会进行分析。
以上 为本次代码分析内容。
与小组成员讨论的扩展为:这次的分析我与讨论了一下不属于本项目的代码,但只要和本项目息息相关的代码也应该对其进行相关的分析,以便我们搞清楚本项目代码的上下文,这也更加便于我们进行后续代码的分析。因为代码分析课程其实不只是代码分析,更是让我们获得更多的学习机会,在代码分析的过程中,我们可以感受到前辈大牛们的代码严谨、思想深厚的理念,同时我们在分析时遇到的问题便可以让我们懂得更多,所以不应该局限于本项目的代码。