【java神操作】java竟然还可以能执行Javascript代码!!

引入:闲着没事想研究下学校查成绩的接口,然后自己写程序查。但是查成绩首先必须登录,所以必须先研究学校网站的登录接口,抓包后发现传到后台的学号密码是经过加密的,研究其加密方法成为必经之路

发现学校网站改造升级后并没有以前想的那么破烂了。登录的账号和密码都通过js进行了编码,所以想通过程序模拟登录,必须弄清楚进行编码操作的js代码,然后最重要的是还要把它翻译成java代码,但是由于js和java的语法还是有差别,有些函数也不是那么通用,再用java写一遍感觉有点麻烦。于是想到java能不能执接执行js代码,这样我只要传一个学号,密码给编码函数就可以获得编码后的结果,省事又快!!于是发现java在1.6版本就提供了支持,真实神通广大啊。

1.首先把js代码写在conwork.js文件里

var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function encodeInp(input) {
    var output = "";
    var chr1, chr2, chr3 = "";
    var enc1, enc2, enc3, enc4 = "";
    var i = 0;
    do {
        chr1 = input.charCodeAt(i++);
        chr2 = input.charCodeAt(i++);
        chr3 = input.charCodeAt(i++);
        enc1 = chr1 >> 2;
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
        enc4 = chr3 & 63;
        if (isNaN(chr2)) {
            enc3 = enc4 = 64
        } else if (isNaN(chr3)) {
            enc4 = 64
        }
        output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
        chr1 = chr2 = chr3 = "";
        enc1 = enc2 = enc3 = enc4 = ""
    } while (i < input.length);
    return output
}

2.在java中定义一个接口,这个接口要有一个与要执行的javascript函数一样的方法签名。定义个Methods接口,内容如下:

package js;

/**
 * 接口中的方法签名必须与要执行的JavaScript方法一致
 */
public interface Methods {
    public String encodeInp(String input);
}

3.然后就开始跑咯!!

package js;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

public class ExecuteScript {
    public static void main(String[] args) {
        //创建一个脚本引擎管理器
        ScriptEngineManager manager = new ScriptEngineManager();
        //获取一个指定的名称的脚本引擎
        ScriptEngine engine = manager.getEngineByName("js");
        try {
            //获取当前类的所在目录的路径
            String path = ExecuteScript.class.getResource("").getPath();
            // FileReader的参数为所要执行的js文件的路径
            engine.eval(new FileReader(path + "conwork.js"));
            if (engine instanceof Invocable) {
                Invocable invocable = (Invocable) engine;
                //从脚本引擎中返回一个给定接口的实现
                Methods executeMethod = invocable.getInterface(Methods.class);
                //执行指定的js方法
                System.out.println(executeMethod.encodeInp("14142400755"));//
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这是java运行上述js代码,学号编码后的结果图
这里写图片描述


问题又来了。通过上面代码,我们每需要执行一个新的js方法就重复写第三步的代码,存在重复操作,我们完全可以把它抽取成通用的方法,这样我们只要给定一个指定的方法接口,就可以获得一个方法的实例,操作起来简直不要太方便!

package js;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

public class ExecuteScript {
    /**
     * 从给定的js文件中获取指定接口中的方法的实例
     * @param fileLoacation js文件路径
     * @param clazz 接口的class
     * @return 返回一个指定接口方法的实例
     */
    public <T> T getMethod (String fileLoacation,Class<T> clazz) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");
        try {
            String path = ExecuteScript.class.getResource("").getPath();
            System.out.println(path);
            // FileReader的参数为所要执行的js文件的路径
            engine.eval(new FileReader(fileLoacation));
            if (engine instanceof Invocable) {
                Invocable invocable = (Invocable) engine;
                T executeMethod = invocable.getInterface(clazz);
                return executeMethod;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

测试用例:

package js;

/**
 * Created by Administrator on 2017/7/2.
 */
public class Main {
    public static void main(String args[]){
        ExecuteScript executeScript = new ExecuteScript();
        String path=Main.class.getResource("").getPath();
        String fileLocation=path + "conwork.js";
        //通过下面一行代码就可以获取指定接口中方法的实例
        Methods method = executeScript.getMethod(fileLocation, Methods.class);
        String result=method.encodeInp("14142400755");
        System.out.println(result);

    }

}

相关文章链接:
1.Java执行JavaScript代码http://www.jb51.net/article/81577.htm

2.JAVA执行javascript方法http://blog.csdn.net/jianggujin/article/details/51046122

3.如何在java中调用js方法http://www.cnblogs.com/langtianya/archive/2012/09/18/2690860.html

posted @ 2017-07-02 20:24  键盘手小陈  阅读(283)  评论(0编辑  收藏  举报