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

  • 相关阅读:
    hdu acm 2844 Coins 解题报告
    hdu 1963 Investment 解题报告
    codeforces 454B. Little Pony and Sort by Shift 解题报告
    广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告
    hdu acm 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活
    hdu acm 1114 Piggy-Bank 解题报告
    poj 2531 Network Saboteur 解题报告
    数据库范式
    ngnix 配置CI框架 与 CI的简单使用
    Vundle的安装
  • 原文地址:https://www.cnblogs.com/chenny3/p/10226134.html
Copyright © 2011-2022 走看看