I have a method that generate a CSV file with some db records
public static void generateCsvForAttendees( List<Attendee> attendeeList ) throws FileNotFoundException
{
PrintWriter pw = new PrintWriter(new File("test.csv"));
StringBuilder sb = new StringBuilder();
//Header
sb.append( "Id" );
sb.append( ',' );
sb.append( "Name" );
sb.append( ',' );
sb.append( "Lastname" );
sb.append('\n');
//Content
for( Attendee attendee: attendeeList )
{
sb.append( attendee.getId() );
sb.append( ',' );
sb.append( attendee.getUser().getName() );
sb.append( ',' );
sb.append( attendee.getUser().getLastname() );
sb.append( '\n' );
}
pw.write(sb.toString());
pw.close();
}
I would like that method would be an endpoint in order to invoke it from any kind of client (web or mobile) to download it. In the Google Cloud Endpoint documentation there isn't something about File as a valid return type. How could I create and endpoint that return a File?
Here is how to save a file from an Endpoint to Cloud Storage and return the URL for downloading it.
1/ Activate Google Cloud Storage in your Project Console
2/ Create a Bucket in your Cloud Storage instance, with the name bucketName. Optional: you can set access rights on this bucket.
3/ In your endpoint Class, create a gcsService as folllow:
private final GcsService gcsService = GcsServiceFactory.createGcsService(new RetryParams.Builder()
.initialRetryDelayMillis(10)
.retryMaxAttempts(10)
.totalRetryPeriodMillis(15000)
.build());
4/ In your method, create an ByteArrayOutputStream:
ByteArrayOutputStream os = new ByteArrayOutputStream();
5/ Create your printer from the ByteArrayOutputStream
6/ Then do the following:
ByteBuffer buf = ByteBuffer.wrap(os.toByteArray());
GcsFilename gcsfileName = new GcsFilename(bucketName, bucketFileName);
//bucketFileName = your file name
GcsFileOptions options = new GcsFileOptions.Builder().mimeType("text/plain").build();
GcsOutputChannel outputChannel = gcsService.createOrReplace(gcsfileName, options);
outputChannel.write(buf);
outputChannel.close();
7/ Your file should then be saved to Cloud Storage: you just have to return in a string wrapper the url to open it. Look the following documentation to decide which URL to use (depending on whether the user shall be authenticated or not, see Section "A user is granted read access to an object") https://cloud.google.com/storage/docs/cloud-console#_accessing
CSV files are pretty easy to work with once back in a client - after all, all they are is a specially formatted String with the commas and quotes and what not. What you could do is just return a String in your endpoints method - the entire String being your CSV file. Then in the client you know that String is the CSV so handle it accordingly (i.e. write it to a file and save it with the .csv extension).
Cloud Endpoints really just return a JSON String. You could also try Base64 encoding a File to String and then decoding the Base64 String in your client but in my opinion it might be easier to just do what I suggested since CSV files. There is also a 1MB limit on the response you get from GAE. Read more about it here: Query response size limit on appengine?