Can anyone help me with this please?
I have a simple test Java servlet as shown below:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
byte[] bytes = ReadWaveformAsBinary();
response.setContentType("application/octet-stream");
response.setContentLength(bytes.length);
ServletOutputStream servletOutputStream = response.getOutputStream();
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
}
This function works. It returns a byte array with 10 double precision numbers in it. I know its all working because I can call it from a C# application as below:
public static bool CallWebServiceDownloadEndPoint(string szWebEndPoint, string szRequest, out double[] data)
{
data = null;
bool bSuccess = true;
WebClient webClient = new WebClient();
try
{
byte[] byteData = webClient.DownloadData(szWebEndPoint + "?" + szRequest);
Array.Reverse(byteData);
data = CreateDoubleArrayFromByteArray(byteData);
Array.Reverse(data);
}
catch
{
bSuccess = false;
}
return bSuccess;
}
The resultant byte array has the expected size of 80 bytes (10 * 8 bytes) and the 10 numbers are all as expected.
My question is, how can I call this Java servlet from JavaScript via an AJAX call?
For instance, I tried the following:
function AJAXSendString(ajaxRequestObject, szURL, szParams, OnCallCompleted)
{
if (ajaxRequestObject != null)
{
ajaxRequestObject.open("GET", szURL, true);
ajaxRequestObject.responseType = "arraybuffer";
ajaxRequestObject.onreadystatechange = function ()
{
if (ajaxRequestObject.readyState == 4)
{
if (ajaxRequestObject.status == 200)
{
var arrayBuffer = ajaxRequestObject.response;
if(arrayBuffer)
{
var byteArray = new Uint8Array(arrayBuffer);
alert(byteArray.byteLength);
}
}
}
}
ajaxRequestObject.send(szParams);
}
But the alert box says 19 (not 80 as I hoped it would).
Thanks for any help.
As suggested I try the following but I get the same result :(
function AJAXSendString2(ajaxRequestObject, szURL, szParams, OnCallCompleted)
{
if (ajaxRequestObject != null)
{
ajaxRequestObject.open("GET", szURL, true);
ajaxRequestObject.responseType = "arraybuffer";
ajaxRequestObject.onload = function(oEvent)
{
var arrayBuffer = ajaxRequestObject.response;
if(arrayBuffer)
{
var byteArray = new Uint8Array(arrayBuffer);
alert(byteArray.byteLength);
}
}
/*ajaxRequestObject.onreadystatechange = function ()
{
if (ajaxRequestObject.readyState == 4)
{
if (ajaxRequestObject.status == 200)
{
var arrayBuffer = ajaxRequestObject.response;
if(arrayBuffer)
{
var byteArray = new Uint8Array(arrayBuffer);
alert(byteArray.byteLength);
OnCallCompleted("1,-1,0,0,-1,1");
}
}
}
}*/
ajaxRequestObject.send(szParams);
}
}
I still see 19 and not 80.
You're attempting to send your parameters in the request body, since it is a GET request they should be in the url
ajaxRequestObject.open("GET", szURL+'?'+szParams, true);
You should use the "onload" event as in this example to get the complete payload/response.
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data
Related
I am trying to upload large binary files from a web client to a .NET 4.6.1 Framework MVC API. These files could range anywhere from 5GB to 20GB.
I have tried splitting the file into chunks to upload each chunk and merge the results at the end, but the merged file is always corrupted. If I work with small files and don't split, the binary will work correctly. However, when I split and merge the file is "corrupted". It won't load or behave as expected.
I have looked all over and haven't seen a proper solution to this so i'm hoping someone can help me here.
I followed this https://forums.asp.net/t/1742612.aspx?How+to+upload+a+big+file+in+Mvc, but I can't get it to work and the corrected solution was never posted. I am keeping track of the order of files before merging on the server.
Javascript (Call to uploadData is made to initiate)
function uploadComplete(file) {
var formData = new FormData();
formData.append('fileName', file.name);
formData.append('completed', true);
var xhr3 = new XMLHttpRequest();
xhr3.open("POST", "api/CompleteUpload", true); //combine the chunks together
xhr3.send(formData);
return;
}
function uploadData(item) {
var blob = item.zipFile;
var BYTES_PER_CHUNK = 750000000; // sample chunk sizes.
var SIZE = blob.size;
//upload content
var start = 0;
var end = BYTES_PER_CHUNK;
var completed = 0;
var count = SIZE % BYTES_PER_CHUNK == 0 ? SIZE / BYTES_PER_CHUNK : Math.floor(SIZE / BYTES_PER_CHUNK) + 1;
while (start < SIZE) {
var chunk = blob.slice(start, end);
var xhr = new XMLHttpRequest();
xhr.onload = function () {
completed = completed + 1;
if (completed === count) {
uploadComplete(item.zipFile);
}
};
xhr.open("POST", "/api/MultiUpload", true);
xhr.setRequestHeader("contentType", false);
xhr.setRequestHeader("processData", false);
xhr.send(chunk);
start = end;
end = start + BYTES_PER_CHUNK;
}
}
Server Controller
//global vars
public static List<string> myList = new List<string>();
[HttpPost]
[Route("CompleteUpload")]
public string CompleteUpload()
{
var request = HttpContext.Current.Request;
//verify all parameters were defined
var form = request.Form;
string fileName;
bool completed;
if (!string.IsNullOrEmpty(request.Form["fileName"]) &&
!string.IsNullOrEmpty(request.Form["completed"]))
{
fileName = request.Form["fileName"];
completed = bool.Parse(request.Form["completed"]);
}
else
{
return "Invalid upload request";
}
if (completed)
{
string path = HttpContext.Current.Server.MapPath("~/Data/uploads/Tamp");
string newpath = Path.Combine(path, fileName);
string[] filePaths = Directory.GetFiles(path);
foreach (string item in myList)
{
MergeFiles(newpath, item);
}
}
//Remove all items from list after request is done
myList.Clear();
return "success";
}
private static void MergeFiles(string file1, string file2)
{
FileStream fs1 = null;
FileStream fs2 = null;
try
{
fs1 = System.IO.File.Open(file1, FileMode.Append);
fs2 = System.IO.File.Open(file2, FileMode.Open);
byte[] fs2Content = new byte[fs2.Length];
fs2.Read(fs2Content, 0, (int)fs2.Length);
fs1.Write(fs2Content, 0, (int)fs2.Length);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + " : " + ex.StackTrace + " " + file2);
}
finally
{
if(fs1 != null) fs1.Close();
if (fs2 != null)
{
fs2.Close();
System.IO.File.Delete(file2);
}
}
}
[HttpPost]
[Route("MultiUpload")]
public string MultiUpload()
{
try
{
var request = HttpContext.Current.Request;
var chunks = request.InputStream;
string path = HttpContext.Current.Server.MapPath("~/Data/uploads/Tamp");
string fileName = Path.GetTempFileName();
string newpath = Path.Combine(path, fileName);
myList.Add(newpath);
using (System.IO.FileStream fs = System.IO.File.Create(newpath))
{
byte[] bytes = new byte[77570];
int bytesRead;
while ((bytesRead = request.InputStream.Read(bytes, 0, bytes.Length)) > 0)
{
fs.Write(bytes, 0, bytesRead);
}
}
return "test";
}
catch (Exception exception)
{
return exception.Message;
}
}
I've got a problem with my web-scraper. It should execute a javascript to make some changes on a webpage, then download the source and extract some specific data.
bool working = true;
for(int i = 0; i < urls.Count(); ++i)
{
working = true;
ChromiumWebBrowser scraper = new ChromiumWebBrowser(urls[i]);
scraper.FrameLoadEnd += scrape;
while(working)
{
Application.DoEvents();
System.Threading.Thread.Sleep(50);
}
}
async void scrape(object sender, FrameLoadEndEventArgs args)
{
ChromiumWebBrowser chrome = (ChromiumWebBrowser)sender;
if (args.Frame.IsMain && chrome.CanExecuteJavascriptInMainFrame)
{
string script = Properties.Resources.script;
chrome.ExecuteScriptAsync(script);
string data = " ";
do
{
string html = await chrome.GetSourceAsync();
string dataField = "data";
int dataFieldIndex = html.IndexOf(phoneField);
data = html.Substring(dataFieldIndex + dataField.Count(), html.IndexOf("<", dataFieldIndex + dataField.Count()) - dataFieldIndex - dataField.Count());
System.Threading.Thread.Sleep(50);
} while (data.Count() == 3);
addDataToHashSet(data);
}
else
{
Debug.WriteLine("Error");
}
}
private void addDataToHashSet(string data)
{
data = data.Replace("-", "");
data = data.Replace(" ", "");
dataHashSet.Add(data);
working = false;
}
Unfortunately, it's unpredictable. It hangs after few iterations - a proper event with CanExecuteJavascriptInMainFrame and IsMain is never triggered for some iterations. Could you explain it to me?
[edit]: My Cef initialization below:
CefSettings cefSettings = new CefSettings();
cefSettings.CefCommandLineArgs.Add("allow-running-insecure-content", "1");
cefSettings.IgnoreCertificateErrors = true;
CefSharpSettings.Proxy = new ProxyOptions(ip: "...", port: "...");
Cef.Initialize(cefSettings);
I am making Thumbnail View pages.
I stored thumbnail images external folder(C:/temp/image) and I get them from server as byte data.
now I want to convert this data into image in javascript and show in HTML.
so I tried to make blob URL using these byte data. But I got error "FILE NOT FOUND"
Here is my code. Please let me know what i'm missing
(It is Spring boot and angular.js )
Service
public List<Map<String, Object>> listRecentWithInfo( int userid) throws IOException, SerialException, SQLException {
List<Map<String, Object>> recentList = dashboardDao.listRecentWithInfo( userid);
for (Map<String, Object> map : recentList) {
int dashboardid = (int) map.get( "DASHBOARDID");
FileInputStream is = null;
BufferedImage bi = null;
ByteArrayOutputStream bao= null;
byte[] imageByte = null;
ResponseEntity<byte[]> res = null;
HttpHeaders headers = new HttpHeaders();
headers.setCacheControl(CacheControl.noCache().getHeaderValue());
if (thumbnailDao.findOne( dashboardid) != null) {
String path = thumbnailPath + thumbnailDao.getOne( dashboardid).getFileName();
is = new FileInputStream(path);
bi = ImageIO.read(is);
System.out.println(bi.getType());
bao = new ByteArrayOutputStream();
ImageIO.write(bi, "png", bao);
imageByte = bao.toByteArray();
res = new ResponseEntity<>(imageByte, headers, HttpStatus.OK);
}
map.put("THUMBNAIL", res);
}
return recentList;
}
js
$http.get("app/dashboard/recentWithInfo").then( function( rtn) {
rtn.data.map(item=> {
if (item.THUMBNAIL) {
var bytes = new Uint8Array(item.THUMBNAIL.body / 2);
for (var i = 0; i < item.THUMBNAIL.body; i += 2) {
bytes[i / 2] = parseInt(item.THUMBNAIL.body.substring(i, i + 2), /* base = */ 16);
}
// Make a Blob from the bytes
var blob = new Blob([bytes], {type: 'image/png'});
var imageUrl = URL.createObjectURL(blob);
URL.revokeObjectURL(imageUrl);
item.THUMBNAIL = imageUrl;
}
});
$scope.items = rtn.data;
console.log(rtn.data);
});
});
Thanks in advance!
I Got a solution By myself
I realized that I can convert Byte Data into Base64 just like that
"data:image/png;base64," + item.THUMBNAIL.body;
and this BASE64 encoded data can be used as Image source in HTML!
I am a beginner in socket.io. I have been used a library
https://www.npmjs.com/package/socket.io-stream
We were successfully uploaded images using the browser. But now, I want to upload images from android application. If anyone have android code please give me ..
https://github.com/socketio/socket.io-client-java/issues/29
I have been searching on google, but not found any proper solution.
var imageBuffer = customJs.decodeBase64Image(base64Data);
var imageTypeDetected = imageBuffer.type.match(/\/(.*?)$/);
var filename = 'profile-' + Date.now() + '.' + imageTypeDetected[1];
// config.uploadImage --- Folder path where you want to save.
var uploadedImagePath = config.uploadImage + filename;
try {
fs.writeFile(uploadedImagePath, imageBuffer.data, function () {
dbMongo.updateImage({email: decoded.email, user_id: decoded.userId, 'profile_picture': config.showImagePath + filename}, function (res) {
if (res.error) {
socket.emit('set_update_image', {'error': 1, 'message': 'Error!' + res.message, 'data': null, 'status': 400});
} else {
console.log(res);
socket.emit('set_update_image', res);
}
});
});
} catch (e) {
socket.emit('set_update_image', {'error': 1, 'message': 'Internal server error ' + e, 'data': null, 'status': 400});
}
From other file call a function
exports.decodeBase64Image = function decodeBase64Image(dataString) {
var matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
var response = {};
if (matches.length !== 3)
{
return new Error('Invalid input string');
}
response.type = matches[1];
response.data = new Buffer(matches[2], 'base64');
return response;
}
For the upload image from android using socket you need to send image as base64 string,
Following is the example for convert Image into base64 then you send data same as another paramaters.
String base64Image = getBase64Data(dirPath + "/" + fileName);
public String getBase64Data(String filePath) {
try {
InputStream inputStream = new FileInputStream(filePath);//You can get an inputStream using any IO API
byte[] bytes;
byte[] buffer = new byte[8192];
int bytesRead;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
while ((bytesRead = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
e.printStackTrace();
}
bytes = output.toByteArray();
return "data:image/jpeg;base64," + Base64.encodeToString(bytes, Base64.DEFAULT);
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
In android, you need to encode the image by using Base64
public void sendImage(String path)
{
JSONObject sendData = new JSONObject();
try{
sendData.put("imageData", encodeImage(path));
socket.emit("image",sendData);
}catch(JSONException e){
}
}
private String encodeImage(String path)
{
File imagefile = new File(path);
FileInputStream fis = null;
try{
fis = new FileInputStream(imagefile);
}catch(FileNotFoundException e){
e.printStackTrace();
}
Bitmap bm = BitmapFactory.decodeStream(fis);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,100,baos);
byte[] b = baos.toByteArray();
String encImage = Base64.encodeToString(b, Base64.DEFAULT);
//Base64.de
return encImage;
}
In server side, receive image and decode it
socket.on("image", function(info) {
var img = new Image();
img.src = 'data:image/jpeg;base64,' + info.imageData;
});
I have loaded a web page in BB as follow
//RegBrowserFieldConfig extends BrowserFieldConfig
RegBrowserFieldConfig regBrowserFieldConfig = new RegBrowserFieldConfig();
//RegBrowserFieldListener extends BrowserFieldListener
RegBrowserFieldListener regBrowserFieldListener = new RegBrowserFieldListener();
BrowserField registrationBrowserField = new BrowserField(regBrowserFieldConfig);
registrationBrowserField.addListener(regBrowserFieldListener);
add(registrationBrowserField);
registrationBrowserField.requestContent("http://myurl.com/");
That web page loads fine. There is a submit button in that web page which call onsubmit in the form element in HTML. That is calling to a JavaScript function. With in that function there are some other URL that will fire according to the requirements.
What I need is to get the response of those URL calls. How can I do that?
I tried this way..
BrowserFieldListener list = new BrowserFieldListener() {
public void documentLoaded(BrowserField browserField,
Document document) throws Exception {
String url = document.getBaseURI(); //u can get the current url here... u can use ur logic to get the url after clicking the submit button
Serverconnection(url);//from this methode u can get the response
}
};
browserField.addListener(list);
Serverconnection..
public String Serverconnection(String url) {
String line = "";
// if (DeviceInfo.isSimulator()) {
// url = url + ";deviceSide=true";
// } else {
// url = url + ";deviceSide=true";
// }
url = url + getConnectionString();
try {
HttpConnection s = (HttpConnection) Connector.open(url);
s.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
s.setRequestProperty(
"Accept",
"text/html,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");
s.setRequestProperty(HttpProtocolConstants.HEADER_ACCEPT_CHARSET,
"UTF-8");
s.setRequestMethod(HttpConnection.GET);
InputStream input = s.openInputStream();
byte[] data = new byte[10240];
int len = 0;
StringBuffer raw = new StringBuffer();
while (-1 != (len = input.read(data))) {
raw.append(new String(data, 0, len));
}
line = raw.toString();
input.close();
s.close();
} catch (Exception e) {
System.out.println("response--- excep" + line + e.getMessage());
}
return line;
}
EDIT..
private static String getConnectionString() {
String connectionString = "";
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
connectionString = "?;interface=wifi";
}
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
connectionString = "?;&deviceside=false";
} else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT) {
String carrierUid = getCarrierBIBSUid();
if (carrierUid == null) {
connectionString = "?;deviceside=true";
} else {
connectionString = "?;deviceside=false?;connectionUID="
+ carrierUid + "?;ConnectionType=mds-public";
}
} else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE) {
}
return connectionString;
}
private static String getCarrierBIBSUid() {
ServiceRecord[] records = ServiceBook.getSB().getRecords();
int currentRecord;
for (currentRecord = 0; currentRecord < records.length; currentRecord++) {
if (records[currentRecord].getCid().toLowerCase().equals("ippp")) {
if (records[currentRecord].getName().toLowerCase()
.indexOf("bibs") >= 0) {
return records[currentRecord].getUid();
}
}
}
return null;
}