0

Im working in an application that uses java + spring on the server side aswell as extdirectspring. On the client side it uses extjs/javascript.

I want to poke a method on the serverside and retrieve a file from the database. If the file doesn't exist then I'd like to display an error in some way.

The attempt to retrieve the file and the check it exists need to happen in the same call - the file could be deleted in between calls.

The way I can see people have done it in the current application is using spring controllers + request mappings and a window.open("someUrl/filename.blah"); with the server returning the file from the mapped method.

This doesnt seem to let you handle the case where the file doesn't exist though.

Ideally I'd just like to send some json back from the server which has the file data (possibly null) and sucess/failure. When I get the response I can then either show some information about the failure or open the file. Unfortunately I can't observe the current failure mode because something somewhere is caching the files - if I delete them from the database then they appear to still exist and you can still download them!

By 'open' I mean show the standard 'what do you want to do with this file open/save' dialog. I'm not trying to parse the file or do anything with it - I just want to serve it up to the browser/user.

Is there a way to do that without using a url and window.open? Eg some method that takes a blob of data and a file name or similar?

Update

The transfer of the data/json isn't the problem I'm trying to solve.

As I'm using extdirect I'll probably just do it like this:

public class SomeClass
{
    @ExtDirectMethod
    public AFile getFile(Long id) throws Exception
    {
        //do stuff
    }
}

Then on the clientside you just do:

someClass.getFile(id, function(file){
    if(file.found){
        SomeHowGiveThisToTheUser(file.name,file.data);  ????
        return;
    }

    ReportCouldntFind(file.name);
});

The bit I dont know how to do is the give the file to the user.

Further update

I dont think it's possible to do this without blob urls or data uri's. Both of these are mentioned in this post. I haven't tried them out as we are having to support a browser that is too old for both techniques.

Community
  • 1
  • 1
JonnyRaa
  • 7,559
  • 6
  • 45
  • 49
  • I'm sure you'd find solutions if you'd Google for how to fetch data from a server without loading a page, but what you need is to make an XHR request. Do a search on that term, and you'll find more than enough information. – cookie monster Jul 09 '14 at 16:10
  • Another term to search for is AJAX, which is just an alternate name for the above. I see that you're using ExtJS on the client, and I'm pretty sure they have an API to help with this. – cookie monster Jul 09 '14 at 16:13
  • @cookiemonster I probably didn't make it clear enough - the problem is not retrieving data from the server it's getting the browser to save/open a file if it hasn't been directly retrieved from a url – JonnyRaa Jul 10 '14 at 08:34

1 Answers1

1

You are wanting to do some standard Ajax (Assuming you have jQuery available).

Something like:

$.getJSON( url, function( data ) {
  if (data.success){

  } else {

  }
});

And on the server side, add code to return the expected JSON.

In extJS:

Ext.Ajax.request({
  url : url,
  method: 'GET',
  headers: { 'Content-Type': 'application/json' },                     
  params : params,
  success: function (response) {
         var jsonResp = Ext.util.JSON.decode(response.responseText);
         if (response.success){
           // do success stuff, like using response.fileData
         } else {
           // do fail stuff
         }
  failure: function (response) {
      var jsonResp = Ext.util.JSON.decode(response.responseText);
      // etc.
 });

On the server in a Java servlet you could something like this (assumes apache commons file util):

protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
  InputStream in = new URL( "http://remote.file.url" ).openStream();
  IOUtils.copy(in, response.getOutputStream());
}

Probably a more spring specific way to do it, but that gives you an idea.

For your case, you want to wrap the file contents in a JSON object that includes the success proeprty. For that, use the Java JSON jar: http://json.org/java/


Update: Finally understand what you are asking.

It finally occurred to me that you are asking how to handle the actual download.

There's a couple ways these days.

Take a look at this SO answer, this is using an iFrame: Download File Using Javascript/jQuery

There are also several fancy downloader components, including several for jQuery.

So you would do a two part process: check for the file availability using a standard ajax call, and then if response.success, use the downloader to serve the file to the user.

Community
  • 1
  • 1
mtyson
  • 8,196
  • 16
  • 66
  • 106
  • 1
    JavaScript doesn't have a `$` object with a `getJSON` method. – cookie monster Jul 09 '14 at 16:06
  • 2
    @cookiemonster $ is a shortcut to jQuery. – Libert Piou Piou Jul 09 '14 at 16:07
  • @LibertPiouPiou: I know that it *can* be, but I dont' see any mention of jQuery in the question, and I'd bet that the OP doesn't know what it is. I do see that the OP is using ExtJS. – cookie monster Jul 09 '14 at 16:08
  • 2
    `$.getJSON` does not return data, as it is async, it returns a promise – Patrick Evans Jul 09 '14 at 16:11
  • @cookiemonster - answer updated to include extJS version – mtyson Jul 09 '14 at 16:19
  • @mtyson thanks for the response but the problem isn't sending the file contents it's providing it to the user if it hasn't come from an url. I basically want to be to get that save/open dialog without using window.open(url). Ideally I'd like window.open(filename, contents) or something equivalent. – JonnyRaa Jul 10 '14 at 08:37
  • also the mdn documentation seems to say that using window.open is pretty much deprecated – JonnyRaa Jul 10 '14 at 08:38
  • @Johny Leeds - Are you looking for the server-side on how to read and send the file contents? – mtyson Jul 10 '14 at 16:48