I was trying to upload file in my web application using ajax and servlets.
My ajax code is something like this :
<script>
var client = new XMLHttpRequest();
function upload2() {
alert("in upload");
var file = document.getElementById("uploadfile");
/* Create a FormData instance */
var formData = new FormData();
/* Add the file */
formData.append("upload", file.files[0]);
client.open("post", "fileupload", true);
client.setRequestHeader("Content-Type", "multipart/form-data");
client.send(formData); /* Send to server */
}
/* Check the response status */
client.onreadystatechange = function () {
if (client.readyState == 4 && client.status == 200) {
alert(client.statusText);
}
}
</script>
My form is something like this :
<input type="file" name="uploadfile" id="uploadfile"/>
<input type="button" value="upload" name="upload" onclick="upload2()"/>
And my servlet that is being called in function is :
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
for (FileItem fi : upload.parseRequest(request)) {
if (fi.isFormField()) {
continue;
}
System.out.println("filename: " + fi.getName());
InputStream is = fi.getInputStream();
FileOutputStream fos = new FileOutputStream("C:\\Users\\admin\\Desktop\\SharedCrpto1\\web\\Files\\" + fi.getName());
int x = is.read();
while (x >= 0) {
fos.write((byte) x);
x = is.read();
System.out.println("reading");
}
}
But am getting an exception with this code :
org.apache.commons.fileupload.FileUploadException: the request was
rejected because no multipart boundary was found
The main problem I think is how to use the form data that has been formed by appending the file in my Servlet part.
My question is what is the cause of this exception?
Second question is how to modify my code so that I can upload multiple files at a time? Please help.
Related
I try to submit form data to google sheet via ajax but google script if else statement not work.
Below is the google script
// original from: http://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/
// original gist: https://gist.github.com/willpatera/ee41ae374d3c9839c2d6
// Enter sheet name where data is to be written below
var SHEET_NAME = "Records";
var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service
function doGet(e){
return handleResponse(e);
}
function handleResponse(e) {
// shortly after my original solution Google announced the LockService[1]
// this prevents concurrent access overwritting data
// [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html
// we want a public lock, one that locks for all invocations
var lock = LockService.getPublicLock();
lock.waitLock(30000); // wait 30 seconds before conceding defeat.
try {
// next set where we write the data - you could write to multiple/alternate destinations
var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));
var sheet = doc.getSheetByName(SHEET_NAME);
// we'll assume header is in row 1 but you can override with header_row in GET/POST data
var headRow = e.parameter.header_row || 1;
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var nextRow = sheet.getLastRow()+1; // get next row
var row = [];
// loop through the header columns
for (i in headers){
switch (headers[i]) {
case "Timestamp":
row.push(new Date());
break;
case "LogTime":
row.push(new Date());
break;
default:
row.push(e.parameter[headers[i]]);
break;
}
}
// more efficient to set values as [][] array than individually
sheet.appendRow(row);
// return json success results
return ContentService
.createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))
.setMimeType(ContentService.MimeType.JSON);
} catch(e){
// if error return this
return ContentService
.createTextOutput(JSON.stringify({"result":"error", "error": e}))
.setMimeType(ContentService.MimeType.JSON);
} finally { //release lock
lock.releaseLock();
}
}
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
SCRIPT_PROP.setProperty("key", doc.getId());
}
I submit the form data using ajax
HTML
<form id="checkin-form">
<input type="hidden" name="Event" value="<?php echo $events[1]; ?>"/>
<input type="hidden" name="LogTime" value="" />
...
</form>
Javascript
$('#checkin-form').on('submit', function(e) {
e.preventDefault();
var jqxhr = $.ajax({
crossDomain: true,
url: url,
method: "GET",
dataType: "json",
data: $("#checkin-form").serialize()
});
return false;
});
From google script, the column LogTime cannot get the Date() but keep empty. What is the possible issue?
Here is the google sheet column
Best regards,
Kelvin
Don't know why the google apps script does not work, finally, I found the article from https://medium.com/#dmccoy/how-to-submit-an-html-form-to-google-sheets-without-google-forms-b833952cc175, when I redo running the Setup function, everything works properly. The Setup function has already been run before and the script worked.
my code is for input
<input id="imgages" name="imgages" type="file" onchange="uploadFile()" />
and my script is :
function _(el) {
return document.getElementById(el);
}
function uploadFile() {
var file = _("imgages").files[0];
var formdata = new FormData();
formdata.append("imgages", file);
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.addEventListener("error", errorHandler, false);
ajax.addEventListener("abort", abortHandler, false);
ajax.open("POST", "file_upload_parser.php");
ajax.send(formdata);
}
function progressHandler(event) {
_("loaded_n_total").innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
var percent = (event.loaded / event.total) * 100;
_("progressBar").value = Math.round(percent);
_("status").innerHTML = Math.round(percent) + "% uploaded... please wait";
}
function completeHandler(event) {
_("status").innerHTML = event.target.responseText;
_("progressBar").value = 0; //wil clear progress bar after successful upload
}
function errorHandler(event) {
_("status").innerHTML = "Upload Failed";
}
function abortHandler(event) {
_("status").innerHTML = "Upload Aborted";
}
my problem is how can i chenge this part to use url for laravel and add csrf in this ajax part??
I mean I dont know how to add csrf token laravel in this script.
ajax.open("POST", "file_upload_parser.php");
You can add the csrf token in the head of your html ...
<meta name="csrf-token" content="{{ csrf_token() }}">
... and use formData.set('_token', document.querySelector('[name="csrf-token"]').getAttribute('content')) to send it with the request.
I found my problem
I have to add token after formdata.append("imgages", file);
formdata.append("imgages", file);
formdata.append("_token", '{{ csrf_token() }}');
and I add a route for store in host.
I am using struts2 framework on server side. I am uploading a file using
server side :
<s:file name="fTU" id="fTU"/>
<input type="submit" value ="ok" onclick="upload()">
client side :
function upload(){
var file = document.getElementById("fTU");
try {
this.xml = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
this.xml = new ActiveXObject("Microsoft.XMLHTTP");
} catch (err) {
this.xml = null;
}
}
if(!this.xml && typeof XMLHttpRequest != "undefined")
this.xml = new XMLHttpRequest();
if (!this.xml){
this.failed = true;
}
var formData = new FormData();
/* Add the file */
formData.append("upload", file.files[0]);
xml.open("POST", "", true);
xml.setRequestHeader("Content-Type", "false");
xml.send(formData); /* Send to server */
xml.onreadystatechange = function () {
if (xml.readyState == 4 && xml.status == 200) {
alert(xml.statusText);
}
}
}
How to fetch the uploaded file object on struts2 server side?
It is going in server side class and I am trying to retrieve file by using request.getParameter(upload) but it is giving null.
function upload(form){
var fd = new FormData(form);
$.ajax({
url : "<url-value>", //this is the actionName
type: "POST",
data: fd,
processData: false,
contentType: false,
success: function(data){
},
error: function(xhr, status, error){
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
});
return false;
}
I think you missed to add the Action Link in the xml.open() method. Take a look at the MDN to see some examples.
How does your Action-class look like? Have you defined a File field named upload with getter/setters?
Please also check, that your browser supports the FormData element, see question.
I also would suggest you to use a library like jQuery to simplify the Javascript code.
Action
public class FileUpload extends ActionSupport {
File myFile;
public String execute() {
//do some preparations for the upload
return SUCCESS;
}
public String upload() {
//only here the myFile is filled with data
return SUCCESS;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public File getMyFile() {
return myFile;
}
}
struts.xml
<!-- init method to show the form -->
<action name="fileForm" class="...FileUpload">
<result name="success">fileupload.jsp</result>
</action>
<!-- upload method to upload the file -->
<action name="fileUpload" class="...FileUpload" method="upload">
<result name="success">fileupload.jsp</result>
</action>
JSP
<s:form enctype="multipart/form-data" method="post" name="fileinfo" action="fileUpload">
<s:file name="myFile"/>
</s:form>
<input type="submit" onClick="upload()" value="OK">
Javascript (taken from the MDN example above)
function upload() {
var fd = new FormData(document.querySelector("form"));
$.ajax({
url : "fileUpload", //this is the actionName
type: "POST",
data: fd,
processData: false,
contentType: false
});
return false; //to stop submitting the form
}
I have not tested this code, so please change it or add comments if something doesn't work.
I'm performing AJAX using the following code:
function main() {
// get the name fields
var name1 = document.getElementById("name1").value;
var name2 = document.getElementById("name2").value;
// Encode the user's input as query parameters in a URL
var url = "response.php" +
"?name1=" + encodeURIComponent(name1) +
"&name2=" + encodeURIComponent(name2);
// Fetch the contents of that URL using the XMLHttpRequest object
var req = createXMLHttpRequestObject();
req.open("GET", url);
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
try {
// If we get here, we got a complete valid HTTP response
var response = req.responseText; // HTTP response as a string
var text = JSON.parse(response); // Parse it to a JS array
// Convert the array of text objects to a string of HTML
var list = "";
for (var i = 0; i < text.length; i++) {
list += "<li><p>" + text[i].reply + " " + text[i].name + "</p>";
}
// Display the HTML in the element from above.
var ad = document.getElementById("responseText");
ad.innerHTML = "<ul>" + list + "</ul>";
} catch (e) {
// display error message
alert("Error reading the response: " + e.toString());
}
} else {
// display status message
alert("There was a problem retrieving the data:\n" + req.statusText);
}
}
req.send(null);
}
// creates an XMLHttpRequest instance
function createXMLHttpRequestObject() {
// xmlHttp will store the reference to the XMLHttpRequest object
var xmlHttp;
// try to instantiate the native XMLHttpRequest object
try {
// create an XMLHttpRequest object
xmlHttp = new XMLHttpRequest();
} catch (e) {
// assume IE6 or older
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
} catch (e) {}
}
// return the created object or display an error message
if (!xmlHttp) alert("Error creating the XMLHttpRequest object.");
else return xmlHttp;
}
This works exactly as planned, the code within the try block is executed perfectly. But the alert "There was a problem retrieving the data: is also activated, with req.statusText displaying "OK".
How can this be possible? How can the code within the if statement activate perfectly but at the same time the else block is activated?
I'm stumped, any ideas?
The servor code is simply:
<?php
if( $_GET["name1"] || $_GET["name2"] ) {
$data = array(
array('name' => $_GET["name1"], 'reply' => 'hello'),
array('name' => $_GET["name2"], 'reply' => 'bye'),
);
echo json_encode($data);
}
?>
And the HTML:
<input id="name1">
<input id="name2">
<div id="responseText"></div>
<button onclick="main();">Do Ajax!</button>
Your conditional is probably being activated when req.readyState == 3 (content has begun to load). The onreadystatechange method may be triggered multiple times on the same request. You only care about what happens when it's 4, so refactor your method to only test when that is true:
var req = createXMLHttpRequestObject();
req.open("GET", url);
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
try {
// If we get here, we got a complete valid HTTP response
var response = req.responseText; // HTTP response as a string
var text = JSON.parse(response); // Parse it to a JS array
// Convert the array of text objects to a string of HTML
var list = "";
for (var i = 0; i < text.length; i++) {
list += "<li><p>" + text[i].reply + " " + text[i].name + "</p>";
}
// Display the HTML in the element from above.
var ad = document.getElementById("responseText");
ad.innerHTML = "<ul>" + list + "</ul>";
} catch(e) {
// display error message
alert("Error reading the response: " + e.toString());
}
} else {
// display status message
alert("There was a problem retrieving the data:\n" + req.statusText);
}
}
};
req.send(null);
Does anyone has a clean suggestion of instantiate this jquery's useful library.
I need to submit files and manage the Json response from the server.
I always get none json response within the Js code. I have reviewed some articles mentioning it but the code doesn't fit to the purpose.
The situation is: I achieve the submition and saving in the database but the Json response never arrives.
Thanks in advance.
This is my view code:
<script type="text/javascript">
$("#formUplImg").fileupload({
dataType: "json",
url:'#Url.Action("CreateJson","ProductImage")',
done: function (e, data) {
alert(data.StatusMessage);
}
});
</script>
#using (Html.BeginForm("CreateJson", "ProductImage", FormMethod.Post, new { id = "formUplImg", enctype = "multipart/form-data", #class = "jqtransform" }))
{
#Html.ValidationSummary(true)
<div class="rowElem">
<input type="file" id="Content" name="Content" />
</div>
<div class="rowElem">
#Html.ValidationMessageFor(item => item.Content)
</div>
<div class="rowElem">#Html.JQueryUI().Button("Guardar imagen", ButtonElement.Button, ButtonType.Submit, new { id = "guardar_imagen" })</div>
}
This is my controller action code:
[HttpPost]
public ContentResult CreateJson(UploadedFileInfo fileInfo)
{
try
{
if (fileInfo.Content == null)
throw new Exception("Hubo problemas con el envĂo. Seleccione un archivo a subir");
var file = new TempDocument
{
CreatedBy = User.Identity.Name,
CreationTime = DateTime.Now,
FileName = fileInfo.Content.FileName,
MimeType = fileInfo.Content.ContentType,
Size = fileInfo.Content.ContentLength,
Content = new byte[fileInfo.Content.ContentLength]//Image content to save
};
fileInfo.Content.InputStream.Read(file.Content, 0, fileInfo.Content.ContentLength);//Reading image content into ProductImage object
DocumentsManager.StorePendingDocuments.Add(file);
DocumentsManager.SaveTempDocuments();//Store each document uploaded to: TempDocument Table
TempData["SuccessMsg"] = "The image was saved successfully";
var json = new JavaScriptSerializer().Serialize(new { Success = true, StatusMessage = "El objeto fue insertado correctamente" });
return Content(json, "application/json");
}
catch (Exception exception)
{
TempData["ErrorMsg"] = exception.Message;
var json = new JavaScriptSerializer().Serialize(new { Success = false, StatusMessage = exception.Message });
return Content(json, "application/json");
}
}
Use return type of Action as ActionResult and use:
`return Json(new { Result = "Success" });`
So that on success you will get Json object containing result value.