如何定制 fis3-jello

一、写在前面的

        fis3-jello 是基于 fis3 针对 jsp/velocity 模板的前端工程解决方案。github 地址为:https://github.com/fex-team/fis3-jello

        注意:fis3 对 Node 版本要求 0.8.x,0.10.x, 0.12.x,4.x,6.x,不在此列表中的版本不予支持。

        本文主要介绍如何在 fis3-jello 的基础上来添加自己的需求。

二、fis3-server-jello

        fis3-jello 具有很多特性,大多特性都是通过内嵌的 JavaEE 服务器实现的,例如模板继承、模板数据绑定。fis3-jello 在 release 时,会使用 fis3 提供的配置/接口将项目中相应的目录复制到内嵌服务器的目录中。我们在 release 后,可以通过命令 fis3 server open 打开服务器资源目录看到。

1. fis3 如何开发服务器插件

        fis3 中的服务器是通过独立的 npm 包来完成的,命名规范为 fis3-server-xxxx。而 fis3-jello 中的服务器对应的 npm 包为 fis3-server-jello。

        fis3-jello 打开内嵌服务器的命令为 fis3 server start --type jello,而该命令的执行模块为 fis3-command-server,该模块接收到 --type jello 参数后,通过 fis.require() 方法找到对应的服务器模块,之后调用 fis3-server-jello 模块中的 start 方法。

2. 结构

        fis3-server-jello 的 github 地址为:https://github.com/fex-team/fis3-server-jello。

        文件目录如下:

│ .gitignore
│ .npmignore
│ fis.keystore
│ index.js
│ LICENSE
│ package.json
│ README.md

└─vendor
        framework.tar
        server.jar
        server.js

3. 分析

       该插件的大致运行流程为,先检查计算机中是否配置 java 环境,代码如下:

function checkJavaEnable (opt, callback) {
    var javaVersion = false
    process.stdout.write('checking java support: ')
    var java = spawn('java', ['-version'])

    java.on('exit', function () {
        if (!javaVersion) {
            process.stdout.write('java not support!')
        }

        callback(javaVersion. opt)
    })
}

        接着解压 framework.tar 至系统临时目录下,最后构建 java 命令来执行 server.jar。

var markerFile = path.join(opt.root, 'WEB-INF', 'web.xml')
if (!fis.util.exists(markerFile)) {
    extract(path.join(__dirname, 'framework.tar'), opt.root, done)
} else {
    setTimeout(done, 200)  
}

        我反编译了 server.jar,看到主要就是使用 apache commons 将 tomcat embed 包装成一个命令工具,反编译得到的代码如下。

package com.baidu.fis.server.launch;

import java.io.File;
import java.io.PrintStream;
import org.apache.catalina.Server;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.cli.BasicParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;

public class Main
{
  public static int PORT = 8080;
  public static String BASE_DIR = null;
  public static String WEBAPP_DIR = "./web";
  public static String WEBAPP_PATH = "";
  public static Boolean HTTPS = Boolean.valueOf(false);
  
  public static void main(String[] args)
    throws Exception
  {
    System.setProperty("java.awt.headless", "true");
    
    Options options = new Options();
    
    options.addOption("h", "help", false, "output usage information");
    options.addOption("p", "port", true, "server listen port");
    options.addOption("base", true, "tomcat base dir");
    options.addOption("root", true, "document root");
    options.addOption("webapp", true, "webapp path");
    options.addOption("type", false, "useless just ignore it.");
    options.addOption("https", false, "https");
    
    HelpFormatter help = new HelpFormatter();
    BasicParser parser = new BasicParser();
    CommandLine cmd = parser.parse(options, args);
    if (cmd.hasOption("help"))
    {
      help.printHelp("assemble", options);
      return;
    }
    if (cmd.hasOption("port")) {
      PORT = Integer.valueOf(cmd.getOptionValue("port")).intValue();
    }
    if (cmd.hasOption("base")) {
      BASE_DIR = cmd.getOptionValue("base");
    } else if (BASE_DIR == null) {
      BASE_DIR = System.getProperty("java.io.tmpdir");
    }
    if (cmd.hasOption("root")) {
      WEBAPP_DIR = cmd.getOptionValue("root");
    }
    if (cmd.hasOption("webapp"))
    {
      WEBAPP_PATH = cmd.getOptionValue("webapp");
      if ((!WEBAPP_PATH.isEmpty()) && (!WEBAPP_PATH.startsWith("/"))) {
        WEBAPP_PATH = "/" + WEBAPP_PATH;
      }
    }
    if (cmd.hasOption("https")) {
      HTTPS = Boolean.valueOf(true);
    }
    startServer();
  }
  
  protected static void startServer()
  {
    Tomcat tomcat = new Tomcat();
    try
    {
      String base = new File(BASE_DIR).getCanonicalPath();
      String webapp = new File(WEBAPP_DIR).getCanonicalPath();
      
      tomcat.setBaseDir(base);
      Connector defaultConnector = tomcat.getConnector();
      
      defaultConnector.setPort(PORT);
      if (HTTPS.booleanValue())
      {
        System.out.println("Use HTTPS");
        
        System.out.println(System.getProperty("user.dir") + "/../fis.keystore");
        defaultConnector.setScheme("https");
        defaultConnector.setSecure(true);
        defaultConnector.setAttribute("keystoreFile", System.getProperty("user.dir") + "/../fis.keystore");
        defaultConnector.setAttribute("keystorePass", "123456");
        defaultConnector.setAttribute("clientAuth", "false");
        defaultConnector.setAttribute("sslProtocol", "TLS");
        defaultConnector.setAttribute("SSLEnabled", Boolean.valueOf(true));
      }
      tomcat.addWebapp(WEBAPP_PATH, webapp);
      
      tomcat.start();
      
      tomcat.getServer().await();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
}

       最后来看一下 framework.tar 文件,在执行 server.jar 之前,程序会解压 framework.tar 中的文件到指定的系统临时目录中。我们可以解压 framework.tar 文件,看到文件的目录结构如下:

├─META-INF
└─WEB-INF
    │  fis.tld
    │  tools.xml
    │  velocity.properties
    │  web.xml
    │
    ├─lib
    │      antlr-2.7.2.jar
    │      aopalliance-1.0.jar
    │      commons-beanutils-1.7.0.jar
    │      commons-chain-1.1.jar
    │      commons-collections-3.2.1.jar
    │      commons-digester-1.8.jar
    │      commons-fileupload-1.3.1.jar
    │      commons-io-2.4.jar
    │      commons-lang-2.4.jar
    │      commons-logging-1.1.jar
    │      commons-validator-1.3.1.jar
    │      dom4j-1.1.jar
    │      fastjson-1.1.41.jar
    │      fis-velocity-tools.jar
    │      jstl-1.2.jar
    │      oro-2.0.8.jar
    │      slf4j-api-1.7.7.jar
    │      spring-aop-3.2.10.RELEASE.jar
    │      spring-beans-3.2.10.RELEASE.jar
    │      spring-context-3.2.10.RELEASE.jar
    │      spring-core-3.2.10.RELEASE.jar
    │      spring-expression-3.2.10.RELEASE.jar
    │      spring-web-3.2.10.RELEASE.jar
    │      sslext-1.2-0.jar
    │      standard-1.1.2.jar
    │      struts-core-1.3.8.jar
    │      struts-taglib-1.3.8.jar
    │      struts-tiles-1.3.8.jar
    │      velocity-1.7.jar
    │      velocity-tools-2.0.jar
    │
    └─views
            index.vm

        这里最值得注意的就是 /WEB-INF/lib/fis-velocity-tools.jar,该 jar 包就是用来 fis3-jello 服务器中最主要的程序,其开源的工程git地址为:https://github.com/fex-team/fis-velocity-tools。我们可以通过修改该项目,来定制自己的特性。

三、fis-velocity-tools

1. 开发准备

        整个项目使用 maven 工具进行管理,为了使其在 tomcat 容器中运行以方便开发,我在 pom.xml 中添加了一个插件,如下:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>tomcat-maven-plugin</artifactId>
    <version>1.1</version>
    <configuration>
        <path>/wp</path>
        <port>8080</port>
        <uriEncoding>UTF-8</uriEncoding>
        <url>http://localhost:8080/</url>
        <server>tomcat6</server>
    </configuration>
</plugin>

 2. web.xml

        这个项目就是在开发一个 web 项目。

原文地址:https://www.cnblogs.com/SyMind/p/8611878.html