最近,在开发过程中遇到了一个有趣的问题。该问题要求我在服务器端运行js文件,最开始我想当然的使用了ScriptEngineManager的java库。但在实际使用的过程中发现,这款js引擎并不支持jquery代码运行。(P.S.js引擎可以运行jquery兼容方案比较早,我目前没有找到更多的可行可行方法。)所以,我在后续的开发过程中选择使用selenium的webdriver控件,通过模拟网页访问,从而实现调用js功能。但是如果每次网络请求都需要重新启动webdirver,那么就会导致程序相应时间过长,综合上述问题,我最终选用单例线程池的方式实现webdirver的快速调用。
首先定义webdriver的线程池。
public class chormediverpool {
public ExecutorService fixedThreadPool;
private volatile static chormediverpool chormediverpool;
private chormediverpool (){
fixedThreadPool = Executors.newFixedThreadPool(5);
}
public static chormediverpool chormediverpool() {
if (chormediverpool == null) {
synchronized (chormediverpool.class) {
if (chormediverpool == null) {
chormediverpool = new chormediverpool();
}
}
}
return chormediverpool;
}
}
然后,在每次servlet接受请求的时候调用该单例线程池,利用threadlocal保存每个线程的webdriver从而保证项目可以快速调用js获取结果。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置返回格式
response.setContentType("text/plain; charset=utf-8");
//调用单例线程池
chormediverpool chormediverpool = service.chormediverpool.chormediverpool();
//调用线程池callbale函数
Future future =chormediverpool.fixedThreadPool.submit(new Callable() {
@Override
public Object call() throws Exception {
//根据threadlocal判断,存在即服用,不存在即创建
if (localVar.get() == null){
System.setProperty("webdriver.chrome.driver","d:/chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.setBinary("C:\\Users\\Administrator\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe");
ChromeDriver driver = new ChromeDriver(options);
Dimension dimension = new Dimension(1300, 800);
driver.manage().window().setSize(dimension);
localVar.set(driver);
driver.get(url);
String result = driver.getPageSource();
Pattern pattern = Pattern.compile("<body>.*</body>" );
Matcher matcher = pattern.matcher(result);
if (matcher.find()) {
String sign = matcher.group(0);
return sign.substring(6,sign.length()-7);
}else {
return "";
}
}else {
localVar.get().get(url);
String result = localVar.get().getPageSource();
Pattern pattern = Pattern.compile("<body>.*</body>" );
Matcher matcher = pattern.matcher(result);
if (matcher.find()) {
String sign = matcher.group(0);
return sign.substring(6,sign.length()-7);
}else {
return "";
}
}
return "";
}
});
try {
//返回相关数据
response.getWriter().print(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
通过这种方式就可以在服务端快速调用jquery代码。