0 Replies Latest reply on Feb 22, 2012 1:40 AM by jf321023

    Can the Interceptor change the intercepted method's return value?

    jf321023

      Hi, guys:

       

           I have a try to do with the Interceptor.  I want to intercepte the mothed and do some judgments , then invoke the mothed and change it's return value.

       

           In a practical application , such as  a delete button , I want to detemine whether to render it based on the role that the current user has.

       

           My some code follows:

       

           1. the page:

          

      <h:body>
                <h:form id="myform">
                          <h:commandButton id="test" value="Test" rendered="#{testAction.test(true)}" />
                </h:form>
      </h:body>
      
      

          

           2. the CDI bean

       

      @Model
      public class TestAction {
        
                @Role(roleName={"all","user"})
                public boolean test(boolean flag){
                          return flag;
                }
      }
      
      

       

           3. the interceptor binding type

       

      @InterceptorBinding
      @Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
      @Retention(RetentionPolicy.RUNTIME)
      public @interface Role {
                @Nonbinding String[] roleName() default {"all"};
      }
      
      

          

           4.the interceptor

       

      @Role @Interceptor  
      public class RoleInterceptor {
      
                @Inject private UserSession userSession;
        
                @AroundInvoke 
                public Object isUserHasRole(InvocationContext ctx){
                          try{
                                    System.out.println(FacesContext.getCurrentInstance().getCurrentPhaseId().toString());
                                    String[] roleNames = ctx.getMethod().getAnnotation(Role.class).roleName();
                                    System.out.println(roleNames[0]+roleNames[1]);
                                    System.out.println(userSession.getUsername());
                                      // TODO: do some judgments
                                    ctx.getMethod().invoke(ctx.getTarget(), new Object[]{false});
                                    Object o = ctx.proceed();
                                    return o;
                          }catch (Exception e) {
                                    // TODO: handle exception
                          }
                          return null;
                }
      }
      
      

       

           5. enable the interceptor in the         beans.xml

       

       <interceptors>
            <class>org.jboss.viewconfig.RoleInterceptor</class>
         </interceptors>
      
      

       

           Now, the are two problem .  First, the Interceptor  method will be invoked six times  and all the times in the RenderResponse phase.   I don't know why it be invoked six times in my code.

       

      Second, after the interceptor method return , the intercepted method will invoke one time.   so now i can't change the inercepthed method's return value with the Interceptor .    Can it be possable?  and how should i do?