在做程序过程中使用到了一个动态调用,具体的代码如下:
public static Object invokePrivateMethod(Object object, String methodName, Object params) throws NoSuchMethodException {
Assert.notNull(object);
Assert.hasText(methodName);
Class[] types = new Class[params.length];
for (int i = 0; i < params.length; i++) {
types[i] = params[i].getClass();
}
Class clazz = object.getClass();
Method method = null;
for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
method = superClass.getDeclaredMethod(methodName, types);
break;
} catch (NoSuchMethodException e) {
// 方法不在当前类定义,继续向上转型
}
}
if (method == null) {
throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + "." + methodName);
}
boolean accessible = method.isAccessible();
method.setAccessible(true);
Object result = null;
try {
result = method.invoke(object, params);
} catch (Exception e) {
ReflectionUtils.handleReflectionException(e);
}
method.setAccessible(accessible);
return result;
}
被调用的方法如下:
1 package com.test;
2
3 import javax.servlet.http.HttpServletRequest;
4
5 public class TestMethod {
6
7 public String loadParams(HttpServletRequest req,String test1,String test2){
8 return req.getParameter("username");
9 }
10
11 }
在servlet里面调用:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String v = (String) MethodUtils.invokeMethod("com.test.TestMethod", "loadParams", request, "1", "2");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
但是调用报错,提示:
java.lang.NoSuchMethodException: com.test.TestMethod.loadParams(org.apache.catalina.connector.RequestFacade, java.lang.String, java.lang.String)
at java.lang.Class.getMethod(Class.java:1605)
at com.test.MethodUtils.invokeMethod(MethodUtils.java:20)
at com.test.TestHelloWorld.doGet(TestHelloWorld.java:46)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Thread.java:619)
发现,request这个接口被tomcat实例化后,传入的是RequestFacade这个对象了,这样找不到对应的函数了。
不知道这种情况是如何处理,我简单的做了一个自己的对象,进行了包装,把request包装在里面,这样就可以。
但是,接口和实例应该是可以自由转换的,怎么不行呢?