save image to a folder under web-app in grails - image

I need to save image to a folder in my application. So far I have learned to save image into a database but I need to save it to a folder. How can I do this? Can anyone please help me on this please? here is my code below to save into database >>>
def upload={
def user = User.findById(1)
CommonsMultipartFile file = params.list("photo")?.getAt(0)
user.avatar = file?.bytes
user.save()
}

Find below for the step wise implementation, I have added a GSP page with the uploadForm(it will have multipart form submission by default), and then a controller function to handle file save request, and a service method to save file in a specified directory:
Step1: Create a form for file upload:
<g:uploadForm name="picUploadForm" class="well form-horizontal" controller="<your-controller-name>" action="savePicture">
Select Picture: <input type="file" name="productPic"/>
<button type="submit" class="btn btn-success"><g:message code="shopItem.btn.saveProductImage" default="Save Image" /></button>
</g:uploadForm>
Step2: Then in your controller's savePicture action:
String baseImageName = java.util.UUID.randomUUID().toString();
// Saving image in a folder assets/channelImage/, in the web-app, with the name: baseImageName
def downloadedFile = request.getFile( "product.baseImage" )
String fileUploaded = fileUploadService.uploadFile( downloadedFile, "${baseImageName}.jpg", "assets/channelImage/" )
if( fileUploaded ){
// DO further actions, for example make a db entry for the file name
}
Step3: and in the file uploader service(User defined service with the name FileUploadService in this case):
def String uploadFile( MultipartFile file, String name, String destinationDirectory ) {
def serveletContext = ServletContextHolder.servletContext
def storagePath = serveletContext.getRealPath( destinationDirectory )
def storagePathDirectory = new File( storagePath )
if( !storagePathDirectory.exists() ){
println("creating directory ${storagePath}")
if(storagePathDirectory.mkdirs()){
println "SUCCESS"
}else{
println "FAILED"
}
}
// 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
}
}

You have only to copy the MutipartFile into web-app folder. This is how :
MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("myfile");
String fileName = System.currentTimeMillis() + f.name
String destinationFileName = configService.getAbsoluteDocumentsPath() + fileName // We will put it on web-app/documents/xxxxx
f.renameTo(new File(destinationFileName))
//Save filename to database in
user.avatar = fileName
user.save()
And in configService I have that (used to calculate paths)
class ConfigService {
def grailsApplication
/**
* #return absolute path of documents
*/
def getAbsoluteDocumentsPath(){
def asolutePath = grailsApplication.mainContext.servletContext.getRealPath('documents')
return asolutePath.endsWith("/") ? asolutePath : asolutePath + "/"
}
}
EDIT
To make sure that your request is an instance of MutipartHttServletRequest Add the following test
if(request instanceof MultipartHttpServletRequest) {
//Do stuff here
}
Don't forget to check the the encoding of the form in which you put the file input.

I have solve this so easily as follows. You will have to import followings :
import org.apache.commons.io.FileUtils
import org.springframework.web.multipart.commons.CommonsMultipartFile
import org.springframework.web.multipart.*
Good luck who needs this >>>
def saveImageToFolder = {
String message = ""
MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("userPhoto")
if(!f.empty) {
def usr = User.findByUsername(1)
if(!usr){
User user = new User()
user.username = params.username
user.avatarType = f.getContentType()
if(user.save()){
def userId = user.id
String username = user.username
String fileName = username + "." + f.getContentType().substring(6) // here my file type is image/jpeg
byte[] userImage = f.getBytes()
FileUtils.writeByteArrayToFile(new File( grailsApplication.config.images.location.toString() + File.separatorChar + fileName ), userImage )
message = "User Created Successfully."
}else{
message = "Can not Create User !!!"
}
}else{
message = "Username already exists. Please try another one !!!"
}
}
else {
message = 'file cannot be empty'
}
render(view: 'addUser', model:[message: message])
}
and in your config file paste this >>>
images.location = "web-app/images/userImages/" // after web-app/folder name/folder name and go on if you want to add other folder

Related

Rename a recorded file every time I save a record in xamarin

I am saving my records using this code:
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
public string fileName { get; set; }
fileName = Path.Combine(path, "sample.wav");
if (!recorder.IsRecording)
{
recorder.StopRecordingOnSilence = TimeoutSwitch.IsToggled;
//Start recording
var audioRecordTask = await recorder.StartRecording();
BtnDoneRec.IsEnabled = false;
await audioRecordTask;
RecEditor.IsEnabled = true;
BtnDoneRec.IsEnabled = false;
PlayButton.IsEnabled = true;
var filePath = recorder.GetAudioFilePath();
if (filePath != null)
{
var stream = recorder.GetAudioFileStream();
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
stream.CopyTo(fileStream);
}
}
}
else
{
//stop recording ...
await recorder.StopRecording();
}
I want my record to have a specific name which is labeled with my RecEditor
using (var streamReader = new StreamReader(fileName))
{
File.Move("sample.wav", RecEditor.Text + ".wav");
}
So it will rename "sample.wav" to "RecEditor text.wav" every time I click my save button.
But when I click save, it gives me this record
System.IO.FileNotFoundException: 'Could not find file '/sample.wav'.'
The record is stored in /storage/emulated/0/sample.wav
The sample.wav is created in my device but I don't know why it give me 'Could not find file '/sample.wav'.' error. What am i doing wrong here?
I believe that what you're looking is something like this:
if(File.Exists(fileName))
{
var newFileName = Path.Combine(path, $"{RecEditor.Text}.wav");
File.Move(fileName, newFileName);
}
You don't need to open a new Stream as you are doing. Also, you need to put the full file path not only the file name.
You might want to validate that RecEditor.Text is not empty before using its value for the newfileName
Hope this helps.-

Unable to append to next line in a file through beanshell assertion sampler in Jmeter

Have 2 steps in my JMeter script. Login and Second getting the orders, inside the login thread group I am using a bean shell assertion to validating few conditions and once I hit with an error I am writing the error to a log file. So for the first thread, it is writing it correctly but when it reaches the next assertion it overwrites the same file without appending it.
First Assertion:
import org.apache.jmeter.assertions.AssertionResult;
String failureMessage = "";
String successMessage = "";
String ResCode =SampleResult.getResponseDataAsString();
if (!ResCode.contains("Admin") )
{
failureMessage = "Got Response Code" + ResCode;
log.warn("Creation of a new record failed: Response code " + ResCode);
AssertionResult result = new AssertionResult("Expected Response 200");
result.setFailure(true);
result.setFailureMessage(failureMessage);
prev.addAssertionResult(result);
prev.setSuccessful(false);
SampleResult.setStartNextThreadLoop(true);
}
else {
successMessage = "Got Response Code" + ResCode;
log.info("----->"+successMessage);
FileOutputStream logfile = new FileOutputStream(vars.get("LogFile"));
PrintStream printtoFile = new PrintStream(logfile);
printtoFile.println( successMessage );
printtoFile.close();
logfile.close();
}
Second Assertion:
import org.apache.jmeter.assertions.AssertionResult;
String failureOrderMessage = "";
String successOrderMessage = "";
OrderId = vars.get("workOrderId");
log.info("----->"+OrderId);
if (OrderId == null){
failureOrderMessage = "The Order Id :"+OrderId;
log.info("----->"+failureOrderMessage);
FileOutputStream logfile = new FileOutputStream(vars.get("LogFile"));
PrintStream printtoFile = new PrintStream(logfile);
printtoFile.println( failureOrderMessage );
printtoFile.close();
logfile.close();
}
else {
successOrderMessage = "Getting few order id";
log.info("----->"+successOrderMessage);
}
The above assertion is working fine, but every time its overwrite the log file but I want to append it.
Second
FileOutputStream logfile = new FileOutputStream(vars.get("LogFile"));
PrintStream printtoFile = new PrintStream(logfile);
printtoFile.println( successMessage );
printtoFile.close();
logfile.close();
Do I need to every time declare the above code snippet to write to the log file?
You need to create FileOutputStream with append flag:
FileOutputStream logfile = new FileOutputStream(vars.get("LogFile"), true);
append - if true, then bytes will be written to the end of the file rather than the beginning

cant able to test file extension on test class?

visuaforce page:
<apex:page sidebar="false" controller="UploadOpportunityScheduleLineItem123">
<apex:form >
<apex:sectionHeader title="Upload data from CSV file"/>
<apex:pagemessages />
<center>
<apex:inputFile value="{!contentFile}" filename="{!nameFile}" />
<apex:commandButton action="{!ReadFile}" value="Upload File" id="theButton" style="width:70px;"/>
<br/> <br/>
</center>
</apex:form>
</apex:page>
apex:
public with sharing class UploadOpportunityScheduleLineItem123{
// Global variables
public string nameFile{get;set;}
Public Id parentId{get;set;}
public Blob contentFile{get;set;}
List<account> lstScheduleToUpdate = new List<account>();
public account objSchedule{get;set;}
//String array for taking csv data by line.
String[] filelines = new String[]{};
//set for storing all id's from csv.
set<String> opptoupload{get;set;}
//Main constructor
public UploadOpportunityScheduleLineItem123()
{
//Initalizing required objects.
objSchedule = new account();
opptoupload = new set<String>();
}
//Method to read file content and check extension and file format.
public Pagereference ReadFile()
{
parentId=Apexpages.currentPage().getParameters().get('ParentId');
//If without selecting csv file you clicked on upload it will give error message.
if(nameFile == null)
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'You should select csv file to upload');
ApexPages.addMessage(errormsg);
return null;
}
//Taking file extension.
String extension = nameFile.substring(nameFile.lastIndexOf('.')+1);
//Checking if file extension is .csv.
if(extension == 'csv' ||extension == 'CSV')
{
nameFile =blobToString( contentFile,'ISO-8859-1');
//Spliting by new line
filelines = nameFile.split('\n');
//Spliting values by (,) for checking coloumn size
for (Integer i=1;i<filelines.size();i++){
String[] inputconvalues = new String[]{};
inputconvalues = filelines[i].split(',');
account b = new account();
b.name= inputconvalues[0];
b.billingcountry = inputconvalues[1];
b.billingcity = inputconvalues[2];
lstScheduleToUpdate.add(b);
}
//Checking if list is not empty then updating.
if(lstScheduleToUpdate.Size()>0)
{
insert lstScheduleToUpdate;
}
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.info,'Batches File uploaded successfully');
ApexPages.addMessage(errormsg);
return null;
}
//If file is not csv type then it will give error message.
else
{
ApexPages.Message errormsg = new ApexPages.Message(ApexPages.severity.ERROR,'File type should be csv type');
ApexPages.addMessage(errormsg);
return null;
}
}
public static String blobToString(Blob input, String inCharset){
String hex = EncodingUtil.convertToHex(input);
System.assertEquals(0, hex.length() & 1);
final Integer bytesCount = hex.length() >> 1;
String[] bytes = new String[bytesCount];
for(Integer i = 0; i < bytesCount; ++i)
bytes[i] = hex.mid(i << 1, 2);
return EncodingUtil.urlDecode('%' + String.join(bytes, '%'), inCharset);
}
}
test class :
#IsTest(SeeAllData=true)
private class testexceltoaccount
{
static testmethod void testLoadData() {
StaticResource testdoc = [Select Id,Body from StaticResource where name ='testMethodCSVUpload1'];
UploadOpportunityScheduleLineItem123 testUpload = new UploadOpportunityScheduleLineItem123();
testUpload.contentFile= testdoc.Body;
testUpload.ReadFile();
}
}
Cant able to cross this section of code in code coverage :
String extension = nameFile.substring(nameFile.lastIndexOf('.')+1);
//Checking if file extension is .csv.
if(extension == 'csv' ||extension == 'CSV')
{
I tried many possible to cross code coverage but still it is at that point .Please help me in this regard.
Thanks in advance
When we use apex:inputFile on VF page and upload any file, then name of file is automatically update field into the field specified in filename attribute, but when you are writing test class you only specifying content of file
testUpload.contentFile= testdoc.Body;
You should add name in nameFile global variable manually
testUpload.nameFile= 'test.csv';
#IsTest(SeeAllData=true)
private class testexceltoaccount
{
static testmethod void testLoadData() {
StaticResource testdoc = [Select Id,Body,Name from StaticResource where name ='testMethodCSVUpload1'];
UploadOpportunityScheduleLineItem123 testUpload = new UploadOpportunityScheduleLineItem123();
testUpload.contentFile= testdoc.Body;
testUpload.nameFile= 'test.csv';
testUpload.ReadFile();
}
}

Saving of grails domain object with an attribute type object fails

I'm trying to save a domain object with grails 2.3.3 But it is not saved. How can I save it and why is it not saving?
The domain code:
package berg
import nl.jappieklooster.Log
class FieldValue {
Object value
public String toString(){
Log.debug "Field value: {0}", value
return value.toString()
}
static constraints = {
}
}
The code that saves:
// an extract from the bootsrap file
def init = { servletContext ->
def blueFV = new FieldValue(value: Color.blue)
def smallFV = new FieldValue(value: "small")
def fieldVals = [blueFV, smallFV]
saveData(fieldVals,berg.FieldValue)
}
public void saveData(List list, Class type){
def wholeList = type.list() ?: []
println("Started with adding the "+type.getName()+" classes.")
int saved = 0;
int failed = 0;
if(!wholeList){
list.each{ i ->
if(i.validate()){
i.save(flush:true, failOnError: true)
saved++
}
else{
println("! - - - Warning: '"+i.toString()+"' could not be created! - - - !")
failed++
}
}
if(failed > 0)//if one fails, let the message appear more clearly
println(".v.v.")
println("When saving the "+type.getName()+" classes: "+saved+" were saved, "+failed+" failed to be saved.")
if(failed > 0)
println(".^.^.")
}
}
The entire value column does not show up in the database

AJAX file upload reloading application

I have the following snippet
class PresentationUpload {
def uploadForm(form:NodeSeq) : NodeSeq = {
var fileHolder: Box[FileParamHolder] = Empty
def handleFile() = {
fileHolder.map { holder =>
val filePath = "src/main/webapp/files"
val oFile = new File(filePath, holder.fileName)
val output = new FileOutputStream(oFile)
output.write(holder.file)
output.close()
} openOr {
// Do something
}
}
val bindForm = "type=file" #> fileUpload((fph) => fileHolder = Full(fph)) &
"type=submit" #> ajaxSubmit("Submit", handleFile _)
ajaxForm(bindForm(form))
}
}
The file uploads correctly but then reloads the application, is this the correct way to handle ajax uploads or is there another method I should be using?
Thanks for any help, much appreciated
I've configured the lift project (normally "project/build/LiftProject.scala") to not reload after changes to the files directory, problem solved :)
override def scanDirectories = (
temporaryWarPath / "WEB-INF" * ("classes" | "lib")
).get.toSeq

Resources