• 3.7 render 方法
    • 1、render(String view)
    • 2、render(String view) 方法配置模板引擎
    • 3、render 系列其它方法
    • 4、定制 Controller.render 系方法的实现类

    3.7 render 方法

    1、render(String view)

    render(String view) 方法将对 view 所指向的模板进行渲染,view 参数最终指向的模板文件规则如下:

    1. String template = baseViewPath + viewPath + view

    其中 view 即为 render(String view) 方法所携带的参数值,而 baseViewPath、viewPath 则是在路由配置时指定的两个值,例如:

    1. public void configRoute(Routes me) {
    2. // baseViewPath 为 "/_view",该 Routes 对象之下映射的所有 Controller 都将取这个值
    3. me.setBaseViewPath("/_view");
    4.  
    5. // basePath 为第三个参数 "/index"
    6. me.add("/", IndexController.class, "/index");
    7.  
    8. // 第三个参数省略时, basePath 取第一个参数的值 : "/project"
    9. me.add("/project", ProjectController.class);
    10. }

    注意看上面的代码,其中的 me.setBaseViewPath(…) 指定的值即为 baseViewPath,其中 me.add(…) 第三个参数即为 viewPath,当第三个参数省略时默认取第一个参数的值。

    针对上述配置,在 IndexController 中使用 render 时的模板文件如下:

    1. public class IndexController extends Controller {
    2. public void demo() {
    3. // 模板指向 : "/_view/index/abc.html"
    4. render("abc.html");
    5. }
    6. }

    上述的 render("abc.html") 将指向 webapp 目录下面的 "/_view/index/abc.html" 这个模板。

    使用技巧:baseViewPath 配置为项目存放模板的总的根目录。viewPath 配置为当前被映射的 controller 的子目录。最终的效果就是 render(view) 的参数 view 永远是一个最终的文件名,例如: render("index.html"),从而消除掉了 view 参数中的目录部分。

    当需要打破 baseViewPath 与 viewPath 这两个参数的限制时,view 参数以 "/" 打头即可:

    1. render("/other_path/my_path/index.html");

    view 参数以 "/" 打头时,将勿略掉 baseViewPath 与 viewPath 这两个值:

    1. String template = "/other_path/my_path/index.html";

    2、render(String view) 方法配置模板引擎

    render(String view) 将根据 configConstant(Constants me) 中配置的 me.setViewType(ViewType) 方法选择一种模板引进渲染模板文件,例如:

    1. public void configConstant(Constants me) {
    2. me.setViewType(ViewType.JFINAL_TEMPLATE);
    3. }

    以上配置将选择 jfinal 内置的 enjoy 模板引擎渲染模板,该配置是默认值,在使用时无需配置。注意该配置仅仅针对 Controller.render(String view) 方法,其它 render 系方法完全不受影响。

    3、render 系列其它方法

    render系列方法将渲染不同类型的视图并返回给客户端。JFinal目前支持的视图类型有:JFinal Template、FreeMarker、JSP、Velocity、JSON、File、Text、Html、QrCode 二维码 等等。除了JFinal支持的视图型以外,还可以通过继承Render抽象类来无限扩展视图类型。

    通常情况下使用Controller.render(String)方法来渲染视图,使用Controller.render(String)时的视图类型由JFinalConfig.configConstant(Constants constants)配置中的constants. setViewType(ViewType)来决定,该设置方法支持的ViewType有:JFINAL_TEMPLATE、FreeMarker、JSP、Velocity,不进行配置时的缺省配置为JFINAL_TEMPLATE。

    此外,还可以通过 constants.setRenderFactory(RenderFactory)来设置Controller中所有render系列方法所使用的Render实现类。

    以上是 render 系方法使用例子:

    1. // 渲染名为test.html的视图,且视图类型为 JFinal Template
    2. renderTemplate(”test.html”);
    3.  
    4. // 生成二维码
    5. renderQrCode("content");
    6.  
    7. // 渲染名为test.html的视图,且视图类型为FreeMarker
    8. renderFreeMarker(”test.html”);
    9.  
    10. // 渲染名为test.html的视图,且视图类型为Velocity
    11. renderVelocity(“test.html”);
    12.  
    13. // 将所有setAttr(..)设置的变量转换成 json 并渲染
    14. renderJson();
    15.  
    16. // 以 "users" 为根,仅将 userList 中的数据转换成 json 并渲染
    17. renderJson(“users”, userList);
    18.  
    19. // 将user对象转换成 json 并渲染
    20. renderJson(user);
    21.  
    22. // 直接渲染 json 字符串
    23. renderJson("{\"age\":18}" );
    24.  
    25. // 仅将setAttr(“user”, user)与setAttr(“blog”, blog)设置的属性转换成json并渲染
    26. renderJson(new String[]{"user", "blog"});
    27.  
    28. // 渲染名为test.zip的文件,一般用于文件下载
    29. renderFile("test.zip");
    30.  
    31. // 渲染纯文本内容 "Hello JFinal"
    32. renderText("Hello JFinal");
    33.  
    34. // 渲染 Html 内容 "Hello Html"
    35. renderHtml("Hello Html");
    36.  
    37. // 渲染名为 test.html 的文件,且状态为 404
    38. renderError(404 , "test.html");
    39.  
    40. // 渲染名为 test.html 的文件,且状态为 500
    41. renderError(500 , "test.html");
    42.  
    43. // 不渲染,即不向客户端返回数据
    44. renderNull();
    45.  
    46. // 使用自定义的MyRender来渲染
    47. render(new MyRender());

    注意

    1:IE不支持contentType为application/json,在ajax上传文件完成后返回json时IE提示下载文件,解决办法是使用:render(new JsonRender().forIE())或者render(new JsonRender(params).forIE())。这种情况只出现在IE浏览器 ajax 文件上传,其它普通ajax请求不必理会。

    2:除renderError方法以外,在调用render系列的方法后程序并不会立即返回,如果需要立即返回需要使用return语句。在一个action中多次调用render方法只有最后一次有效。

    4、定制 Controller.render 系方法的实现类

    jfinal 提供了 RenderFactory 来定制 Controller.render 所有 render 方法的实现类,以下是定制 Controller.render(String view) 实现类的代码:

    1. // 定制一个 MyRender
    2. public class MyRender extends Render {
    3. ...
    4. }
    5.  
    6. // 扩展 RenderFactory,用于将 Controller.render(String view)
    7. // 切换到自己定制的 MyRender 上去
    8. public class MyRenderFactory extends RenderFactory {
    9. public Render getRender(String view) {
    10. return new MyRender(view);
    11. }
    12. }
    13.  
    14. // 配置生效
    15. public void configConstant(Constants me) {
    16. me.setRenderFactory(new MyRenderFactory());
    17. }

    以上代码中 MyRenderFactory.getRender(…) 方法重写了父类 RenderFactory.getRender(…) 方法,将切换掉 Controller.render(String view) 的实现类。同理,可以通过覆盖掉 getJsonRender() 来切换掉 Controller.renderJson()。 Controller 中所有 render 方法的实现类都可以通过这种方式来切换到自己的实现类上去,极度方便灵活,