JFinal 中使用 Dubbo —— 2 部署及运行

来源:互联网 发布:权力的游戏 三傻 知乎 编辑:程序博客网 时间:2024/06/10 21:26


  • 1. 部署及运行
  • 1.1. 部署
  • 1.2. 运行
  • 1.3. Druid监控
  • 1.4. 问题及解决方案
  • 1.4.1. Controller.getModel(class)问题

  • 1. 部署及运行

    1.1. 部署

    请参见“JFinal教程1——小白的第一个JFinal程序”(http://my.oschina.net/u/1175852/blog/261235)中的相关章节,部署应用到Tomcat的步骤讲得比较详细。部署后结构如下图:

     

    可以看到,ConsumerProvider都依赖Api项目。

     

    1.2. 运行

    ConsumerProvider无论谁先启动都可以,输入URL后,可以看到JFinal Demo原装页面了:

     

    查看管制台,Provider输出了数据操作的SQLActiveRecordPlugin.setShowSql(true)),

     

    页面和Provider都做出了期望的响应,整个Demo就此结束了吗!实际却不是,笔者在此处遇到好几个问题,后面将这些问题和解决方案一一道来。

     

    1.3. Druid监控

    通过Provider服务的“/druidaction可打开Druid监控页面:

     

    即使可以通过启动类将Provider做为一般Java应用启动,但还是将其建成Web项目,原因就在于只有Web项目可以打开Druid监控。对于开发者来说,Sql的执行效率数据很有用。

     

    1.4. 问题及解决方案

    1.4.1. Controller.getModel(class)问题

    Demo运行起来后,对Blog进行创建和修改操作时出现了“Html 500”的错误,Consumer中报错如下:

     

    Blog列表功、创建和修改都没有问题,唯独保存功能出现异常。

     

    通过调试,查到了问题的根源。在TableMapping中,与Blog表对应的Table数据中没有字段信息。因为字段信息是在ActiveRecordPlugin启动时通过TableBuilder从数据库中获取的。

    此问题在一年前向 @JFinal 提出过,问题地址为:http://www.oschina.net/question/1175852_149042

    解决方案有3种:

    1. 写个APIBlog表手动添加字段信息,也就说ConsumerProvider全部采用Model交互。

    2. 创建与Model对应的Java Bean,在Provider与数据库打交道时通过反射在ModelJava Bean之间转换,即采用Java Bean交互,但数据库操作还是使用ActiveRecordPlugin

    3. 放弃ActiveRecordPluginConsumerProvider全部采用Java Bean交互。数据库操作采用HibernateIbatisORM

     

    以上方案各有利弊,笔者为了修改量小,采用了第一种方案,即写了个API手动添加Blog表的字段信息。

    • 创建“com.jfinal.plugin.activerecord.TableInitKit.java”,名称空间是“com.jfinal.plugin.activerecord”,便于访问JFinalTableMapping的保护方法putTable()

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public final class TableInitKit {
     
        /**
         * 手动初始化Model对就的Table字段数据
         
         * @param tableName
         *            表名
         * @param modelClass
         *            model的Class
         * @param attrTypeMap
         *            字段类型Map
         */
        public static void init(String tableName, Class<? extends Model<?>> modelClass,
                Map<String, Class<?>> attrTypeMap) {
            init(tableName, "id", modelClass, attrTypeMap);
        }
     
        /**
         * 手动初始化Model对就的Table字段数据
         
         * @param tableName
         *            表名
         * @param primaryKey
         *            主键名
         * @param modelClass
         *            model的Class
         * @param attrTypeMap
         *            字段类型Map
         */
        public static void init(String tableName, String primaryKey,
                Class<? extends Model<?>> modelClass, Map<String, Class<?>> attrTypeMapTypeMap) {
            Table blogTable = new Table(tableName, primaryKey, modelClass);
            blogTable.setColumnTypeMap(attrTypeMapTypeMap);
     
            TableMapping.me().putTable(blogTable);
        }
    }
    • ConfigDemoConsumerConfig.afterJFinalStart()方法中添加如下代码:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Override
    public void afterJFinalStart() {
        Map<String, Class<?>> blogColumnMap = new HashMap<String, Class<?>>();
        blogColumnMap.put("id", Integer.class);
        blogColumnMap.put("title", String.class);
        blogColumnMap.put("content", String.class);
     
        TableInitKit.init("blog", Blog.class, blogColumnMap);
         
        System.out.println("Blog表字段模拟完成。");
         
        System.out.println("Demo consumer for Dubbo启动完成。");
    }

    重启Consumer之后,保存功能正常。至此,初步功能和架构已经完全能正常工作。

    Dubbo文档:

    Dubbo 的文档镜像



    0 0