如何用反射(或其他方法)得到方法参数的名称
请看如下代码(需求)
package com.servlet;
public class Controller
{
public String login(String username,String userpwd)
{
return null;
}
}public class LoginServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
{
Controller targetObj = new Controller();
Class<Controller> clazz = Controller.class;
Method[] methods = clazz.getMethods();
for(Method method : methods)
{
if("login".equals(method.getName()))
{
try
{
Class[] classs = method.getParameterTypes();
Object[] params = new Object[classs.length];
for(int i=0;i<classs.length;i++)
{
Class tempClazz = classs[i];
//[color=red]请问此处该如何得到login方法的参数字符串的名称(username,userpwd)[/color] //[color=red]我得到这两个字符串之后,直接用[/color]request.getParameter(username),request.getParameter(userpwd)
Array.set(params, i, request.getParameter("username"));
}
String result = method.invoke(targetObj, params).toString();
//do Other Thing
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
用注解应该能解决这问题把
以前用mybatis的时候,它好像就是这么处理map参数名的
[code="java"]
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Param {
String value();
}
[/code]
[code="java"]
import java.lang.reflect.Method;
public class ParameterAnnotation {
public static void main(String[] args) throws Exception {
Method method = ParameterAnnotation.class.getMethod(
"doSomething", Integer.class, String.class);
for (int i = 0; i < method.getParameterTypes().length; i++) {
Param param = (Param)method.getParameterAnnotations()[i][0];
System.out.printf("Parameter name #%d: %s\n", i, param.value());
}
}
public void doSomething(@Param("arg1")Integer arg1, @Param("arg2")String arg2) {
}
}
[/code]
lz可以看看这个
http://topic.csdn.net/u/20110212/09/f8f798dc-03a3-4bb7-afcc-7a74cbed2062.html
我的项目里的做法(包名和注释隐掉了,其它是直接的原本的代码):
[code="java"]import java.lang.reflect.Method;
import java.lang.reflect.Type;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
/**
@author sajia
*/
public class Methods {
private static final ParameterNameDiscoverer parameterNameDiscoverer
= new LocalVariableTableParameterNameDiscoverer();
// NOTE might go wrong if missing debug symbols
public static String[] getParameterNames(final Method method) {
return parameterNameDiscoverer.getParameterNames(method);
}
public static ParameterInfo[] getParameterInfos(final Method method) {
String[] paramNames = getParameterNames(method);
Type[] paramTypes = method.getGenericParameterTypes();
int paramCount = paramNames.length;
ParameterInfo[] paramInfos = new ParameterInfo[paramCount];
for (int i = 0; i < paramCount; i++) {
paramInfos[i] = ParameterInfo.of(paramNames[i], paramTypes[i], i);
}
return paramInfos;
}
}[/code]
上面这块是主要代码,间接依赖了ASM(Spring依赖ASM并包装了些方便的工具类)。如果目标方法关联的类的源码在用javac(或者其它Java源码编译器)编译的时候没有带上-g参数(或其它编译器指定输出调试符号信息的参数),那这个办法就行不通。它是靠ASM读取Class文件里的符号信息(“LocalVariableTable”)来获取信息的。
如果目标方法是一个接口上而不是一个类上的,那也是拿不到信息的。
[code="java"]import java.lang.reflect.Type;
import lombok.Data;
/**
[quote="java_web_hack3"]我就是想自己写,不依赖其他任何技术或框架。。。。
求思路或代码[/quote]
思路非常简单,如果你不想依赖任何外部库的话,自己写一个读取Class文件信息的程序,找到你要的方法关联的LocalVariableTable属性,它的头n条记录就是形式参数。
n是参数的个数,这个个数可以通过解析方法的签名来得到(或者当然,直接拿Method.getParameterTypes().length也行)
LocalVariableTableParameterNameDiscoverer
用annotion是好点 要不写那个太麻烦了...