@Override
public String intercept(ActionInvocation ai) throws Exception {
Object action = ai.getAction();
System.out.println(action.getClass());//------------------------------------为什么此处得到的action名为com.accp.oa.web.action.LoginAction$$EnhancerByCGLIB$$9d32546b ,这个类名后面的是什么啊,怎么多了个这个 Field verifycodeField=action.getClass().getDeclaredField("type");
verifycodeField.setAccessible(true);
}struts

解决方案 »

  1.   

    想获得请求的类名需要调用上下文:invocation.getInvocationContext().getName();
      

  2.   

    想获得当前拦截的action实例使用invocation.getAction();
      

  3.   

    com.accp.oa.web.action.LoginAction$$EnhancerByCGLIB$$9d32546b 
    cglib代理类
      

  4.   


    怎么解决这个问题,我以前写的时候怎么没有后面这个
    现在只要这个com.accp.oa.web.action.LoginAction  怎么改
      

  5.   

    action.getClass()这个得到是个对象。
    可以这样用:
    action.getInvocationContext.getXXX,后面有各种方法
      

  6.   

    我想问的是:为什么我通过action.getClass()得到的类名是这个样子的,com.accp.oa.web.action.LoginAction$$EnhancerByCGLIB$$9d32546b 
    我把以前的项目拿出来运行了下,一摸一样写法,得到的应该是完整的包名加类名,现在怎么多了后面这个$$...这是什么原因导致的
      

  7.   


    下面是api说明
    Object
    public Object()
    Method Detail getClass
    public final Class<?> getClass()
    Returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class. 
    The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:Number n = 0; 
    Class<? extends Number> c = n.getClass(); 
    Returns:
    The Class object that represents the runtime class of this object.
    See Also:
    The Java Language Specification, Third Edition (15.8.2 Class Literals)
      

  8.   

    使用:ai.getProxy().getConfig().getClassName();
      

  9.   


    这个看不太懂
    能不能给我讲解下,我在书上看的,因为我后面要通过这个action的名字去获取里面的字段和方法,名字错了的话,后面根本拿不到。。
    万分感谢!!!
      

  10.   

    struts2将拦截器进行了代理,代理给了cglib,所以你直接getClass获得的是类代理,而不是本身。
    使用ai.getProxy().getConfig().getClassName()从代理的配置中获取实际的类。
      

  11.   


    你的invoction 是ActionInvocation 对象么
      

  12.   

    你看一下自己Console中打印的内容,你打印出来的class实体,不是我所获得的全路径类名String。
    在类没有被代理的情况下,你所获得的是一个全路径实体,要是被cglib代理了,那就是cglib代理实体,$$后面的你可以视为代理唯一标识。
    如果你想用getClass()的方式获取类名,就调用实体的getName()方法:invocation.getAction().getClass().getName()。
    另外,我的肯定是ActionInvocation的实例,实现了struts2拦截器接口的类,不会乱传的。
    最后,觉悟吧,骚年
      

  13.   


    这个不弄好,没心思吃饭啊,对了,
    刚忘了说,我前面都是用注解写的,而且整合了ssh,刚刚我单独用struts2写了一遍,发现没问题,整合了ssh再加注解,就出现这问题了,而且我刚用invocation.getAction().getClass().getName()后面还是带$$...这个,这什么原因啊
      

  14.   

    就是因为单独交给struts2的时候,是不使用代理的。
    委托给spring以后启用cglib代理了,所以会有$$。
      

  15.   

    你从代理的配置里获取不到静态的全路径类名?就是上面说的:ai.getProxy().getConfig().getClassName()
      

  16.   

    其实这样想获得类名也容易,反正是固定格式的,你喜欢这种形式,就用invocation.getAction().getClass().getName()获得了之后分割字符串就好:
    String className = "com.accp.oa.web.action.LoginAction$$EnhancerByCGLIB$$9d32546b ";
    System.out.println(className.split("\\${2}")[0]);
    split函数里的是正则表达式,两个连续$的意思。
      

  17.   

    $$EnhancerByCGLIB$$9d32546b表示是cglib的增强类,不是代理类,差别很大。
      

  18.   

    真的,你写的那些我都试过了,都还有$$..这个的,如果像24楼说的那样的话,应该像strungbuffer一样,能转回来的吧,不然增强类不是和你麻烦?
      

  19.   

    to huangfan575:
    我想你对cglib的理解还是有所偏差的,首先你说的没错,这是一种类增强,但是cglib的增强对象(Enhancer)正是用来设置被代理类的类。通过在增强类中配置需被代理类后,cglib会生成形如:com.accp.oa.web.action.LoginAction$$EnhancerByCGLIB$$9d32546b 形式的代理类,$$最前面是原始全路径类名,中间是对于生成代理的类的一种声明,由CGLIB的Enhancer来实现,然后最后是一个唯一标识,保证整个代理类名是唯一的。
    所以不是像你说的那样$$EnhancerByCGLIB$$9d32546b是一个增强类,它是一个代理类名整体的一部分罢了。 
      

  20.   

    CGLIB使用的是动态代理模式,也就是在运行时才会生成代理类啊,是一个运行实体,为了实现你的拦截大业的啊,骚年
      

  21.   

    呵呵,嗯,给力,不过还有个小问题,书上说自行拦截器是一个递归过程,
    if(rand.equals(verifycode)){
    ai.invoke();
    }
    //-------------
    ActionContext.getContext().put("msg", "验证码错误!");
    return "login";
    假如我现在上面的if判断为true,执行了ai.invoke();下面进入action了,最后会不会回来继续执行------下面的代码?
    我的疑问是,它不是递归执行的么,ai.invoke()是去执行下个拦截器,如果有下个拦截器的话,没有return,就继续执行,有return 就停掉了是不是这样理解的。。
      

  22.   

    你的求知欲真让我欲哭无泪啊,骚年。
    首先,如果为true了,也是会执行下面的方法的,骚年,ai.invoke();仅仅是一个字符串而已,除非写成return ai.invoke();下面才不会执行。
      

  23.   

    然后,所谓递归,你可以看一下拦截器拦截方法的结构:public String intercept(ActionInvocation invocation) throws Exception。这和action方法是一样的,事实上,你可以看成一系列嵌套的方法:
    public String intercept1()
    {
        public String intercept2()
        {
            public String intercept3()
            {
                public String intercept...()
                {
                     public String action方法()
                     {
                         return str;
                     }            }
            }
        }
    }
      

  24.   

    你在当前拦截器执行ai.invoke();的时候,并不是真的执行了action的方法,除非没有拦截器了,否则会另一个拦截器继续拦截,知道最后执行了action的方法,然后返回,就形成了这种实际上的结构。
    或者,在中间某个拦截器收你控制返回,那么不会最终执行action的方法。