Java如何优雅地执行js

简介: Java如何优雅地执行js


ScriptEngine


java从jdk1.6开始引入js引擎 ScriptEngine,从而支持执行js脚本,但是如果js脚本中包含一些浏览器内置对象,比如window对象,那么java在执行该脚本时会抛异常


Selenium?


selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,可以使用包括括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等浏览器,和用户自己操作浏览器一样。 可以作为web自动化测试工具,也可以作为第三方中介来执行一些java中执行不了的js代码


本文主要介绍 通过使用Selenium来让java 执行js方法


引入依赖


<dependency>

   <groupId>org.seleniumhq.selenium</groupId>

   <artifactId>selenium-java</artifactId>

   <version>4.0.0-alpha-5</version>

</dependency>


selenium 对应浏览器驱动下载


各浏览器下载地址:


Chrome浏览器驱动:chromedriver


Firefox浏览器驱动:geckodriver


还有其他的浏览器:IE浏览器驱动、Edge浏览器驱动、Opera浏览器驱动、hantomJS浏览器驱动,这边就具体举例了


注:下载的浏览器驱动 一定得和电脑中的浏览器 版本 符合


Selenium 简单例子


把相关驱动和依赖都配好后,我们先弄一个小例子来测试一下


@RestController

public class ThirdPartyController {


   @GetMapping("/thirdParty/test")

   public void test() throws FileNotFoundException {

       // chromedriver服务地址

       System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/src/main/resources/static/driver/"+ "chromedriver93.exe");

       // 1.创建webdriver驱动

       WebDriver driver = new ChromeDriver();

       // 2.打开百度首页

       driver.get("https://www.baidu.com");

       // 3.退出浏览器

       driver.quit();

   }


}


效果:浏览器会自动打开,并跳到百度


工具类


话不多说,直接上干货,将我们常用的方法抽出工具类,方便大家使用


package com.xiaoniu.blog.utils;


import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;


import java.io.BufferedReader;

import java.io.File;

import java.io.FileReader;

import java.io.IOException;


/**

* @Author: xiaoniuhululu.com

* @Date: 2021-12-28-23:37

* @Description: 执行js

* @Version 1.0 zhangjun

*/

public class JsExecutorUtils {

   //如果觉得文章对你有帮助,欢迎关注微信公众号:小牛呼噜噜

   static Logger logger = LoggerFactory.getLogger(JsExecutorUtils.class);


   /**

    * 不带 线程等待时间的 默认300毫秒

    * @param webDriver

    * @param js

    * @return

    */


   public static Object sendJS(WebDriver webDriver, String js){

       //  默认300 毫秒

       return sendJS(webDriver,js, 300);

   }


   /**

    * 带线程等待时间的,默认是第二个参数的   单位毫秒

    */


   public static Object sendJS(WebDriver webDriver,String js, int m){

       logger.info("执行JS==>>  "+js);

       Object object = ((JavascriptExecutor) webDriver).executeScript(js);

       try { Thread.sleep(m); }catch (Exception e){ }

       return object;

   }


   /**

    * 执行js文件(网上目前没有相关的可参考,自己就撸了一个,挺巧妙的--)

    * @param webDriver

    * @param fileName

    * @param funName

    * @param m

    * @param var2

    * @return

    * @throws IOException

    */

   public static String executeJsByFile(WebDriver webDriver, String fileName,String funName, int m, Object... var2) throws IOException {

       String result= "";

       StringBuilder script = new StringBuilder();

       File file = new File(System.getProperty("user.dir") + "/src/main/resources/static/js/"+ fileName+ ".js");

       FileReader filereader = new FileReader(file);

       BufferedReader bufferedReader = new BufferedReader(filereader);

       String tempString = null;

       while ((tempString = bufferedReader.readLine()) != null) {

           script.append(tempString).append("\n");

       }

       bufferedReader.close();

       filereader.close();


       String params="";

       if(var2.length > 0) {

           for(int i=0;i< var2.length;i++) {

               params = params + "arguments["+ i+ "]";

               if(i!= var2.length-1) {

                   params = params + ",";

               }

           }

       }

       String addStr = "return "+ funName+ "("+params+");";

       script.append(addStr);


       Object object_file = ((JavascriptExecutor) webDriver).executeScript(script.toString(), var2);

       try { Thread.sleep(m); }catch (Exception e){ }


       result = String.valueOf(object_file);

       return result;

   }


}


测试 :执行js


@SpringBootTest

public class DemoJsTests {


   @Test

   void contextLoads() {

       /**

        * 配置系统变量

        */

       System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/src/main/resources/static/driver/"+ "chromedriver96.exe");

       /**

        * 声明一个ChromeOptions变量,来控制 浏览器启动参数

        */

       ChromeOptions chromeOptions = new ChromeOptions();

       // 配置headless属性为true,无界面模式,表示不在前台打开chrome

       chromeOptions.setHeadless(true);


       /**

        *  创建webdriver驱动

        */

       WebDriver driver = new ChromeDriver(chromeOptions);

       String result = String.valueOf(JsExecutorUtils.sendJS(driver,"return 3+2"));

       System.out.println(result);


       //一定记得要及时 退出

       driver.quit();

       return;

   }


}


结果:

5

测试:执行JS文件


test.js

function sum(a, b) {

   return a+b;

}


function average(a, b, c) {

   return (a+b+c)/3;

}


function console() {

   return "test";

}


我们接着来测试一下,看看实战效果,将整个逻辑串一串

package com.xiaoniu.blog;


import com.xiaoniu.blog.utils.JsExecutorUtils;

import org.junit.jupiter.api.Test;

import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.chrome.ChromeOptions;

import org.springframework.boot.test.context.SpringBootTest;


import java.io.IOException;


@SpringBootTest

class BlogApplicationTests {


   @Test

   void contextLoads() {

       // chromedriver服务地址

       System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir") + "/src/main/resources/static/driver/"+ "chromedriver93.exe");


       /**

        * 声明一个ChromeOptions变量,来控制 浏览器启动参数

        */

       ChromeOptions chromeOptions = new ChromeOptions();

       // 配置headless属性为true,无界面模式,表示不在前台打开chrome

       chromeOptions.setHeadless(true);


       WebDriver driver = new ChromeDriver(chromeOptions);


       try {

           String result = JsExecutorUtils.executeJsByFile(driver,"test","sum",300, 8, 9);

           System.out.println("test:"+ result);


           String result2 = JsExecutorUtils.executeJsByFile(driver,"test","average",300, 1, 2,3);

           System.out.println("average:"+ result2);


           String result3 = JsExecutorUtils.executeJsByFile(driver,"test","console",300);

           System.out.println("console:"+ result3);



       } catch (IOException e) {

           e.printStackTrace();

       }

       //一定记得要及时 退出

       driver.quit();


   }


}


结果:


test:17


average:2


console:test


Selenium 操作页面

Selenium可以执行基本上所有 document,window,jquery等js相关操作,不像java的js引擎那样 限制重重


尾语

本文 主要是 将Selenium作为中介 ,让java执行js方法,其他的没有过多,但Selenium作为自动化测试框架,功能异常强大,本职功能可以写自动测试程序,但作用远不止如此,比如由于它可以模拟人去操作页面,能够操作iframe等平常技术难以操作的页面元素,可以当作超级爬虫,跨越网站的层层安全防护墙等等。


本篇文章到这里就结束啦,如果喜欢的话,多多支持,欢迎关注!更多精彩的文章

相关文章
|
6月前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的网上手机销售系统附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的网上手机销售系统附带文章和源代码设计说明文档ppt
67 0
|
30天前
|
缓存 JavaScript 前端开发
Java 如何确保 JS 不被缓存
【10月更文挑战第19天】在 Java 中,可以通过设置 HTTP 响应头来确保 JavaScript 文件不被浏览器缓存。方法包括:1. 使用 Servlet 设置响应头,通过 `doGet` 方法设置 `Expires`、`Cache-Control` 和 `Pragma` 头;2. 在 Spring Boot 中配置拦截器,通过 `NoCacheInterceptor` 类和 `WebConfig` 配置类实现相同功能。这两种方法都能确保每次请求都能获取到最新的 JavaScript 内容。
|
19天前
|
开发框架 JavaScript 前端开发
HarmonyOS UI开发:掌握ArkUI(包括Java UI和JS UI)进行界面开发
【10月更文挑战第22天】随着科技发展,操作系统呈现多元化趋势。华为推出的HarmonyOS以其全场景、多设备特性备受关注。本文介绍HarmonyOS的UI开发框架ArkUI,探讨Java UI和JS UI两种开发方式。Java UI适合复杂界面开发,性能较高;JS UI适合快速开发简单界面,跨平台性好。掌握ArkUI可高效打造符合用户需求的界面。
70 8
|
30天前
|
缓存 JavaScript 前端开发
Java 如何确保 JS 不被缓存
大家好,我是 V 哥。本文探讨了 Java 后端确保 JavaScript 不被缓存的问题,分析了文件更新后无法生效、前后端不一致、影响调试与开发及安全问题等场景,并提供了使用版本号、设置 HTTP 响应头、配置静态资源缓存策略和使用 ETag 等解决方案。最后讨论了缓存的合理使用及其平衡方法。
|
1月前
|
JavaScript Java
Java 控制台VUE.JS的使用
Java 控制台VUE.JS的使用
18 0
|
5月前
|
JavaScript 前端开发 Java
java 执行 javascript 代码
java 执行 javascript 代码
36 6
|
5月前
|
算法 JavaScript 前端开发
【经典算法】LCR187:破冰游戏(约瑟夫问题,Java/C/Python3/JavaScript实现含注释说明,Easy)
【经典算法】LCR187:破冰游戏(约瑟夫问题,Java/C/Python3/JavaScript实现含注释说明,Easy)
80 1
|
5月前
|
存储 JavaScript 前端开发
【经典算法】LeetCode350:两个数组的交集 II(Java/C/Python3/JavaScript实现含注释说明,Easy)
【经典算法】LeetCode350:两个数组的交集 II(Java/C/Python3/JavaScript实现含注释说明,Easy)
29 1
|
6月前
|
JavaScript Java 测试技术
Java项目基于ssm+vue.js的影视创作论坛附带文章和源代码设计说明文档ppt
Java项目基于ssm+vue.js的影视创作论坛附带文章和源代码设计说明文档ppt
39 0
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp小程序的java语言的考试信息报名系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp小程序的java语言的考试信息报名系统附带文章源码部署视频讲解等
51 0