zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    github上总结的python资源列表【转】
    Docker在windows下的使用【二】
    Docker在windows下的使用【一】
    RF环境安装-mac-osx10.10-基础环境-安装指南
    持续集成Jenkins+sonarqube部署教程
    微信朋友圈投票活动的刷票案例分析
    使用 Jenkins 搭建 iOS/Android 持续集成打包平台【转】
    unit3d 初次接触
    python pip 安装包报 编码问题
    深度学习 学习
  • 原文地址:https://www.cnblogs.com/chenny3/p/10226134.html
Copyright © 2011-2022 走看看