Spring自定義MVC

541732025發表於2014-03-25
由於struts等開源MVC框架有漏洞,可以考慮自己實現一套輕量級的MVC框架
自定義一個Dispatcher,實現spring的ApplicationContextAware介面

點選(此處)摺疊或開啟

  1. public class AjaxDispatcher implements ApplicationContextAware {
  2.     //兩個最重要的容器,分別儲存請求path對應的method,以及請求path對應的bean。為了以後反射呼叫method.invoke(bean)
  3.     private static Map<String, Method> ajaxName2Method = new ConcurrentHashMap<String, Method>();
  4.     private static Map<String, Object> ajaxName2Bean = new ConcurrentHashMap<String, Object>();
  5.     ...
  6.     
  7.     @override
  8.     public void setApplicationContext(ApplicationContext ctx) throws BeansException {
  9.         Map<String, Object> map = ctx.getBeansWithAnnotation(AjaxClass.class);//要求每個Ajax類在宣告時會加上@AjaxClass,AjaxClass為自定義annotation
  10.         Collection<Object> beans = map.values();
  11.         for (Object bean : beans) {
  12.             logger.info(\"Inspecting AjaxClass: \" + bean.getClass());
  13.             registerAjaxClass(bean.getClass(), bean);
  14.         }
  15.     }

  16.     public static void registerAjaxClass(Class beanClass, Object bean) {
  17.         String prefix = ((AjaxClass) beanClass.getAnnotation(AjaxClass.class)).prefix();
  18.         if (prefix == null) {
  19.             prefix = \"\";
  20.         }
  21.         //將Ajax類的每個方法註冊到ajaxName2Method容器中
  22.         Method[] ms = beanClass.getMethods();
  23.         for (int j = 0; j < ms.length; j++) {
  24.             Method m = ms[j];
  25.         //跟AjaxClass一樣,Ajax類中的每個method也會宣告為AjaxMethod(自定義annotation,其中有path屬性)
  26.             AjaxMethod ajaxMethod = m.getAnnotation(AjaxMethod.class);
  27.             if (ajaxMethod != null) {
  28.                 String path = ajaxMethod.path();
  29.                 if (path == null || path.trim().equals(\"\")) {
  30.                     path = m.getName();
  31.                 }
  32.                 String fullPath = prefix + path;
  33.                 ajaxName2Method.put(fullPath, ms[j]);
  34.                 logger.info(\"Registering ajax method at path: \" + fullPath);
  35.                 ajaxName2Bean.put(fullPath, bean);
  36.             }
  37.         }
  38.     }

  39.     //業務邏輯呼叫,每一個請求都會呼叫該方法(web.xml中配置相應的servlet,servlet中呼叫該方法)
  40.     public static String dispatch(Map<String, String> req) throws Exception {
  41.         ObjectMapper mapper = new ObjectMapper();
  42.         String path = req.get(KEY_PATH);
  43.         Object ins = ajaxName2Bean.get(path);
  44.         Method m = ajaxName2Method.get(path);
  45.         if (m == null) {
  46.             logger.error(\"No matching method found for path: \" + path);
  47.             return METHOD_ERROR_RESPONSE;
  48.         }
  49.         Class<?>[] paramClasses = m.getParameterTypes();
  50.         Object[] paramValues = null;
  51.         if (null != paramClasses && 1 == paramClasses.length) {
  52.             paramValues = new Object[paramClasses.length];
  53.             try {
  54.                 paramValues[0] = Long.parseLong(req.get(KEY_USERID));
  55.             } catch (NumberFormatException e) {
  56.                 logger.error(\"userid incorrect\" + req.get(KEY_USERID), e);
  57.                 return PARAM_ERROR_RESPONSE;
  58.             }


  59.         } else if (null != paramClasses && 2 <= paramClasses.length) {
  60.             paramValues = new Object[paramClasses.length];
  61.             try {
  62.                 paramValues[0] = Long.parseLong(req.get(KEY_USERID));
  63.             } catch (NumberFormatException e) {
  64.                 logger.error(\"userid incorrect\" + req.get(KEY_USERID), e);
  65.                 return PARAM_ERROR_RESPONSE;
  66.             }


  67.             try {
  68.                 paramValues[1] = mapper.readValue(req.get(KEY_PARAM), paramClasses[1]);
  69.             } catch (Exception e) {
  70.                 logger.error(\"Can not deserialize json param \" + req.get(KEY_PARAM) + \" to class \" + paramClasses[1], e);
  71.                 return PARAM_ERROR_RESPONSE;
  72.             }
  73.         }

  74.         try {
  75.             Object result = m.invoke(ins, paramValues);
  76.             if (result instanceof String) {
  77.                 return (String) result;
  78.             } else {
  79.                 StringWriter buf = new StringWriter();
  80.                 mapper.writeValue(buf, result);
  81.                 return buf.toString();
  82.             }
  83.         } catch (Throwable e) {
  84.             logger.error(\"Exception occured when invoke Ajax Method, path=\" + path, e);
  85.             return DEFAULT_ERROR_RESPONSE;
  86.         }
  87.     }
  88. }

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28912557/viewspace-1129091/,如需轉載,請註明出處,否則將追究法律責任。

相關文章