PageRenderTime 720ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/resty-route/src/main/java/cn/dreampie/route/core/RouteInvocation.java

https://gitlab.com/xialeizhou/resty
Java | 331 lines | 267 code | 26 blank | 38 comment | 64 complexity | bed9c36ec8f1fa7bc6a6be2b04a78eae MD5 | raw file
  1. package cn.dreampie.route.core;
  2. import cn.dreampie.common.Entity;
  3. import cn.dreampie.common.http.HttpRequest;
  4. import cn.dreampie.common.http.HttpStatus;
  5. import cn.dreampie.common.http.exception.WebException;
  6. import cn.dreampie.common.util.HttpTyper;
  7. import cn.dreampie.common.util.json.Jsoner;
  8. import cn.dreampie.common.util.json.ModelDeserializer;
  9. import cn.dreampie.common.util.json.ObjectCastException;
  10. import cn.dreampie.common.util.stream.StreamReader;
  11. import cn.dreampie.log.Logger;
  12. import cn.dreampie.route.interceptor.Interceptor;
  13. import cn.dreampie.route.valid.Valid;
  14. import com.alibaba.fastjson.JSONArray;
  15. import com.alibaba.fastjson.JSONException;
  16. import java.io.IOException;
  17. import java.io.InputStream;
  18. import java.lang.reflect.InvocationTargetException;
  19. import java.lang.reflect.Method;
  20. import java.lang.reflect.ParameterizedType;
  21. import java.lang.reflect.Type;
  22. import java.util.*;
  23. /**
  24. * ActionInvocation invoke the action
  25. */
  26. public class RouteInvocation {
  27. private final static Logger logger = Logger.getLogger(RouteInvocation.class);
  28. private Route route;
  29. private RouteMatch routeMatch;
  30. private Interceptor[] interceptors;
  31. private int index = 0;
  32. // ActionInvocationWrapper need this constructor
  33. private RouteInvocation() {
  34. }
  35. public RouteInvocation(Route route, RouteMatch routeMatch) {
  36. this.route = route;
  37. this.routeMatch = routeMatch;
  38. this.interceptors = route.getInterceptors();
  39. }
  40. /**
  41. * Invoke the route.
  42. */
  43. public Object invoke() {
  44. Object result = null;
  45. if (index < interceptors.length)
  46. result = interceptors[index++].intercept(this);
  47. else if (index++ == interceptors.length) {
  48. Resource resource = null;
  49. try {
  50. resource = route.getResourceClass().newInstance();
  51. resource.setRouteMatch(routeMatch);
  52. //获取所有参数
  53. Params params = null;
  54. //if use application/json to post
  55. HttpRequest request = routeMatch.getRequest();
  56. //判断是否是application/json 传递数据的
  57. String contentType = request.getContentType();
  58. if (contentType != null && contentType.toLowerCase().contains(HttpTyper.ContentType.JSON.value())) {
  59. params = getJsonParams(request);
  60. } else {
  61. params = getFormParams();
  62. }
  63. //数据验证
  64. valid(params);
  65. //执行方法
  66. Object[] args = params.getValues();
  67. route.getMethod().setAccessible(true);
  68. result = route.getMethod().invoke(resource, args);
  69. } catch (ObjectCastException e) {
  70. logger.warn("Argument type convert error - " + e.getMessage());
  71. throw new WebException("Argument type convert error - " + e.getMessage());
  72. } catch (InvocationTargetException e) {
  73. Throwable target = e.getTargetException();
  74. if (target instanceof WebException) {
  75. throw (WebException) e.getTargetException();
  76. } else {
  77. logger.error("Route invocation error.", e);
  78. throw new WebException("Route invocation error - " + target.getMessage());
  79. }
  80. } catch (InstantiationException e) {
  81. logger.error("Resource instantiation error.", e);
  82. throw new WebException("Resource instantiation error - " + e.getMessage());
  83. } catch (IllegalAccessException e) {
  84. logger.error("Route method access error.", e);
  85. throw new WebException("Route method access error - " + e.getMessage());
  86. }
  87. }
  88. return result;
  89. }
  90. /**
  91. * 请求参数验证
  92. *
  93. * @param params 参数
  94. */
  95. private void valid(Params params) {
  96. Valid[] valids = route.getValids();
  97. if (valids.length > 0) {
  98. Map<String, Object> errors = new HashMap<String, Object>();
  99. HttpStatus status = HttpStatus.BAD_REQUEST;
  100. Valid valid;
  101. for (Valid v : valids) {
  102. valid = v.newInstance();
  103. //数据验证
  104. valid.valid(params);
  105. errors.putAll(valid.getErrors());
  106. if (!valid.getStatus().equals(status))
  107. status = v.getStatus();
  108. }
  109. if (errors.size() > 0) {
  110. throw new WebException(status, errors);
  111. }
  112. }
  113. }
  114. /**
  115. * 获取所有的请求参数
  116. *
  117. * @return 所有参数
  118. */
  119. private Params getFormParams() {
  120. Params params = new Params();
  121. int i = 0;
  122. Class paramType = null;
  123. List<String> valueArr = null;
  124. String value = null;
  125. List<String> allParamNames = route.getAllParamNames();
  126. List<String> pathParamNames = route.getPathParamNames();
  127. Object obj = null;
  128. for (String name : allParamNames) {
  129. paramType = route.getAllParamTypes().get(i);
  130. //path里的参数
  131. if (pathParamNames.contains(name)) {
  132. if (paramType == String.class) {
  133. params.set(name, routeMatch.getPathParam(name));
  134. } else
  135. params.set(name, Jsoner.parseObject(routeMatch.getPathParam(name), paramType));
  136. } else {//其他参数
  137. valueArr = routeMatch.getOtherParam(name);
  138. if (valueArr != null && valueArr.size() > 0) {
  139. //不支持数组参数
  140. value = valueArr.get(0);
  141. if (paramType == String.class) {
  142. params.set(name, value);
  143. } else {
  144. obj = Jsoner.parseObject(value, paramType);
  145. //转换为对应的对象类型
  146. parse(params, i, paramType, obj, name);
  147. }
  148. }
  149. }
  150. i++;
  151. }
  152. return params;
  153. }
  154. /**
  155. * 获取所有以application/json方式提交的数据
  156. *
  157. * @param request request对象
  158. * @return 所有参数
  159. */
  160. private Params getJsonParams(HttpRequest request) {
  161. Params params = new Params();
  162. InputStream is = null;
  163. int i = 0;
  164. Class paramType = null;
  165. List<String> allParamNames = route.getAllParamNames();
  166. List<String> pathParamNames = route.getPathParamNames();
  167. Object obj = null;
  168. String json = "";
  169. try {
  170. is = request.getContentStream();
  171. json = StreamReader.readString(is);
  172. } catch (IOException e) {
  173. String msg = "Could not read inputStream when contentType is application/json.";
  174. logger.error(msg, e);
  175. throw new WebException(msg);
  176. }
  177. boolean hasJsonParam = null != json && !"".equals(json);
  178. Map<String, Object> paramsMap = null;
  179. if (hasJsonParam) {
  180. paramsMap = Jsoner.parseObject(json, Map.class);
  181. hasJsonParam = paramsMap != null && paramsMap.size() > 0;
  182. }
  183. for (String name : allParamNames) {
  184. paramType = route.getAllParamTypes().get(i);
  185. //path里的参数
  186. if (pathParamNames.contains(name)) {
  187. if (paramType == String.class) {
  188. params.set(name, routeMatch.getPathParam(name));
  189. } else
  190. params.set(name, Jsoner.parseObject(routeMatch.getPathParam(name), paramType));
  191. } else {//其他参数
  192. if (hasJsonParam) {
  193. obj = paramsMap.get(name);
  194. if (paramType == String.class) {
  195. params.set(name, obj.toString());
  196. } else {
  197. //转换对象到指定的类型
  198. parse(params, i, paramType, obj, name);
  199. }
  200. }
  201. }
  202. i++;
  203. }
  204. return params;
  205. }
  206. private void parse(Params params, int i, Class paramType, Object obj, String name) {
  207. Type genericParamType;
  208. Class paramTypeClass;
  209. List<Map<String, Object>> list;
  210. List<Entity<?>> newlist;
  211. Entity<?> entity;
  212. JSONArray blist;
  213. List<?> newblist;
  214. Set<Entity<?>> newset;
  215. JSONArray bset;
  216. Set<?> newbset;
  217. if (obj.getClass().isAssignableFrom(paramType)) {
  218. params.set(name, obj);
  219. } else {
  220. //判断参数需要的类型
  221. //判断是不是包含 Entity类型
  222. try {
  223. if (Entity.class.isAssignableFrom(paramType)) {
  224. Entity<?> e = (Entity<?>) paramType.newInstance();
  225. e.putAttrs(ModelDeserializer.deserialze((Map<String, Object>) obj, paramType));
  226. params.set(name, e);
  227. } else {
  228. if (Collection.class.isAssignableFrom(paramType)) {
  229. genericParamType = route.getAllGenericParamTypes().get(i);
  230. paramTypeClass = (Class) ((ParameterizedType) genericParamType).getActualTypeArguments()[0];
  231. if (List.class.isAssignableFrom(paramType)) {
  232. list = (List<Map<String, Object>>) obj;
  233. //Entity类型
  234. if (Entity.class.isAssignableFrom(paramTypeClass)) {
  235. newlist = new ArrayList<Entity<?>>();
  236. for (Map<String, Object> mp : list) {
  237. entity = (Entity<?>) paramTypeClass.newInstance();
  238. entity.putAttrs(ModelDeserializer.deserialze(mp, paramTypeClass));
  239. newlist.add(entity);
  240. }
  241. params.set(name, newlist);
  242. } else {
  243. blist = (JSONArray) obj;
  244. if (String.class.isAssignableFrom(paramTypeClass)) {
  245. newblist = new ArrayList<String>();
  246. for (Object e : blist) {
  247. ((List<String>) newblist).add(e.toString());
  248. }
  249. } else {
  250. newblist = new ArrayList<Object>();
  251. for (Object e : blist) {
  252. if (e.getClass().isAssignableFrom(paramTypeClass))
  253. ((List<Object>) newblist).add(e);
  254. else
  255. ((List<Object>) newblist).add(Jsoner.parseObject(Jsoner.toJSONString(e), paramTypeClass));
  256. }
  257. }
  258. params.set(name, newblist);
  259. }
  260. } else if (Set.class.isAssignableFrom(paramType)) {
  261. //Entity
  262. if (Entity.class.isAssignableFrom(paramTypeClass)) {
  263. list = (List<Map<String, Object>>) obj;
  264. newset = new HashSet<Entity<?>>();
  265. for (Map<String, Object> mp : list) {
  266. entity = (Entity<?>) paramTypeClass.newInstance();
  267. entity.putAttrs(ModelDeserializer.deserialze(mp, paramTypeClass));
  268. newset.add(entity);
  269. }
  270. params.set(name, newset);
  271. } else {
  272. bset = (JSONArray) obj;
  273. if (String.class.isAssignableFrom(paramTypeClass)) {
  274. newbset = new HashSet<String>();
  275. for (Object e : bset) {
  276. ((Set<String>) newbset).add(e.toString());
  277. }
  278. } else {
  279. newbset = new HashSet<Object>();
  280. for (Object e : bset) {
  281. if (e.getClass().isAssignableFrom(paramTypeClass))
  282. ((Set<Object>) newbset).add(e);
  283. else
  284. ((Set<Object>) newbset).add(Jsoner.parseObject(Jsoner.toJSONString(e), paramTypeClass));
  285. }
  286. }
  287. params.set(name, newbset);
  288. }
  289. }
  290. } else {
  291. params.set(name, Jsoner.parseObject(Jsoner.toJSONString(obj), paramType));
  292. }
  293. }
  294. } catch (Exception e) {
  295. throw new JSONException("Unconvert type " + paramType, e);
  296. }
  297. }
  298. }
  299. public Method getMethod() {
  300. return route.getMethod();
  301. }
  302. public RouteMatch getRouteMatch() {
  303. return routeMatch;
  304. }
  305. }