MultipartHttpServletRequest getting file content but not form ID - java

I have an html form to submit like this:
<form enctype="multipart/form-data" id="formToSubmit" action="/create_components" method="POST">
<input type="file" name="component_1" id="component_1">
Other inputs here...
On the server side, I wanna get all the inputs (both files and text inputs)... and the form is dynamically created so I don't know in advance the name of the IDs.
On the server I need both content and IDs.
On the server I first tried to loop on the parameters, but this skip the inputs that are of type file and return only the text ones:
Enumeration<?> enums = request.getParameterNames();
while (enums.hasMoreElements()) {
Object inputName = enums.nextElement();
// Here I get all the input that are not files
}
Then I tried in that way:
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
Set set = multipartRequest.getFileMap().entrySet();
Iterator i = set.iterator();
while(i.hasNext()) {
Map.Entry me = (Map.Entry)i.next();
String fileName = (String)me.getKey();
MultipartFile multipartFile = (MultipartFile)me.getValue();
byte[] bytes = multipartFile.getBytes();
}
In this way I actually get the files, but I don't know how to get their IDs.
I need both: the file content and the ID (in this example "component_1"). How can I do that? Is there a way I can change the last code in order to get also the ID?

You have the name of file by calling to:
String valueOfNameAttribute = ((MultipartFile)me.getValue()).getName()
Isn't that what you need?

Related

how to send file through ajax call in makePostRequest() and get it through request parameter in controller

my html code:
<input type="file" id="myFile" name="files[]">
ajax code:
var file = document.getElementById('myFile').files[0].name;
var poststr = 'file='+ escape(file)+'&key='+ escape('project_creation');
makePOSTRequest('controller', poststr,'bdy');
Controller:
if (param.equals("project_creation")) {
param="project_creation";
int proj_id = hlp.createProject(req,emp_id);
}
while retrieving through request i am getting only the file name. I need to save the file in local path.
Any help will be appreciated. Thanks in advance.
Have you used Form? so don't forgot to add attribute enctype="multipart/form-data" into form element.
Your code only working to read file name, if you want to save file, so you have to send file content in ajax call, and save by server coding, please check the below code that helpful to read file content,
var myFunction = function(){
var input = document.getElementById('myFile');
var reader = new FileReader();
reader.onload = function(){
var dataURL = reader.result;
console.log(input.files[0]); //Files property, size, name, type
console.log(dataURL); //File content in base64
var fileName = input.files[0].name; //File Name
var poststr = 'file='+ escape(dataURL)+'filename='+ escape(fileName)+'&key='+ escape('project_creation'); //Prepare URL params
makePOSTRequest('controller', poststr,'bdy');
};
reader.readAsDataURL(input.files[0]);
}
I have face the same issue against file read in javascript, and this code working for me.
I have face same issue against file read in javascript, and this code working for me.

download as csv using struts 2

I want to write some data to a csv file and user should be able to download it through browser.
#Actions({ #Action(value = "/downloadReport", results = { #Result(name = "success", type = "stream", params = {
"contentType", "${type}", "inputName", "stream", "bufferSize","2048", "contentDisposition",
"attachment;filename=\"${filename}\"" }) }) })
#SkipValidation
public String downloadReport() throws BaseAppException {
try {
filename =AdSkippingConstants.REPORT_FILE_NAME;
type = AdSkippingConstants.CSV_FILE_TYPE;
File file = new File(filename);
FileUtils.write(file, "Helloo World");
stream = new FileInputStream(file);
}
catch (IOException e) {
logger.error("Error occured while exporting error data", e);
}
return SUCCESS;
}
In jsp i am using ajax call
function exportAsCSV(){
$.ajax({
url: 'downloadReport.action?',
type: "POST",
success: function() {
//To Un Block the Change Password page if the page reloaded
//$('div.ui-dialog').unblock();
// $('#change_password_details_body').html(data);
},
error: function(){
//To Un Block the Change Password page if the page reloaded with error.
//$('div.ui-dialog').unblock();
}
});
}
I am able to get the response and even fileDownload=true is coming in response but still download to csv option is not opening in any browser and also please let me know how to pass html data to action for writing to csv.
In jsp i am using this code to do ajax call
var gridModel = "gridModel";
var sortname = "1";
var sortorder = "asc";
var caption = '<s:text name="grid.label.heading" />';
var url = "getGridSearchResults.action";
init.push(function() {
loadTable("gridtable", url, gridModel, columnDefs, columns, sortname,
sortorder, caption);
});
<table cellpadding="0" cellspacing="0" border="0" class="table table- striped table-bordered" id="gridtable"></table>
So with ajax call i am loading the data for the table.
You don't need AJAX. This is a common misconception.
You simply need to perform a call to an action returning a stream result, with a contentDisposition: attachment HTTP header.
This will tell the browser to download the file instead of opening it inline.
Read more in this answer
EDIT: if you need to send data from an HTML table to the action, you need to
use hidden input fields having the same value that you printed with <s:property/> tags (or whatever);
specify an index with the list[%{#status.index}].attribute notations to post the different records as different elements of a Collection.
I have done it using :
ActionContext.getContext().getSession().put("RESULTS_GRID", searchResultsForDownload);
and then retrieving the list in my DownLoadAction for getting the data and writing to csv using BufferedWriter.

Receiving varying lengths in request.getInputStream for the same file

I have a file uploader on my website, since i cannot use php I'm using jsp pages.
My main page uses a hidden iframe to post data to a second jsp page that handles the upload. However the uploaded images is always corrupted, more specifically it's larger in size than the original file.
Any hints or tips would be appreciated.
Main page code:
<form id="uploadForm">
<input type="file" name="datafile" /></br>
<input type="button" value="upload" onClick="fileUpload(document.getElementById('uploadForm'),'single_upload_page.jsp','upload'); return false;" >
</form>
The code for fileUpload concerning the form:
form.setAttribute("target","upload_iframe");
form.setAttribute("action", action_url);
form.setAttribute("method","post");
form.setAttribute("enctype","multipart/form-data");
form.setAttribute("encoding","multipart/form-data");
// Submit the form...
form.submit();
The code that handles the upload:
DataInputStream in = new DataInputStream(request.getInputStream());
int dataLength = request.getContentLength();
Because of the varying size of dataLength I'm assuming that the request.getInputStream receives extra data.
I only posted the code I think matters, if I need to post more or if you need any more information don't hesitate to ask.
Simple request
The problem is request.getContentLength() gives the length of the whole request, containing headers and all.
You have to search for Content-Length header value, convert it to Long and that's the proper size.
if you can't get it (it can be unavailable) simply consume the whole input stream. But of course, you'll not have idea of the file size.
Multipart request
Anyway... as your form is multipart/form-data you should use some library to parse all the different parts, find the one you need (the file part) and read it. You can use commons-fileupload.
Sample from real life
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse resp)
throws ServletException, IOException
{
// (....)
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload sfu = new ServletFileUpload(factory);
FileItemIterator it = sfu.getItemIterator(request);
// TAKE THE FIRST PART FROM REQUEST (HERE COMES THE FILE)
if (it.hasNext())
{
FileItemStream fis = it.next();
// grab data from fis (content type, name)
...fis.getContentType()...
...fis.getName()...
// GET CONTENT LENGTH SEARCH FOR THE LENGTH HEADER
...getContentLength(fis.getHeaders(), request)...
// here I use an own method to process data
// but FileItemStream has an openStream method
FileItem item = processUpload(factory, fis, uploadInfo);
(....)
}
private long getContentLength(FileItemHeaders pHeaders, HttpServletRequest request)
{
try
{
return Long.parseLong(pHeaders.getHeader("Content-length"));
}
catch (Exception e)
{
// if I can't grab the value return an approximate (in my case I don't care)
return request.getContentLength();
}
}

Google App Engine - Data being stored in a weird way

I'm using Java. This is the pure data that gets inserted in the datastore:
<p>Something</p>\n<p>That</p>\n<p> </p>\n<p>Should.</p>\n<p> </p>\n
<p>I have an interesting question.</p>\n<p>Why are you like this?</p>\n
<p> </p>\n<p>Aren't you fine?</p>
This is how it gets stored:
<p>Something</p> <p>That</p> <p>�</p> <p>Should.</p> <p>�</p>
<p>I have an interesting question.</p> <p>Why are you like this?</p>
<p>�</p> <p>Aren't you fine?</p>
What's up with the weird symbols? This happens only live, not on my local dev_appserver.
EDIT
Here's the code that inserts the data:
String content = ""; // this is where the data is stored
try {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iter = upload.getItemIterator(request);
while(iter.hasNext()) {
FileItemStream item = iter.next();
InputStream stream = item.openStream();
if(item.isFormField()) {
String fieldName = item.getFieldName();
String fieldValue = new String(IOUtils.toByteArray(stream), "utf-8");
LOG.info("Got a form field: " +fieldName+" with value: "+fieldValue);
// assigning the value
if(fieldName.equals("content")) content = fieldValue;
} else {
...
}
}
} catch (FileUploadException e){
}
...
// insert it in datastore
Recipe recipe = new Recipe(user.getKey(), title, new Text(content), new Text(ingredients), tagsAsStrings);
pm.makePersistent(recipe);
It's a multipart/form-data form so I have to do that little item.isFormField() magic to get the actual content, and construct a String. Maybe that's causing the weird encoding issue? Not sure.
To retrieve the data I simply do:
<%=recipe.getContent().getValue()%>
Since content is of type Text (app engine type) I use the .getValue() to get the actual result. I don't think it's an issue with retrieving the data, since I can see the weird characters directly in the online app-engine datastore viewer.
Are you using eclipse ? if yes check under File > Properties > Text File encoding that your file is UTF-8 encoding.
I would guess not.
So, change it to UTF-8 and your issue should get fixed.
regards
didier
Followed this page to create a Servlet Filter so that all my pages were being encoded in utf8:
How to get UTF-8 working in Java webapps?
After creating the filter, everything works!

How to detect if a form input element of type file is empty

I have some code which reads a file through a form field of type file
<input type="file" ... />
I want to give the user another option of providing a url to a file rather than having to upload it as many are already online.
How can I detect when this field is empty on the server side. I am using Apache Commons FileUpload
FileItemStream item = iter.next();
name = item.getFieldName();
stream = item.openStream();
if(!item.isFormField()){
if(item.toString()!=""){
....
I need to detect when item is empty. The above code doesn't work, nor does using:
if(item.equals(null)){
....
You can't call item.equals( null ) when item is null. You have to test it like this:
if( item == null ) {
...
}
To check for any empty file input in the form while uploding any file to the server best way follow my instructions
1. use #MultipartConfig() at the top of your servlet class
2. add the following method to your class
private InputStream getImageStream(HttpServletRequest request, String image){
try {
Part part = request.getPart(image);
String header = part.getHeader("content-disposition");
InputStream input = null;
if(header.contains("filename")){
input = part.getInputStream();
}
return input;
} catch (IOException | ServletException e ){
e.printStackTrace();
}
return null;
}
Code description
The code get the file using build in class "Part"
After that it will assign the all contents of the object part the we call using request.getPart(image), Where "image" is the name of the file input in your form field. And assign it to String object "header"
If you uplode any file to the input field the "header" will contain a sub sting "filename" and if it does it means you upload a file and assign it to InputStream object input else the is no file and the InputStream input will be assigned to null by default
return the InputStream object
And in your get or post method call the above method with the code below
InputStream school_pic = getImageStream(request, "schoolPic");
where "schoolPic" is the name of your input file in the form
That is all gusy

Categories

Resources