B4J Question How To:Getting File Content from Http Request

Dogbonesix

Active Member
Licensed User
Longtime User
Hi There,

I am trying to upload a file to my B4J App from an HTML page. I am using Jquery Ajax to send the file:

JS AJAX:
$('input[type=file]').on('change', prepareUpload);
                function prepareUpload(event){
                  files = event.target.files;
                };
            $('#submitFile').click(function()
            {
                var formData = new FormData();
                $.each(files,function(key, value){
                    
                    formData.append(key, value);
                });
                var fileName = $('#sptDocUpload').val();
                var fileCleaned = fileName.split('\\');
                var docName = encodeURIComponent(fileCleaned[2]);
                ///console.log(docName);
                
                    console.log(files[0])
                //alert(formData);
                $.ajax({
                  url: 'upload?name='+docName, 
                  type: 'POST',
                  data: formData,
                  success: function(data){ $('#whereyoutype').val(data); },
                  cache: false,
                  contentType: false,
                  processData: false
                });
            });

I have set up my server handler to take /upload and run to an upload module
Sub Handle from upload module:
Sub Handle(req As ServletRequest, resp As ServletResponse)
    resp.Write("File Submitted.  ")
    If req.Method <> "POST" Then
        resp.SendError(500, "method not supported.")
        Return
    End If
            Dim In As InputStream = req.InputStream
            Dim fileDir As String = File.DirApp & "\www\" & Main.filesFolder  & "\"
            Dim uploadedFile As InputStream = map.Get("name")
            
            
' Release Unix /  Remove the comment on the line below to create a release application
            fileDir = fileDir.Replace ("\", "/")
            
            If File.Exists(fileDir, "") = False Then
                File.MakeDir(fileDir,"")
            End If
            
            Dim out As OutputStream = File.OpenOutput(fileDir, name, False)
            
            File.Copy2(In, out)
            out.Close
            Log("Received file: " & name & ", size=" & File.Size(Main.filesFolder, name))
            resp.Write("File received successfully.")
            
End Sub

The problem is my uploaded file then always has the HTTP header content in it
1618939786944.png


How do I get the file without the HTTP headers included?
 

OliverA

Expert
Licensed User
Longtime User
Try
B4X:
    Try
        'Note: By using File.Combine, one does not have to worry about / or \
        Dim fileDir As String = File.Combine(File.DirApp, File.Combine("www", Main.filesFolder))
        Dim uploadedFile As String = req.GetParameter("name")
        If uploadedFile = "" Then uploadedFile = "test.file" 'Just to make it easier for me
        Log($"uploadedFile: ${uploadedFile}"$)
        'Note: GetMultipartData will create the folder if it does not exist. Here
        'I'm just letting it use the same directory
        Dim parts As Map = req.GetMultipartData(fileDir, 10000000)
        'Notice the name="0" in your screenshot. That's the key name we are looking for (so we are only working with the first file, even if more than
        'one is uploaded with your JS example)
        If parts.ContainsKey("0") Then
            Dim filePart As Part = parts.Get("0")
            'Note: TempFile method needs to be called before using IsFile.
            'See: https://www.b4x.com/android/forum/threads/async-xmlhttprequest-multiple-file-upload.82432/
            Dim tempFile As String = filePart.TempFile
            If filePart.IsFile Then
                FileMove(File.GetFileParent(tempFile), File.GetName(tempFile), fileDir, uploadedFile)
            Else
                Log("This was not a file")                
            End If
        
        End If
    Catch
        Log(LastException)
    End Try
The FileMove code is as follows
B4X:
'https://www.b4x.com/android/forum/threads/how-do-you-rename-a-file.19215/post-546367
Sub FileMove(SourceFolder As String, SourceFile As String, TargetFolder As String, TargetFile As String) As Boolean
    Dim source, target As JavaObject
    source.InitializeNewInstance("java.io.File", Array(SourceFolder, SourceFile))
    target.InitializeNewInstance("java.io.File", Array(TargetFolder, TargetFile))
    Return source.RunMethod("renameTo", Array(target))
End Sub
 
Upvote 0

Dogbonesix

Active Member
Licensed User
Longtime User
OliverA. Thanks. We have been struggling over this solution for a while. I have not had a chance to see how it works but it looks very viable. I will keep posted.
 
Upvote 0

Dogbonesix

Active Member
Licensed User
Longtime User
I know this is a late reply but a lot of work has been done. I had a few lines some excess code on my module (kinda hidden or overlooked) that caused a problem. Running the module exactly as written essentially works GREAT! The - 'Note: By using File.Combine, one does not have to worry about / or \ - was an issue. I had to add a line at the beginning fileDir = fileDir.Replace ("\", "/") to get the code to work properly, otherwise it wouldn't create the sub folders correctly. Any way it works. Do you take donations? Try the code at svn.cgumpdesign.com. If you leave the login and PWD blank you will have access to the sample data. If you chose to visit please leave a comment.
 
Upvote 0
Top