亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java中struts 框架的實現

2019-11-26 15:09:49
字體:
來源:轉載
供稿:網友

該文章主要簡單粗暴的實現了struts的請求轉發功能。 其他的功能后續會慢慢補上。

最近在學習javassist的內容,看到一篇文章  大家一起寫mvc  主要簡單的描述了mvc的工作流程,同時實現了簡單的struts2功能。

這里仿照的寫了個簡單的struts2框架,同時加上了自己的一些理解。

該文章主要簡單粗暴的實現了struts的請求轉發功能。 其他的功能后續會慢慢補上。

首先,在struts2框架中,請求的實現、跳轉主要是通過在struts.xml進行相關配置。 一個<action>標簽表示一個請求的定義,action中包含了①請求的名稱“name”;②請求對應的實現類“class” ;③同時還可通過“method”屬性自定義執行的方法,若沒配置默認執行execute0方法。<result》標簽定義了①結果的類型“name”,包括'SUCCESS'、'NONE'、'LOGIN'、'INPUT'、'ERROR';②請求的類型“type”,包括'dispatcher(默認)'、'chain'、'redirect'、'redirectAction'、'stream';③結果的跳轉。 在配置完struts.xml后,界面中的表單就可以通過action屬性與action定義的name屬性值相匹配找到對應的action標簽,從而找到對應的class以及執行的方法。再根據執行方法返回的string字符串同result標簽中的name相匹配,根據定義的type類型,進行下一步請求操作。

好了,在了解了struts2是怎么將界面請求同程序功能相連接后,我們通過自己的代碼來實現這部分的功能。

那么,我們該如何下手了?

我們將需要實現的功能簡單的分為兩部分 ①action部分 ②result部分

   action部分

       ①我們需要根據界面的請求找到對應的類以及執行的方法

    result部分

        ①我們需要根據方法執行的邏輯返回'SUCCESS'、'NONE'、'LOGIN'、'INPUT'、'ERROR'這類型的字符串
 
        ②需要對不同的返回類型,指定不同的下一步請求地址
 
        ③需要定義請求的類型,包括'dispatcher(默認)'、'chain'、'redirect'、'redirectAction'、'stream'

在本文章中,result的返回類型只實現了'SUCCESS'、'LOGIN'兩種,并且暫不考慮請求類型,實現的是默認的dispatcher請求轉發類型。完善的功能后期會再補充。

那么,下面我們來通過代碼看怎么實現如上功能。 

首先定義了ActionAnnotation和ResultAnnotation 兩個自定義注解來請求需要對應的方法以及方法返回的字符串對應的跳轉請求

 /**  * action注解:ActionName相當于web.xml配置中的url-pattern   * @author linling  *  */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ActionAnnotation {   String ActionName() default "";   ResultAnnotation[] results() default {}; }   /**    * 返回注解對象:name相當于struts配置中的result的name,包括'SUCCESS'、'NONE'、'ERROR'、'INPUT'、'LOGIN';value相當于struts配置中對應返回跳轉內容    * @author linling    *    */   @Retention(RetentionPolicy.RUNTIME)   @Target(ElementType.METHOD)   public @interface ResultAnnotation   {     ResultType name() default ResultType.SUCCESS;     String value() default "index.jsp";   }  

然后我們定義一個ActionContext類,來保存一個請求所需要的內容

 /**  * 實現模擬struts根據配置文件跳轉至action執行相應方法中需要的內容  * @author linling  *  */ public class ActionContext {   /**    * 相當于web.xml中url-pattern,唯一的    */   private String Url;       /**    * ActionAnnotation注解對應方法,也就是action中要執行的方法    */   private String method;       /**    * ActionAnnotation中的Result,對應action方法返回的類型。例如:key:'SUCCESS';value:'index.jsp'    */   private Map<ResultType, String> results;       /**    * action的類    */   private Class<?> classType;       /**    * action的對象    */   private Object action;       /**    * 方法參數類型    */   private Class<?>[] paramsType;       /**    * 方法參數的名稱,注意這里方法名稱需要和上面paramType參數一一對應    * 可以理解為是struts中action中的屬性    */   private String[] actionParamsName;       /**    * 本次請求的HttpServletRequest    */   private HttpServletRequest request;       /**    * 本次請求的HttpServletResponse    */   private HttpServletResponse response;   

analysePackage是在組裝ActionContext需要的方法

  /**      * 遍歷scan_package包下的class文件,將使用了ActionAnnotation注解的方法進行解析,組裝成ActionContext對象 并放入urlMap中      * @param real_path      * @param scan_package      * @throws ClassNotFoundException      * @throws InstantiationException      * @throws IllegalAccessException      * @throws NotFoundException      */     public static void analysePackage(String real_path, String scan_package) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NotFoundException     {       File file = new File(real_path);       if(file.isDirectory())       {         File[] files = file.listFiles();         for(File f : files)         {           analysePackage(f.getAbsolutePath(),scan_package);         }       }       else       {         String str = real_path.replaceAll("/", ".");         if (str.indexOf("classes." + scan_package) <= 0 || !str.endsWith(".class"))         {           return;         }         String fileName = str.substring(str.indexOf(scan_package),str.lastIndexOf(".class"));         Class<?> classType = Class.forName(fileName);         Method[] methods = classType.getMethods();         for(Method method : methods)         {           if(method.isAnnotationPresent(ActionAnnotation.class))           {             ActionContext actionContext = new ActionContext();             ActionAnnotation actionAnnotation = (ActionAnnotation)method.getAnnotation(ActionAnnotation.class);             String url = actionAnnotation.ActionName();             ResultAnnotation[] results = actionAnnotation.results();             if(url.isEmpty() || results.length < 1)             {               throw new RuntimeException("method annotation error! method:" + method + " , ActionName:" + url + " , result.length:" + results.length);             }             actionContext.setUrl(url);             actionContext.setMethod(method.getName());             Map<ResultType, String> map = new HashMap<ResultType, String>();             for(ResultAnnotation result : results)             {               String value = result.value();               if(value.isEmpty())               {                 throw new RuntimeException("Result name() is null");               }               map.put(result.name(), value);             }             actionContext.setResults(map);             actionContext.setClassType(classType);             actionContext.setAction(classType.newInstance());             actionContext.setParamsType(method.getParameterTypes());             actionContext.setActionParamsName(getActionParamsName(classType, method.getName()));             urlMap.put(url, actionContext);           }         }       }     }   

getParams是根據httpServletRequest請求中的請求內容獲得請求參數數組,該參數數組為調用方法體的參數內容

  /**      * 根據 參數類型parasType 和 參數名actinParamsName 來解析請求request 構建參數object[]      * @param request      * @param paramsType      * @param actionParamsName      * @return      * @throws InstantiationException      * @throws IllegalAccessException      * @throws IllegalArgumentException      * @throws InvocationTargetException      * @throws NoSuchMethodException      * @throws SecurityException      */     public static Object[] getParams(HttpServletRequest request, Class<?>[] paramsType, String[] actionParamsName) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException     {       Object[] objects = new Object[paramsType.length];       for(int i = 0; i < paramsType.length; i++)       {         Object object = null;         if(ParamsUtils.isBasicType(paramsType[i]))         {           objects[i] = ParamsUtils.getParam(request, paramsType[i], actionParamsName[i]);         }         else         {           Class<?> classType = paramsType[i];           object = classType.newInstance();           Field[] fields = classType.getDeclaredFields();           for(Field field : fields)           {             Map<String, String[]> map = request.getParameterMap();             for(Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();)             {               String key = iterator.next();               if(key.indexOf(".") <= 0)               {                 continue;               }               String[] strs = key.split("http://.");               if(strs.length != 2)               {                 continue;               }               if(!actionParamsName[i].equals(strs[0]))               {                 continue;               }               if(!field.getName().equals(strs[1]))               {                 continue;               }               String value = map.get(key)[0];               classType.getMethod(convertoFieldToSetMethod(field.getName()), field.getType()).invoke(object, value);               break;             }           }           objects[i] = object;         }       }       return objects;     }   

好了,接下來。我們可以來實現action方法了

  public class LoginAction   {     @ActionAnnotation(ActionName="login.action",results={@ResultAnnotation(name=ResultType.SUCCESS,value="index.jsp"),@ResultAnnotation(name=ResultType.LOGIN,value="login.jsp")})     public ResultType login(String name, String password)     {       if("hello".equals(name) && "world".equals(password))       {         return ResultType.SUCCESS;       }       return ResultType.LOGIN;     }           @ActionAnnotation(ActionName="loginForUser.action",results={@ResultAnnotation(name=ResultType.SUCCESS,value="index.jsp"),@ResultAnnotation(name=ResultType.LOGIN,value="login.jsp")})     public ResultType loginForUser(int number, LoginPojo loginPojo)     {       if("hello".equals(loginPojo.getUsername()) && "world".equals(loginPojo.getPassword()))       {         return ResultType.SUCCESS;       }       return ResultType.LOGIN;     }   }   

接下來,我們需要做的是讓程序在啟動的時候去遍歷工作目錄下所有類的方法,將使用了ActionAnnotation的方法找出來組裝成ActionContext,這就是我們請求需要執行的方法。這樣在請求到了的時候我們就可以根據請求的地址找到對應的ActionContext,并通過反射的機制進行方法的調用。
 
我們定了兩個Servlet。一個用于執行初始化程序。一個用來過濾所有的action請求

  <servlet>     <servlet-name>StrutsInitServlet</servlet-name>     <servlet-class>com.bayern.struts.one.servlet.StrutsInitServlet</servlet-class>     <init-param>       <param-name>scan_package</param-name>       <param-value>com.bayern.struts.one</param-value>     </init-param>     <load-on-startup>10</load-on-startup>    </servlet>         <servlet>     <servlet-name>DispatcherServlet</servlet-name>     <servlet-class>com.bayern.struts.one.servlet.DispatcherServlet</servlet-class>    </servlet>    <servlet-mapping>     <servlet-name>DispatcherServlet</servlet-name>     <url-pattern>*.action</url-pattern>    </servlet-mapping> 

DispatcherServlet實現了對所用action請求的過濾,并使之執行對應的action方法,以及進行下一步的跳轉

ublic void doPost(HttpServletRequest request, HttpServletResponse response)       throws ServletException, IOException   {       request.setCharacterEncoding("utf-8");     String url = request.getServletPath().substring(1);     ActionContext actionContext = DispatcherServletUtil.urlMap.get(url);     if(actionContext != null)     {       actionContext.setRequest(request);       actionContext.setResponse(response);       try       {         Object[] params = DispatcherServletUtil.getParams(request, actionContext.getParamsType(), actionContext.getActionParamsName());         Class<?> classType = actionContext.getClassType();         Method method = classType.getMethod(actionContext.getMethod(), actionContext.getParamsType());         ResultType result = (ResultType)method.invoke(actionContext.getAction(), params);         Map<ResultType,String> results = actionContext.getResults();         if(results.containsKey(result))         {           String toUrl = results.get(result);           request.getRequestDispatcher(toUrl).forward(request, response);         }         else         {           throw new RuntimeException("result is error! result:" + result);         }                 }  

好了,現在我們已經實現了最簡單的strut2框架的請求轉發的功能。功能寫得很粗糙,很多情況都還未考慮進來,希望大家多多指點~

以上所述就是本文的全部內容了,希望大家能夠喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
免费99精品国产自在在线| 在线观看日韩www视频免费| 欧美激情视频三区| 成人国产在线激情| 人妖精品videosex性欧美| 亚洲自拍偷拍在线| 国产精品jvid在线观看蜜臀| 久久久久久亚洲精品中文字幕| 中文字幕亚洲国产| 久久精品一本久久99精品| 国产精品久久久久一区二区| 丝袜亚洲另类欧美重口| 国内精品一区二区三区| 疯狂做受xxxx高潮欧美日本| 日韩中文字幕在线看| 欧美日韩亚洲天堂| 欧美大尺度在线观看| 亚洲的天堂在线中文字幕| 欧美午夜精品伦理| 亚洲乱亚洲乱妇无码| 深夜精品寂寞黄网站在线观看| 亚洲精品视频免费在线观看| 92看片淫黄大片看国产片| 成人久久精品视频| 亚洲一区二区免费在线| 欧美性xxxx极品hd欧美风情| 国产精品一区电影| 国产精品视频免费在线| 国产精品日韩欧美大师| 日韩免费不卡av| 不卡伊人av在线播放| 久久99久久久久久久噜噜| 国产精品久久久久999| 国产精品欧美一区二区| 动漫精品一区二区| 日韩欧美国产中文字幕| 国产精品免费看久久久香蕉| 97久久国产精品| 日韩激情av在线免费观看| 国产成人精品在线观看| 国产精品视频26uuu| 日韩精品欧美激情| 亚洲第一男人av| 日韩欧美在线国产| 国产乱人伦真实精品视频| 国产一区深夜福利| 亚洲a成v人在线观看| 精品国产区一区二区三区在线观看| 欧美乱妇高清无乱码| 91夜夜揉人人捏人人添红杏| 中文字幕精品国产| 亚洲激情在线观看视频免费| 亚洲电影成人av99爱色| 91亚洲精品久久久久久久久久久久| 国产精品欧美日韩| 在线播放国产一区中文字幕剧情欧美| 国产精品99久久99久久久二8| 欧美wwwwww| 亚洲天堂一区二区三区| 欧美日韩国产影院| 欧美第一黄色网| 国产在线视频2019最新视频| 97在线观看视频| 亚洲一区二区国产| 久久亚洲欧美日韩精品专区| 国产一区视频在线播放| 国产精品爽黄69| 国产女人18毛片水18精品| 精品人伦一区二区三区蜜桃免费| 国产精品视频专区| 日韩精品视频在线免费观看| 综合网日日天干夜夜久久| 国产精品永久免费| 日韩经典中文字幕在线观看| 亚洲国产天堂久久综合网| 中文字幕久久精品| 日韩电影免费观看中文字幕| 欧美专区在线播放| 亚洲一区美女视频在线观看免费| 国产成人精品综合久久久| 精品国偷自产在线视频| 91探花福利精品国产自产在线| 久久精品一偷一偷国产| 亚洲影院色无极综合| 宅男66日本亚洲欧美视频| 国产精品吹潮在线观看| 亚洲一区亚洲二区亚洲三区| 日韩电影在线观看中文字幕| 久久久久久国产精品久久| 亚洲一区二区三区乱码aⅴ蜜桃女| 97视频在线观看亚洲| 亚洲国产欧美一区二区丝袜黑人| 91精品国产综合久久香蕉922| 成人97在线观看视频| 久久人人97超碰精品888| 国产精品白丝jk喷水视频一区| 久久艹在线视频| 亚洲一区二区三区四区在线播放| 色哟哟入口国产精品| 91国产视频在线播放| 97国产精品视频| 欧美理论电影网| 成人美女av在线直播| 欧美激情成人在线视频| 成人亚洲综合色就1024| 久久综合国产精品台湾中文娱乐网| 国产欧美在线观看| 日韩电影中文字幕在线观看| 国产www精品| 亚洲国产精品va在线观看黑人| 久久噜噜噜精品国产亚洲综合| 久久国产精品久久国产精品| 成人精品视频久久久久| 国产午夜一区二区| 国产视频精品久久久| 韩国v欧美v日本v亚洲| 欧美国产欧美亚洲国产日韩mv天天看完整| 成年无码av片在线| 午夜精品一区二区三区在线| 国产一区二区丝袜高跟鞋图片| 国产91在线高潮白浆在线观看| 亚洲第一av在线| 日韩一区在线视频| 热久久美女精品天天吊色| 亚洲人成电影在线观看天堂色| 国产精品十八以下禁看| 午夜精品99久久免费| 久久久久久久久网站| 成人午夜在线观看| 高跟丝袜一区二区三区| 美日韩精品视频免费看| 亚洲欧美日韩视频一区| 久久久久北条麻妃免费看| 日韩中文字幕国产| 亚洲色图第一页| 日韩视频精品在线| 国产精品久久97| 国产成+人+综合+亚洲欧美丁香花| 日本精品久久久久影院| 伊人伊人伊人久久| 国产欧美在线播放| 一本一道久久a久久精品逆3p| 久久高清视频免费| 欧美大片在线免费观看| 97超视频免费观看| 亚洲最大福利网站| 91精品视频一区| 亚洲一级片在线看| 欧美一级片在线播放| 久久91亚洲精品中文字幕| 日本欧美中文字幕| 久久久久久国产| 久精品免费视频| 亚洲精品乱码久久久久久金桔影视| 欧美一性一乱一交一视频| 欧美日本国产在线| 欧美精品久久久久久久久| 不卡在线观看电视剧完整版| 欧美在线视频一区| 欧美高清自拍一区| 久久久久久久久久婷婷| 日韩大陆欧美高清视频区| 国产精品aaa| 欧美性猛交xxxx乱大交3|