首先网上找不到webview的下载的demo,资料也很少,毕竟java不擅长桌面客户端所以资料比较少,所以这里就自己找了一下思路,实现了一下,有需要的可以参考一下;
或者推荐另外一个内嵌浏览器jbrowers,听说不错,不过要付费的,可以找破解版;
内嵌webview效果图:
webview下载图片:
webview下载的存放目录:
首先遇到的几个问题:
安全 ID 结构无效。
解决:这个是WpSystem这个目录是系统目录,所以报错了,自己新建个目录就可以了;
拒绝访问:
解决:这个问题一般是目录有问题或者语法调用有问题
简单的代码demo,不是最优的写法(存在很大优化空间),只是一个思路,具体优化就看自己的;
```java
package com.javafx;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.web.PopupFeatures;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.util.Callback;
public class Controller implements Initializable {
Executor excutor=Executors.newFixedThreadPool(3);
private boolean maybeCheckNeedDownLoad = false;
@FXML
private WebView webView;
@Override
public void initialize(URL location, ResourceBundle resources) {
// TODO Auto-generated method stub
final WebEngine webengine = webView.getEngine();
// String url =
// Main.class.getResource("/html/index.html").toExternalForm();
webengine.getLoadWorker().stateProperty()
.addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue ov, State oldState,
State newState) {
if (newState == Worker.State.SUCCEEDED) {
System.out.println("SUCCEEDED");
System.out.println(webengine.getLocation());
} else if (newState == Worker.State.SCHEDULED) {
System.out.println("SCHEDULED");
System.out.println(webengine.getLocation());
if (maybeCheckNeedDownLoad)
check(webengine.getLocation());
} else if (newState == Worker.State.CANCELLED) {
System.out.println("CANCELLED");
System.out.println(webengine.getLocation());
}
}
});
webengine
.setOnAlert((WebEvent<String> wEvent) -> {
System.out.println("Alert Event - Message: "
+ wEvent.getData());
});
webengine.setOnVisibilityChanged((WebEvent<Boolean> wEvent) -> {
System.out.println("Alert Event - Message: "
+ wEvent.getData());
});
webengine.setOnError((wEvent) -> {
System.out.println("Alert Event - Message: "
+ wEvent.getMessage()+"=="+wEvent.getException().toString());
});
webengine.setOnStatusChanged((WebEvent<String> wEvent) -> {
/* System.out.println(wEvent.getSource());
System.out.println(wEvent.getData());
System.out.println(wEvent.getEventType());*/
});
webengine
.setCreatePopupHandler(new Callback<PopupFeatures, WebEngine>() {
@Override
public WebEngine call(PopupFeatures config) {
// do something
// return a web engine for the new browser window
String url = webengine.getLocation();
System.out.println("PopupFeatures" + url);
maybeCheckNeedDownLoad = true;
return webengine;
}
});
//webengine.load("http://xiazai.zol.com.cn/down.php?softid=428055&subcateid=1443&site=10&checkStr=b59ee0b66cc7aae39&pos=dxgs2&rand=78ae0");
webengine.load("http://baidu.com/");
//webengine.load("http://local.dg.console.com:8081");
// webengine.load("http://local.dg.console.com:8081/api/export/exportStoreList?paramStr=%7B%22pageIndex%22:0,%22pageSize%22:0,%22conditions%22:%5B%7B%22type%22:%22simple%22,%22field%22:%22t.status%22,%22comparison%22:%22Eq%22,%22value%22:%22%22%7D,%7B%22type%22:%22keyword%22,%22field%22:%22t.store_name,t.boss_name%22,%22comparison%22:%22Like%22,%22value%22:%22%22%7D,%7B%22field%22:%22t.create_time%22,%22dateRange%22:%22UNLIMITED%22,%22type%22:%22dateRange%22,%22startDate%22:%22%22,%22endDate%22:%22%22%7D,%7B%22type%22:%22simple%22,%22field%22:%22t.state%22,%22comparison%22:%22Eq%22,%22value%22:%22%22%7D,%7B%22type%22:%22keyword%22,%22field%22:%22t.invite_phone%22,%22comparison%22:%22Like%22,%22value%22:%22%22%7D%5D,%22orders%22:%5B%7B%22field%22:%22t.create_time%22,%22direction%22:%22Desc%22%7D%5D,%22areaCode%22:%22%22,%22areaLevel%22:%22%22,%22paging%22:false%7D");
}
private void check(String url) {
maybeCheckNeedDownLoad = false;
System.out.println(url);
URL urlobj;
try {
urlobj = new URL(url);
HttpURLConnection urlconnection;
urlconnection = (HttpURLConnection) urlobj.openConnection();
urlconnection.setRequestMethod("GET");
urlconnection.connect();
Map headers = urlconnection.getHeaderFields();
Object connect_content = headers.get("Content-Disposition");
if (connect_content == null) {
connect_content = headers.get("content-disposition");
}
if (connect_content instanceof Collection) {
List<String> aa = (List<String>) connect_content;
String bb = aa.get(0);
System.out.println(bb);
if (bb.contains("attachment;")) {
excutor.execute(()->{
String kv[] = bb.split("filename=");
String filename= kv[kv.length - 1].replaceAll("\"","");
System.out.println("需要下载:" +filename);
saveFile(url,"E:\\test\\"+filename);
});
}
}
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return;
}
private void saveFile(String url,String saveFilePathTarget) {
URL uurl;
try {
uurl = new URL(url);
HttpURLConnection urlconnection=(HttpURLConnection) uurl.openConnection();
urlconnection.setRequestMethod("GET");//或者POST
File saveFile=new File(saveFilePathTarget);
urlconnection.connect();
if(!saveFile.exists()){
System.out.println("不存在");
//saveFile.mkdirs();
}
InputStream inputstream=urlconnection.getInputStream();
OutputStream out = new FileOutputStream(saveFile);
int size = 0;
int len = 0;
byte[] buf = new byte[1024];
while ((size = inputstream.read(buf)) != -1) {
len += size;
out.write(buf, 0, size);
}
inputstream.close();
out.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
总结:
1、这里因为是demo代码只要是提一下实现思路,实现功能为主,其他的优化自己优化:
a、webview的弹出窗口事件的监听;
b、webview判断url的类型是否是下载文件的响应;
c、是的话就下载;
目前测试的代码是标签的点击实现的下载,不支持window.open("下载url")的js事件;目前没去找原因是不是不识别window.open()方法,如果有知道的或者直接如何解决window.open()的可以通知一下本人,本人记录一下实现方案;