通过Filter将请求forwar到JFinal的Controller进行处理

 网站有一个特殊需要,要求对于所有的请求都返回相同的页面,因此开发 AppClientFilter 拦截所有请求

但是希望这样相同的页面通过 JFinal生成,请问是否如何实现?

PS:forward到jsp页面正常,但是JFinal Controller则报 404错误。

HttpServletRequest req = (HttpServletRequest) request;

//"/_tools/notify" = 404 error

String newUrl = contextPath + "/_tools/notify";//"/WEB-INF/pages/_main.jsp";

req.setAttribute("flag", "filter");

req.setAttribute("url", requestURL);

req.getRequestDispatcher(newUrl).forward(request, response);

解决问题的分隔线:

首先在Config配置Handler、路由

@Override
public void configRoute(Routes me) {
	me.add("/_tools/notify", HelloController.class, "/");// JFinal功能测试
	// 后台功能
	//me.add(new AdminRoutes());
}

@Override
public void configHandler(Handlers me) {
    String skipedUrlRegx = PropKit.get("except_urlpattern");
    Handler handler1 = StrKit.isBlank(skipedUrlRegx) ? new UrlSkipHandler("\\.css$|\\.js$|\\.jpg$|\\.gif$|\\.png$|\\.gzjs$|\\.gzcss", false) : new UrlSkipHandler(skipedUrlRegx, false);
    me.add(handler1); //过滤静态文件
    me.add(new ContextPathHandler("basePath")); //为FreeMarker添加应用根
me.add(new RootHandler());
}
/**
* 实现对所有的请求都返回相同的页面
* 
* @author 张宗荣
* 
*/
public class RootHandler extends Handler {

@Override
public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
String[] urlPara = { null };
Action action = JFinal.me().getAction(target, urlPara);

if (action == null) {
  // 先将 target 存起来,可在 controller 中通过getAttr("target")得到
  request.setAttribute("target", target);
  // 直接转发到 Controller.index();
  next.handle("/_tools/notify", request, response, isHandled);
} else {
  next.handle(target, request, response, isHandled);
}

}

}


评论区

JFinal

2016-10-11 18:00

web.xml 中还是正常按 jfinal 的配置,配置上 JFinalFilter,然后再创建一个可访问到的 Controller,假定访问到这个 Controller.index() 方法的路由是 "/"

接下来做一个 MyHandler,将所有请求转发给前面的 Controller.index();
class MyHandler extends Handler {
public void handle(target, req, res, isHandled) {
// 先将 target 存起来,可在 controller 中通过getAttr("target")得到
req.setAttribute("target", target);
// 直接转发到 Controller.index();
next.handle("/", req, res, isHandled);
}
}

JFinal

2016-10-11 18:03

此外 MyController 要注册路由,通过 me.add("/", MyController.class),MyHandler 也要注册一下 me.add(new MyHandler()),具体方法可以参考 jfinal 手册

通过以上方法进行的转发,可以在 MyController 中很方便的调用各种方法,例如 render(...)、renderJson()、getAttr("target")、getPara(...) 等等

cnzzr

2016-10-11 21:21

@JFinal 谢谢指导。
分享完整的Handler代码

@Override
public void configHandler(Handlers me) {
String skipedUrlRegx = PropKit.get("except_urlpattern");
Handler handler1 = StrKit.isBlank(skipedUrlRegx) ? new UrlSkipHandler("\\.css$|\\.js$|\\.jpg$|\\.gif$|\\.png$|\\.gzjs$|\\.gzcss", false) : new UrlSkipHandler(skipedUrlRegx, false);
me.add(handler1);

me.add(new ContextPathHandler("basePath"));
// me.add(new ViewAttrHandler());

me.add(new RootHandler());
}

/**
* 实现对所有的请求都返回相同的页面
*
* @author 张宗荣
*
*/
public class RootHandler extends Handler {

@Override
public void handle(String target, HttpServletRequest request, HttpServletResponse response, boolean[] isHandled) {
String[] urlPara = { null };
Action action = JFinal.me().getAction(target, urlPara);

if (action == null) {
// 先将 target 存起来,可在 controller 中通过getAttr("target")得到
request.setAttribute("target", target);
// 直接转发到 Controller.index();
next.handle("/_tools/notify", request, response, isHandled);
} else {
next.handle(target, request, response, isHandled);
}

}

}

JFinal

2016-10-11 21:25

@cnzzr 可以将这部分代码追加到贴子中,追加部分的前面说明一下是解决后的追加代码,因为回复功能不支持语法高亮显示,追加完后,可以再评论 @ 一下有需要的人就可以了,感谢支持