2012-09-13 52 views
3

我目前正在使用Java的一些web開發項目,我已經實現了一個前端控制器,其中的任務是實例化新的控制器,具體取決於路徑。java.lang.NoSuchMethodException與構造函數newInstance

那麼當用戶運行?q = user/login ex。前端控制器應該安裝UserController,我正在嘗試使用這段代碼。

String q = request.getParameter("q"); 

    try { 
     String[] page = q.split("/"); 
     // Make first char upper, to match class name conventions. 
     page[0] = (page[0].substring(0, 1).toUpperCase() + page[0].substring(1).toLowerCase()).trim(); 

     Class contDes = Class.forName("dk.elvar.rocks." + page[0]+ "Controller"); 
     Constructor co = contDes.getConstructor(); 
     co.newInstance(request, response, page); 

這導致

java.lang.NoSuchMethodException: dk.elvar.rocks.UserController.<init>() 
at java.lang.Class.getConstructor0(Class.java:2706) 
at java.lang.Class.getConstructor(Class.java:1657) 
at dk.elvar.rocks.FrontController.doGet(FrontController.java:35) 

我tryed尋找它在谷歌,和錯誤的,在聲明加載對象的構造,使課堂公開,已經存在。

UserController中:

public class UserController extends HttpServlet { 

private final String USERNAME = "Martin"; 
private final String PASSWORD = "David"; 

    private static final long serialVersionUID = 1L; 
HttpServletRequest request; 
HttpServletResponse response; 

public UserController(HttpServletRequest request, HttpServletResponse response, String[] action) { 
    this.request = request; 
    this.response = response; 

    if(action[1].equalsIgnoreCase("login")) { 
     this.renderLoginAction(); 
    } 
    if(action[1].equalsIgnoreCase("val-login")) { 
     this.validateLoginAction(); 
    } 
} 

回答

14

你可能會得到這個例外,因爲這個類沒有默認構造函數。你可以通過它們傳遞給getConstructor方法獲得一個帶參數的構造函數:

Constructor co = contDes.getConstructor(
       HttpServletRequest.class, 
       HttpServletResponse.class, 
       String[].class); 
co.newInstance(request, response, page); 
+0

謝謝你,這個完美的作品!然而,我不明白你的意思是一個默認的構造函數?我在UserController中定義了一個構造函數,我如何將其定義爲默認值? – MartinElvar

+2

@Martin Elvar Jensen沒有任何參數的構造函數是一個默認的構造函數。默認情況下,所有的java類都有默認的構造函數,但是當你用一些參數定義一個新的構造函數時,就會失去這個隱式的默認構造函數。 – basiljames

+1

謝謝@basiljames現在我完全理解:-) – MartinElvar

0

其一般不建議使用其他則默認構造函數,如web.xml文件或者struts-config.xml中使用實例化的servlet使用反射。

如果你想獲得比默認的構造函數之外的其他類的實例,

Class userController = Class.forName("<packages.>UserController"); 
Constructor userControllerConstructor = userController.class.getConstructor(HttpServletRequest.class, HttpServletResponse.class, String[].class); 
UserController userControllerObj = (UserController)constructor.newInstance(request,response, action); 
相關問題