2012-08-17 67 views
0

我有一個Servlet類,它使用反射做一些動態類初始化和方法調用。它有以下代碼來做到這一點。Java反射不工作和獲取java.lang.NoSuchMethodException

@Override 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    try { 
     String reqActionContext = PageContextHelper.getFunctionName("login"); 
     // Trace reqActionContext 
     System.out .println("reqActionContext : " + reqActionContext); 
     // Get the page context related class object 
     Object contextClass = PageContextHelper.getContextBoundedClass("authentication"); 
     Class <?>[ ] paramTypes = new Class <?>[2]; 

     paramTypes[0] = HttpServletRequest.class ; 
     paramTypes[1] = HttpServletResponse.class ; 

     // Is there a class associated with the current context 
     if (contextClass != null) { 
      // Trace contextClassSystem. out .println("Contextclass : " + contextClass); 
      // get the Class 
      Class <?> thisClass = contextClass.getClass(); 
      // Trace thisClass 
      System.out .println("thisClass : " + thisClass); 
      // get the method 
      Method contextMethod = thisClass.getDeclaredMethod(reqActionContext, paramTypes); 

      if (contextMethod != null) { 
       contextMethod.invoke (contextClass, request, response); 
      } 
     } 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } catch (InvocationTargetException e) { 
     e.printStackTrace(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

其中獲得上下文界類具有以下代碼的類:
PageContextHelper.java

public class PageContextHelper { 

    private static final String CONTEXT_CLASS_SUFFIX = "ContextHelper" ; 

    private static final String CONTEXT_CLASS_PACKAGE = "com.proj.context." ; 

    /** 
    * Get the base path related context class object. 
    * 
    *@param basePath 
    *@return 
    */ 
    public static Object getContextBoundedClass (String basePath) { 
     Class <?> classOBJ = null ; 

     try{ 

      if(basePath != null && !basePath.isEmpty() && basePath.length() > 1) { 
       basePath = basePath .substring(0,1).toUpperCase() + basePath.substring(1).toLowerCase(); 
      } 
      // Get the class object 
      classOBJ = Class.forName(CONTEXT_CLASS_PACKAGE + basePath + CONTEXT_CLASS_SUFFIX); 
     } catch (ClassNotFoundException e) { 
      // Do nothing and return null object 
     } 
     return classOBJ; 
    } 

    ..... 

} 

這是尋找類是com.proj.context.AuthenticationContextHelper,它具有以下內容:
com.proj.context.AuthenticationContextHelper

package com.proj.context; 

    public class AuthenticationContextHelper{ 

    public void loginProcess (HttpServletRequest request, HttpServletResponse response) throws Exception { 
     try { 
      // Do some processing here 
     } catch (Exception e) { 
      // TODO : Remove this trace line and do something meaningful 
      e.printStackTrace(); 
     } 
    } 
} 

當我運行代碼得到下面的跟蹤:跟蹤

reqActionContext :loginProcess 
Contextclass : class com.proj.context.AuthenticationContextHelper 
thisClass : class java.lang.Class 
java.lang.NoSuchMethodException: java.lang.Class.loginProcess(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 
     at java.lang.Class.getDeclaredMethod(Class.java:1937) 
     at com.proj.servlet.ContentServlet.doGet(ContentServlet.java:81) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) 
     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
... 

它說NoSuchMethod但該方法存在的類com.proj.context.AuthenticationContextHelper

我是否在代碼中缺少任何基本的或錯誤的東西?

我使用的環境是的Java 1.6.0_32的Tomcat 7

回答

1

您從getContextBoundedClass()返回Class對象,並獲得該爲Object這裏:

Object contextClass = PageContextHelper.getContextBoundedClass("authentication"); 

而是這樣說:

Class contextClass = PageContextHelper.getContextBoundedClass("authentication"); 

你不要再打電話contextClass.getClass()。取而代之的是獲得一個類的實例,您可以調用contextClass.newInstance()來創建該對象的一個​​實例,並在調用該方法時使用該實例。閱讀本教程:

http://docs.oracle.com/javase/tutorial/reflect/index.html

+0

將'contextClass'引用更改爲類'Class'並調用'contextClass.newInstance()'解決了我的問題。 – 2012-08-17 06:31:41

1

在你doGet()方法,你必須:

contextMethod.invoke (contextClass, request, response); 

你傳遞一個contextClass這類型的類。您需要將該類的實例傳遞給您希望調用該方法的類,而不是該類的Class對象。不知道你在哪裏有AuthenticationContextHelper的實例,我沒有看到它在你的Servlet類中的任何地方。如果這是不可能的,你可以可能使loginProcess()方法靜態,然後將空對象傳遞到invoke(null, request, response)

classOBJ = Class.forName(CONTEXT_CLASS_PACKAGE + basePath + CONTEXT_CLASS_SUFFIX); 

當你嘗試:


的PageContextHelper.getContextBoundedClass方法調用的Class.forName

看起來它返回一個Class對象返回類AuthenticationContextHelper創建一個方法,您正在創建類Class上的方法,因爲您致電Class.getClass()。這就是爲什麼你會得到你的例外。看看你的輸出:

Contextclass : class com.proj.context.AuthenticationContextHelper 
thisClass : class java.lang.Class 

它們都是Class對象。

+0

的'PageContextHelper.getContextBoundedClass'方法通過調用'Class.forName'方法返回類'AuthenticationContextHelper'。 – 2012-08-17 05:17:50

+0

@ShanthaKumara這不是發生了什麼,請參閱我的答案中的編輯 – 2012-08-17 05:28:50

+0

您的觀點是正確的,@sethu的答案解決了我的問題。 – 2012-08-17 05:44:00