国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java中struts 框架的實現

java中struts 框架的實現

2019-12-20 14:38hebedich JAVA教程

本文給大家介紹的是java中struts 框架的實現,有需要的小伙伴可以參考下。

該文章主要簡單粗暴的實現了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 兩個自定義注解來請求需要對應的方法以及方法返回的字符串對應的跳轉請求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
 * 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類,來保存一個請求所需要的內容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
 * 實現模擬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需要的方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
   * 遍歷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請求中的請求內容獲得請求參數數組,該參數數組為調用方法體的參數內容

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
   * 根據 參數類型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("\\.");
            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方法了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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請求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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方法,以及進行下一步的跳轉

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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框架的請求轉發的功能。功能寫得很粗糙,很多情況都還未考慮進來,希望大家多多指點~

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲www啪成人一区二区 | 亚洲一区二区三区高清 | 国产麻豆一区二区三区 | 亚洲一区二区三区高清 | 成人精品国产免费网站 | 视频一区在线播放 | 在线欧美视频 | 91精品国产乱码久久久久久 | 日韩欧美一级精品久久 | 亚洲欧美日韩精品久久奇米色影视 | 免费又黄又爽又猛的毛片 | 91麻豆精品国产91久久久更新资源速度超快 | 激情中文网 | 中国a一片一级一片 | 在线免费av观看 | 久久99国产精品久久99大师 | 91精品国产综合久久久久久 | 中文在线一区 | 亚洲成人av一区二区三区 | 日韩成人精品在线 | 国产精品99久久免费观看 | 毛片久久久 | 亚洲高清视频在线 | 日韩欧美视频一区二区 | 精品无人区一区二区三区动漫 | 免费观看aaa | 亚洲一区二区三区视频 | 精品国产乱码久久久久久牛牛 | 国产伦精品一区二区三区四区视频 | 国产黄色小视频在线观看 | 国产片av在线永久免费观看 | 欧洲免费视频 | 日韩一区二区精品 | 青青草成人在线 | 欧美精产国品一二三区 | 欧美日韩国产一区二区三区不卡 | 久久精品无码一区二区日韩av | 国产精品日本一区二区不卡视频 | 高清国产一区二区三区 | 久久一区二区三区四区 | 91精品国产综合久久福利软件 |