how to download an image from url in grails - grails

Can anyone help me how to download an image from url in grails. Currently I am using the following code, but it is saving in current folder of the application. I want to download browser specific folder(like default folder which we download some file from web or saveAS)
def imageDownload() {
//imageURL = "http://www.google.com/images/logo.png"
String fullPath = params.imageURL
String baseName = FilenameUtils.getBaseName(fullPath);
String extension = FilenameUtils.getExtension(fullPath);
def fileName = baseName+"."+extension
def fileDoc = new File(fullPath);
def webUtils = WebUtils.retrieveGrailsWebRequest()
def response = webUtils.getCurrentResponse()
response.setContentType("application/png")
response.setHeader "Content-disposition", "attachment; filename=\"${fileName}\"";
def file = new FileOutputStream(fullPath.tokenize("/")[-1])
def out = new BufferedOutputStream(file)
out << new URL(fullPath).openStream()
out.close()
redirect(action: "imageDetails", params:params)
}
Need help, Thank you.

def downloadImage = {
def fileURL = "http://www.google.com/images/logo.gif"
def thisUrl = new URL(fileURL);
def connection = thisUrl.openConnection();
def dataStream = connection.inputStream
response.setContentType("application/octet-stream")
response.setHeader('Content-disposition', 'Attachment; filename=logo.gif')
response.outputStream << dataStream
response.outputStream.flush()
}

you can do it easily with a few groovy tricks:
URL urlCont = new URL(imageURL);
InputStream inStream = new BufferedInputStream(urlCont.openStream());
byte[] bytes = IOUtils.toByteArray(inStream);

def download() {
String fullPath = params.imageURL
String baseName = FilenameUtils.getBaseName(fullPath);
String extension = FilenameUtils.getExtension(fullPath);
def fileName = baseName+"."+extension
def webUtils = WebUtils.retrieveGrailsWebRequest()
def response = webUtils.getCurrentResponse()
response.setContentType("application/png")
response.setHeader "Content-disposition", "attachment; filename=\"${fileName}\"";
def outputStream = response.getOutputStream()
URL url = new URL(fullPath);
InputStream is = new BufferedInputStream(url.openStream());
byte[] buffer = new byte[1024];
int length=0;
while (-1!=(length=is.read(buffer)))
{
outputStream.write(buffer, 0, length);
}
outputStream.close();
is.close();
}
Thats all I am using..It is downloaded successfully...

Related

How do I set the content length when downloading a files in Grails

I have a method in my controller that allows to download the file that was uploaded. I am trying to have the Content-Length header be added to the download method so download progress bars work.
Problem is mine is not working which is response.setContentLength("${documentInstance.fileSize}")
I am getting error that file not found. If it take off this method the download will work
Here is the method
def download(long id) {
Document documentInstance = Document.get(id)
if ( documentInstance == null) {
flash.message = "Document not found."
redirect (action:'list')
} else {
response.setContentType("APPLICATION/OCTET-STREAM")
response.setHeader("Content-Disposition", "Attachment;Filename=\"${documentInstance.filename}\"")
response.setContentLength("${documentInstance.fileSize}")
def file = new File(documentInstance.fullPath)
def fileInputStream = new FileInputStream(file)
def outputStream = response.getOutputStream()
byte[] buffer = new byte[4096];
int len;
while ((len = fileInputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
outputStream.flush()
outputStream.close()
fileInputStream.close()
}
}
You have to set it has a Header parameter:
response.setHeader("Content-Length", "${bytes.length}")
Also, you might want to disable rendering of the view after you've streamed the file.
webRequest.renderView = false

How to save to a file system directory in Grails

I am trying to save an uploaded file into the file system directory, and allow other users to download it.
I am currently saving it in my database and not in my file system directory. Here is my code:
class Document {
String filename
byte[] filedata
Date uploadDate = new Date()
static constraints = {
filename(blank: false, nullable:false)
filedata(blank: true, nullable: true, maxSize:1073741824)
}
}
and my controller for uploading the file is:
class DocumentController {
static allowedMethods = [delete: "POST"]
def index = {
redirect(action: "list", params: params)
}
def list() {
params.max = 10
[documentInstanceList: Document.list(params), documentInstanceTotal: Document.count()]
}
def uploadPage() {
}
def upload() {
def file = request.getFile('file')
if(file.isEmpty())
{
flash.message = "File cannot be empty"
}
else
{
def documentInstance = new Document()
documentInstance.filename = file.getOriginalFilename()
documentInstance.filedata = file.getBytes()
documentInstance.save()
}
redirect (action: 'list')
}
}
I think you could do a fuction similar to the one below:
boolean upload(MultipartFile uploadFile, String fileUploadDir){
String uploadDir = !fileUploadDir.equals('') ?: 'C:/temp' //You define the path where the file will be saved
File newFile = new File("$uploadDir/${uploadFile.originalFilename}"); //You create the destination file
uploadFile.transferTo(newFile); //Transfer the data
/**You would need to create an independent Domain where to store the path of the file or have the path directly in your domain*/
}
Since you will only need to save the path of the file you could add a string to your domain to store it or you could create an independent domain to store the data of your file. You will also need to add try/catch statements where needed.
And to retrieve the file you would need to add to your controller something like the next code:
File downloadFile = new File(yourFileDomain?.pathProperty) //get the file using the data you saved in your domain
if(downloadFile){ //Set your response properties
response.characterEncoding = "UTF-8"
response.setHeader "Content-disposition", "attachment; filename=\"${yourFileDomain?.fileNameProperty}\"" //add the header with the filename you saved in your domain you could also set a default filename
//response.setHeader "Content-disposition", "attachment; filename=\"myfile.txt\""
response.outputStream << new FileInputStream(downloadFile)
response.outputStream.flush()
return
}
Hope this helps, any comments are welcome.

Reading JSON object from txt file in Groovy

I am trying to collect a JSON from a txt file. But my below code seems to keep giving me "nullPointerException".
File f = new File(tempDir+File.separator+'jsonObject.txt')
if (f){
log.error " file exists $f"
FileReader f2 = new FileReader(f);
log.error " file data- $f2"
if (f2 == null) {
//do something
} else {
JsonSlurper jsonParser = new JsonSlurper();
game = jsonParser.parse(new FileReader(f));
}
}
SOLUTION FOUND
Reading a json txt file:
File f = new File(tempDir+File.separator+'jsonObject.txt')
def slurper = new JsonSlurper()
def jsonText = f.getText()
json = slurper.parseText( jsonText )
Writing json to a file:
File g = new File(tempDir+File.separator+'jsonObject.txt')
g.createNewFile()
def json = new JsonBuilder()
json {
"result" result
}
g.setText(json.toString())
Please, try this:
import groovy.json.JsonSlurper
def inputFile = new File("D:\\yourPath\\json.txt")
def InputJSON = new JsonSlurper().parseText(inputFile.text)
InputJSON.each{ println it }
try:
File f = new File( tempDir, 'jsonObject.txt' )
if( f.exists() ) {
def game = f.withReader { r ->
new JsonSlurper().parse( r )
}
println game
}
Try simple and optimized solution:
import groovy.json.JsonSlurper
try {
File inputFile = new File("your_file_path")
def slurper = new JsonSlurper()
def data = slurper.parse(inputFile)
} catch (Exception e) {
e.printStackTrace()
}
parseFile can take a file as an input:
import groovy.json.JsonSlurper
def inputFile = new File("/your/path/my.json")
def InputJSON = new JsonSlurper().parseFile(inputFile, 'UTF-8')
InputJSON.each{ println it }

delete an existing file in grails

I am saving image files in my web folder. But at the time of saving or suppose a user want to change his picture than i want to delete the old picture and save the new one with the same file name. But I am failing after trying. Can anyone please help me on this please? Here is all my action below :
my save action >>>
def savePicture = {
String message = ""
def user = User.findById(1)
def userId = user.id
MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("productPic");
def okcontents = ['image/png', 'image/jpeg', 'image/gif']
if (! okcontents.contains(f.getContentType())) {
message = "Avatar must be one of: ${okcontents}"
render(view:'uploadForm', model:[message: message])
return;
}
String type = f.getContentType().substring(6)
String baseImageName = java.util.UUID.randomUUID().toString();
baseImageName = "user${user.id}"
// Saving image in a folder assets/channelImage/, in the web-app, with the name: baseImageName
def downloadedFile = f //.getFile( "product.baseImage" )
String fileUploaded = fileUploadService.uploadFile( downloadedFile, "${baseImageName}.${type}", "assets/channelImage/" )
if( fileUploaded ){
user.avatarType = type
user.save()
message = "File Saved Successfully."
redirect(action: 'show', params: [userId: userId])
}
}
my service action where I am trying to delete before save >>>
def String uploadFile( MultipartFile file, String name, String destinationDirectory ) {
def serveletContext = ServletContextHolder.servletContext
def storagePath = serveletContext.getRealPath( destinationDirectory )
def storagePathDirectory = new File("${storagePath}/${name}").delete()
// Store file
if(!file.isEmpty()){
file.transferTo( new File("${storagePath}/${name}") )
println("Saved File: ${storagePath}/${name}")
return "${storagePath}/${name}"
}else{
println "File: ${file.inspect()} was empty"
return null
}
}
my show method in controller >>>
def show = {
Long uid = Long.parseLong(params.userId)
def avatarUser = User.get(uid)
String link = "user${avatarUser.id}.${avatarUser.avatarType}"
[link:link]
}
my view page >>>
<g:if test="${link}">
<img src="${resource(dir: 'assets/channelImage', file: "${link}")}" />
</g:if>

How to make the .xlsx file download

The below is used to create the .xls file and download the file.
I want to download it to .xlsx file. If i simply change the extension into ".xlsx", the report directly opens in the browser. I want it to open in .xlsx extension. Kindly help me.
Below is the code reference for you,
//setting the application path to a variable
strPath = Server.MapPath("ExcelFiles");
//Creating a file name
strExportPath = "Card" + intRnd.ToString() + intRnd1.ToString() + ".xls";
hidFilePath.Value = "ExcelFiles/" + strExportPath;
//Creating the full path with the filename
strExcelPath = strPath + "\\" + strExportPath;
Session["AK_SC_CRD_EXCEL_PATH"] = strExcelPath;
StreamWriter objStreamWriter = new StreamWriter(strExcelPath, true);
//Write the XL Contents to a stream writer.
objStreamWriter.WriteLine(strXLContents);
objStreamWriter.Close();
objStreamWriter = null;
Thanks.
You may need to add a MIMETYPE for xslx to your response.
.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Similar to below;
Response.ContentType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Adding Following code will force your file download instead of opening in the browser.
Response.AddHeader("content-disposition", "attachment;filename=yourfilename.xlsx");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
/*Add your code here to write file to response stream*/
Response.End();
Use following code to download Excel:-
HttpContext context = HttpContext.Current;
FileStream fs = null;
BinaryReader br = null;
byte[] data = null;
try
{
if (File.Exists(filePath))
{
FileInfo file = new FileInfo(filePath);
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
br = new BinaryReader(fs, System.Text.Encoding.Default);
data = new byte[Convert.ToInt32(fs.Length)];
br.Read(data, 0, data.Length);
context.Response.Clear();
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
context.Response.AddHeader("content-disposition", "attachment; filename=" + file.FullName);
context.Response.AddHeader("Content-Length", file.Length.ToString());
context.Response.BinaryWrite(data);
context.Response.Flush();
}
}
catch (Exception ex)
{
Response.Write(ex.Message);
}

Resources