Java调用Lua脚本的通用工具类

Lua是一种小巧的脚本语言,java调用选用LuaJ实现

一、Java调用Lua脚本

1、引入luaj依赖

maven:

<!-- https://mvnrepository.com/artifact/org.luaj/luaj-jse -->
<dependency>
 <groupId>org.luaj</groupId>
 <artifactId>luaj-jse</artifactId>
 <version>3.0.1</version>
</dependency>
compile group: 'org.luaj', name: 'luaj-jse', version: "3.0.1"

2、工具类实现

public class LuaJUtils {
    private LuaJUtils() {}

    /**
     * 加载lua脚本获取LuaJ 的Globals对象,注意Globals不是线程安全的
     * @version 1.0
     * @since jdk1.8
     * @date 2021/1/2
     * @param filePath lua脚本的路径
     * @throws
     * @return org.luaj.vm2.Globals
     */
    public static Globals loadScriptFromFile(String filePath) {
        Globals globals = JsePlatform.standardGlobals();
        globals.loadfile(filePath).call();
        return globals;
    }

    /**
     * 调用lua脚本内的函数,并返回LuaValue值,如果返回为空,返回一个Nil的对象
     * @version 1.0
     * @since jdk1.8
     * @date 2021/1/2
     * @param globals
     * @param funcName 函数名称
     * @param luaValue 参数值,LuaValue对象,可以表示为基本数据类型、数组、对象等
     * @throws
     * @return org.luaj.vm2.LuaValue
     */
    public static LuaValue callFunction(Globals globals, String funcName, LuaValue luaValue) {

        LuaValue func = globals.get(LuaValue.valueOf(funcName));
        LuaValue result = func.call(luaValue);
        return result;
    }

    /**
     * 结果对象luavalue 与java对象的转换
     * @version 1.0
     * @since jdk1.8
     * @date 2021/1/2
     * @param luaValue
     * @param tClass java对象泛型
     * @throws
     * @return T
     */
    public static <T> T fromResult(LuaValue luaValue, Class<T> tClass) {
        return (T) CoerceLuaToJava.coerce(luaValue, tClass);
    }
}

3、测试Lua脚本

--无参函数
function hello()
print 'hello'
end

--带参函数,字符串
function test(str)
return '发过来的消息:' .. str
end

--带参函数,数组
function test2(str)
return '发过来的消息:' .. str[1]
end

4、单元测试

package com.iscas.common.lua.tools;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;

/**
 * LuaJ测试
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/1/2 18:01
 * @since jdk1.8
 */
@RunWith(JUnit4.class)
public class LuaJUtilsTests {
    @Test
    public void test() {
        String filePath = "C:\\Users\\m1531\\IdeaProjects\\newframe\\special\\common-lua-tools\\test.lua";
        Globals globals = LuaJUtils.loadScriptFromFile(filePath);

        //测试无参
        LuaJUtils.callFunction(globals, "hello", null);

        //测试字符串传参
        LuaValue luaValue = LuaJUtils.callFunction(globals, "test", LuaValue.valueOf("测试字符串传参"));
        String s = LuaJUtils.fromResult(luaValue, String.class);
        System.out.println(s);


        //测试数组传参
        LuaTable luaTable = new LuaTable();
        luaTable.set(1, "测试数组传参");
        LuaValue luaValue2 = LuaJUtils.callFunction(globals, "test2", luaTable);
        String s2 = LuaJUtils.fromResult(luaValue2, String.class);
        System.out.println(s2);

    }
}

二、Lua脚本调用Java函数
1、使用java编写一个类

package com.iscas.common.lua.tools.test;

/**
 * 测试Lua脚本调用java
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/1/2 18:22
 * @since jdk1.8
 */
public class TestLuaCallJava {

    public static String test(String arg1) {
//        System.out.println(arg1);
        return "传参为:" + arg1;
    }

    public String test2(String arg1) {
//        System.out.println(arg1);
        return "传参为:" + arg1;
    }
}

2、编辑lua调用脚本
两个函数代表两种调用方式

--在Lua中直接创建Java类的实例的方法:

function testCallJava1(str)
--使用luajava创建java类的实例(对象)
local testLuaCallJava = luajava.newInstance("com.iscas.common.lua.tools.test.TestLuaCallJava")
--调用对象方法
testLuaCallJava:test(str)
end


--在Lua中绑定Java类的方法:
function testCallJava2(str)
--使用luajava绑定一个java类
local testLuaCallJava = luajava.bindClass("com.iscas.common.lua.tools.test.TestLuaCallJava");
--调用类的静态方法/变量
testLuaCallJava:test(str)
-- 使用绑定类创建类的实例(对象)
local testLuaCallJava_instance = luajava.new(testLuaCallJava)
-- 调用对象方法
local result = testLuaCallJava_instance:test2(str .. 'world')
return result
end

3、单元测试

作为一种脚本语言,Lua没办法脱离高级语言而独立运行起来,使用Java来调用运行:

package com.iscas.common.lua.tools;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;

/**
 * 测试Lua调用Java
 *
 * @author zhuquanwen
 * @vesion 1.0
 * @date 2021/1/2 18:26
 * @since jdk1.8
 */
@RunWith(JUnit4.class)
public class LuaCallJavaTests {
    @Test
    public void test() {
        String filePath = "C:\\Users\\m1531\\IdeaProjects\\newframe\\special\\common-lua-tools\\luaCallJava.lua";
        Globals globals = LuaJUtils.loadScriptFromFile(filePath);

        //测试无参
        LuaJUtils.callFunction(globals, "testCallJava1", LuaValue.valueOf("hello"));

        LuaValue luaValue = LuaJUtils.callFunction(globals, "testCallJava2", LuaValue.valueOf("hello"));
        System.out.println(luaValue.toString());
    }
}

上一篇:PHP案例 ——音乐列表项目(下)


下一篇:[状压DP思路妙题]图