NutzCN Logo
问答 在AbstractProcessor 中设置request,并在jsp el中取值
发布于 2860天前 作者 threefish 1622 次浏览 复制 上一个帖子 下一个帖子
标签:

AbstractProcessor

@Override
    public void process(ActionContext ac) throws Throwable {
        ac.getRequest().setAttribute("test", "test");
        ac.getRequest().getSession().setAttribute("view", "view");
}

Module

  @GET
    @At("/test")
    @Ok("jsp:test")
    public void test() {
      Mvcs.getReq().setAttribute("main", "main");
    }

test jsp中

<body class="hold-transition ">
1:${main}
2:${test}
3:${view}
</body>

结果

1:main
2:
3:view

应该如何取得test值呢?感觉好像是执行顺序的原因导致取不到test值

20 回复

打印一下两个req的hashcode,看看是不是同一个对象

另外,为啥名字是AbstractProcessor?

hashcode是同一个

hashCode1:191217753
hashCode2:191217753

AbstractProcessor 是举个例子,这个不是真的类名

动作链的配置贴一下, 好神奇的样子, 入口方法内也getAttribute看看, process方法的完整内容也贴出来看看

var chain = {
    "default": {
        "ps": [
            "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
            "org.nutz.mvc.impl.processor.EncodingProcessor",
            "org.nutz.mvc.impl.processor.ModuleProcessor",
            "org.nutz.integration.shiro.NutShiroProcessor",
            "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
            "org.nutz.mvc.impl.processor.AdaptorProcessor",
            "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
            "org.nutz.mvc.impl.processor.ViewProcessor",
            "com.test.mvc.GlobalProcessor"
        ]
    }
};
public class GlobalProcessor extends AbstractProcessor {
    @Override
    public void process(ActionContext ac) throws Throwable {
            //执行目标方法
            doNext(ac);
            System.out.println("hashCode2:" + Mvcs.getReq().hashCode());
            Mvcs.getReq().setAttribute("test", "test");
            Mvcs.getReq().getSession().setAttribute("view", "view");
        
    }
}

@Ok是ViewProcessor执行的,把处理器放在它之前.

var chain = {
    "default": {
        "ps": [
            "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor",
            "org.nutz.mvc.impl.processor.EncodingProcessor",
            "org.nutz.mvc.impl.processor.ModuleProcessor",
            "org.nutz.integration.shiro.NutShiroProcessor",
            "org.nutz.mvc.impl.processor.ActionFiltersProcessor",
            "org.nutz.mvc.impl.processor.AdaptorProcessor",
            "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
            "com.test.mvc.GlobalProcessor",
            "org.nutz.mvc.impl.processor.ViewProcessor"
           
        ]
    }
};

还是ViewProcessor先执行 1.r.58版本

前后各放了一个还是ViewProcessor先执行

只需要放在ViewProcessor之前.

我猜GlobalProcessor根本没执行, debug一下吧

public class GlobalProcessor extends AbstractProcessor {
    @Override
    public void process(ActionContext ac) throws Throwable {
           
            System.out.println("hashCode2:" + Mvcs.getReq().hashCode());
            Mvcs.getReq().setAttribute("test", "test");
            Mvcs.getReq().getSession().setAttribute("view", "view");
 //执行目标方法
            doNext(ac);
        //只有这样才能实现我要的效果,但是我就是想放在后面
    }
}

全程使用的debug,确确实实的是ViewProcessor先执行后再执行的GlobalProcessor

是不是改了动作链文件没生效

启动时候会打印这样的日志, 看看里面的顺序

22:17:56.545 DEBUG (JsonActionChainMakerConfiguretion.java:37) <init> - ActionChain Config:
{
   "default": {
      "ps": ["net.wendal.nutzbook.common.mvc.LogTimeProcessor", "net.wendal.nutzbook.common.mvc.DailyUniqueUsersProcessor", "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor", "org.nutz.mvc.impl.processor.EncodingProcessor", "org.nutz.mvc.impl.processor.ModuleProcessor", "org.nutz.integration.shiro.NutShiroProcessor", "org.nutz.mvc.impl.processor.ActionFiltersProcessor", "org.nutz.mvc.impl.processor.AdaptorProcessor", "org.nutz.mvc.impl.processor.MethodInvokeProcessor", "org.nutz.mvc.impl.processor.ViewProcessor"],
      "error": "org.nutz.mvc.impl.processor.FailProcessor"
   }
}

日志是对的GlobalProcessor在ps数组第一位ViewProcessor在最后一位 与@wendal 你的日志相同

"GlobalProcessor在ps数组第一位"? 你之前给的配置不是这样的呢, 贴现在的配置和日志

2017-02-22 10:25:05 DEBUG JsonActionChainMakerConfiguretion:37 - ActionChain Config:
{
   "default": {
      "ps": ["com.test.mvc.GlobalProcessor", "org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor", "org.nutz.mvc.impl.processor.EncodingProcessor", "org.nutz.mvc.impl.processor.ModuleProcessor", "org.nutz.integration.shiro.NutShiroProcessor", "org.nutz.mvc.impl.processor.ActionFiltersProcessor", "org.nutz.mvc.impl.processor.AdaptorProcessor", "org.nutz.mvc.impl.processor.MethodInvokeProcessor", "org.nutz.mvc.impl.processor.ViewProcessor"],
      "error": "com.test.view.FailProcessor"
   }
}

我明白了, GlobalProcessor已经比ViewProcessor先执行.

doNext()是继续深入执行下一个处理器, 类似于过滤器的工作方式.

那段代码

public class GlobalProcessor extends AbstractProcessor {
    @Override
    public void process(ActionContext ac) throws Throwable {
           
            System.out.println("hashCode2:" + Mvcs.getReq().hashCode());
            Mvcs.getReq().setAttribute("test", "test");
            Mvcs.getReq().getSession().setAttribute("view", "view");
 //执行目标方法
            doNext(ac);
        //只有这样才能实现我要的效果,但是我就是想放在后面 . 
        // ********************** 为啥想放在最后 ************ 理由是啥?
    }
}

就是想在所有业务完成后,有一个统一的接口向request中放Attribute值

doNext的过程中,连view都渲染完了,放attribute有何意义?

所以说只有放在前面了@qq_4f9057d2

"业务完成之后", 假设页面无业务, 都在入口方法内完成, 那就放着MethodInvokeProcessor与ViewProcessor之间

ok可以了,放着MethodInvokeProcessor与ViewProcessor之间
感谢@wendal
解释下:第一步执行目标方法目标方法执行完毕后,第二步修改request,第三步执行视图渲染

 "org.nutz.mvc.impl.processor.MethodInvokeProcessor",
            "com.test.mvc.GlobalProcessor",
            "org.nutz.mvc.impl.processor.ViewProcessor"
@Override
    public void process(ActionContext ac) throws Throwable {
        ac.getRequest().setAttribute("test","test");
        doNext(ac);
    }
添加回复
请先登陆
回到顶部