write file into spring boot folder - spring-boot

my spring boot project structure is like this
src
|-main
|--|-java
|--|-resources
static
|-css
|-images
|-js
now I want to write a file into the static/images folder
I tried to new File like
BufferedOutputStream stream =new BufferedOutputStream(new FileOutputStream(new File("static/images")));it will throw "No such file or directory" exception
but in other html file I can get the js by "js/jsFile.js"

new File("static/images") is right
I used new File("/static/images") so I got an Exception

I was in the situation where using Spring Boot I had to save the image into one directory which is accessed statically.
Below code worked perfect
byte[] imageByteArray ....
String fileName = "image.png";
String fileLocation = new File("static\\images").getAbsolutePath() + "\\" + fileName;
FileOutputStream fos = new FileOutputStream(fileLocation);
fos.write(imageByteArray);
fos.close();
Hope it helped.

#zhuochen shen is correct.
The thing is to happen me is Eclipse doesn't show write file. So I looked at file explore. File is writing correctly.
try {
Path path=Paths.get("static/images/"+productDto.getImage().getOriginalFilename());
Files.write(path,productDto.getImage().getBytes());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
enter image description here
enter image description here

Related

update profile image functionality is not working while hosting as jar

Hi I am new to Springboot I was trying to develop a application, One of its functionality is to upload profile Image. It was working fine in STS but when I pack it in jar and hosting it on AWS EC2 envirnment I am getting some error while processing that image
Error:
handler for profile picture:
#PostMapping("/process-contact")
public String processContact(#ModelAttribute Contact contact, #RequestParam("profileImage") MultipartFile file,
HttpSession session) {
try {
contact.setUser(user);
user.getContacts().add(contact);
// processing and uploading photo
if (file.isEmpty()) {
System.out.println("File is empty");
contact.setImage("contact.png");
} else {
//Processing Image
InputStream inputStream = file.getInputStream();
Path paths = Paths.get(new ClassPathResource("/static/img").getFile().getPath()+"/" +file.getOriginalFilename());
Files.copy(inputStream, paths, StandardCopyOption.REPLACE_EXISTING);
contact.setImage(file.getOriginalFilename());
}
// Success Message
session.setAttribute("message", new Message("Your contact is added...", "success"));
this.userRepository.save(user);
System.out.println("Successfully Added");
} catch (Exception E) {
E.printStackTrace();
// Failed message
session.setAttribute("message", new Message("Something went wrong "+E.getMessage(), "danger"));
}
return "normal/add_contact_form";
}
It is working fine in IDE after some research I found way of writing data in jar is diffrent could some please help me how can I implemenr it for jar also.
Thankyou
all you need to do is replace this line:
Path paths = Paths.get(new ClassPathResource("/static/img").getFile().getPath()+"/" +file.getOriginalFilename());
With:
Path paths = Paths.get(new FileSystemResource("/static/img").getFile().getPath()+"/" +file.getOriginalFilename());
THat will work like charm.

Spring MVC - Copy image into WEB-INF/assets folder

I am trying to copy image into assets folder inside WEB-INF folder. Following code successfully copy images outside the project but can't copy inside WEB-INF folder.
public static void copyFile(String source, String destination) throws IOException {
try {
File sourceFile = new File(source);
File destinationFile = new File(destination);
FileInputStream fileInputStream = new FileInputStream(sourceFile);
FileOutputStream fileOutputStream = new FileOutputStream(destinationFile);
int bufferSize;
byte[] bufffer = new byte[512];
while ((bufferSize = fileInputStream.read(bufffer)) > 0) {
fileOutputStream.write(bufffer, 0, bufferSize);
}
fileInputStream.close();
fileOutputStream.close();
} catch (IOException e) {
throw new IOException(e.getMessage());
}
}
I get a image path from Http request.
CopyFile.copyFile(imageUrl, "http://localhost:8080/M.S.-Handloom-Fabrics/static/"+imageName+".png");
I have mapped the resources in dispatcher-servlet.xml
<mvc:resources mapping="/static/**" location="/WEB-INF/assets/"/>
Here is the error
Info: http:\localhost:8080\M.S.-Handloom-Fabrics\static\TueJun1216_27_54NPT20180.png (The filename, directory name, or volume label syntax is incorrect)
http://localhost:8080/M.S.-Handloom-Fabrics/static/"+imageName+".png"
is a URL, not a file-path, and is therefore meaningless as a parameter to the File constructor.
IF you configured your app server to explode your webapp on deploy then you could use ServletContext.getRealPath but as this SO post details nicely you most likely do not want to do this as your saved files will be lost upon re-deploy.
Saving them outside of the web app is the way to go.

Spring cannot find the file via specified path

My files hierarchy:
>resources:
>static:
>css:
>json:
>networks:
>network-list.json
>js:
>img:
I've tried to create a new file via:
File jsonNetworkDetailsFile = new File("/json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("static/json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("../json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("../../json/networks/network-list.json");
File jsonNetworkDetailsFile = new File("/json/networks/network-list.json");
...and some more. None of it works.
I'm still getting the
java.io.FileNotFoundException: the system cannot find the path specified
What's the proper way?
EDIT
Found a solution. Had to include full path to the file like:
File jsonNetworkDetailsFile = new File("src/main/resources/static/json/networks/Turtlecoin/turtlecoin-pools.json");
EDIT2
As TwiN stated - it's impossible to reference a file through File object as soon as the app is packed into .jar. A proper solution would include:
InputStream jsonNetworkDetailsFile = new ClassPathResource("/static/json/networks/network-list.json").getInputStream();
InputStream is = new ClassPathResource("/someFile.txt").getInputStream();
where /someFile.txt is in your resources folder.
As mentioned in the documentation for ClassPathResource:
Supports resolution as java.io.File if the class path resource resides
in the file system, but not for resources in a JAR. Always supports
resolution as URL.
In other words, you'll want to use the getInputStream() method for your case:
InputStream is = new ClassPathResource("/someFile.txt").getInputStream();
try {
String contents = new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
System.out.println(contents); // do something with the content here
is.close();
} catch (IOException e) {
e.printStackTrace();
}
I'm mentioning this because ClassPathResource also has a getFile() method.
For more details, see reference
Try something like this :
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("classpath:static/json/networks/network-list.json").getFile());
You could also use :
#Value(value = "static/json/networks/network-list.json")
private Resource myFile;
And then :
myFile.getInputStream()
(will only work on a class annoted with #Component, #Service... etc)
you can try this to load files from ressources :
ClassLoader loader = Thread.currentThread().
getContextClassLoader();
InputStream configStream = loader.getResourceAsStream("/static/json/networks/network-list.json");
I think you should give the exact location to File object. Another solution:
File currDir = new File(".");
String path = currDir.getAbsolutePath();
// String path = "C:\\ExternalFiles\\"; // Or you can give staticly
File jsonNetworkDetailsFile = new File(path);
Hope it helps.

Spring Boot load another file from app.properties

I am new to Spring Boot. I have this emailprop.properties in src/main/resource:
//your private key
mail.smtp.dkim.privatekey=classpath:/emailproperties/private.key.der
But I am getting the error as
classpath:\email properties\private.key.der (The filename, directory
name, or volume label syntax is incorrect)
How do I properly load this file?
Update-1
my java code is
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),
emailProps.getProperty("mail.smtp.dkim.privatekey"));
its working as "D:\\WorkShop\\MyDemoProj\\EmailService\\src\\main\\resources\\private.key.der"Instead of emailProps.getProperty("mail.smtp.dkim.privatekey")
Update-2
i have tried java code is
String data = "";
ClassPathResource cpr = new ClassPathResource("private.key.der");
try {
byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream());
data = new String(bdata, StandardCharsets.UTF_8);
} catch (IOException e) {
e.printStackTrace();
}
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),data);
Error is : java.io.FileNotFoundException: class path resource [classpath:private.key.der] cannot be resolved to URL because it does not exist
Tried Code is :
ClassPathResource resource = new ClassPathResource(emailProps.getProperty("mail.smtp.dkim.privatekey"));
File file = resource.getFile();
String absolutePath = file.getAbsolutePath();
Still same error..
please update the answer..
If you want to load this file runtime then you need to use ResourceLoader please have a look here for the documentation - section 8.4.
Resource resource = resourceLoader.getResource("classpath:/emailproperties/private.key.der");
Now if you want to keep this exact path in properties file you can keep it there and then load it in your Autowired constructor/field like that:
#Value("${mail.smtp.dkim.privatekey}") String pathToPrivateKey
and then pass this to the resource loader.
Full example you can find here. I don't want to copy paste it.
If your file is located here:
"D:\\WorkShop\\MyDemoProj\\EmailService\\src\\main\\resources\\private.key.der"
then it should be:
mail.smtp.dkim.privatekey=classpath:private.key.der
EDIT:
I see now, you are using DKIMSigner, which expects file-path string,
Try changing your code like this:
ClassPathResource resource = new ClassPathResource(emailProps.getProperty("mail.smtp.dkim.privatekey"));
File file = resource.getFile();
String absolutePath = file.getAbsolutePath();
dkimSigner = new DKIMSigner(emailProps.getProperty("mail.smtp.dkim.signingdomain"), emailProps.getProperty("mail.smtp.dkim.selector"),absolutePath
);

loading a pdf in-browser from a file in the server file system?

How can I get a pdf located in a file in a server's directory structure to load in a browser for users of a Spring MVC application?
I have googled this and found postings about how to generate PDFs, but their answers do not work in this situation. For example, this other posting is not relevant because res.setContentType("application/pdf"); in my code below does not solve the problem. Also, this other posting describes how to do it from a database but does not show full working controller code. Other postings had similar problems that caused them not to work in this case.
I need to simply serve up a file (not from a database) and have it been viewable by a user in their browser. The best I have come up with is the code below, which asks the user to download the PDF or to view it in a separate application outside the browser. What specific changes can I make to the specific code below so that the user automatically sees the PDF content inside their browser when they click on the link instead of being prompted to download it?
#RequestMapping(value = "/test-pdf")
public void generatePdf(HttpServletRequest req,HttpServletResponse res){
res.setContentType("application/pdf");
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
ServletOutputStream outStream=null;
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(new File("/path/to", "nameOfThe.pdf")));
/*ServletOutputStream*/ outStream = res.getOutputStream();
//to make it easier to change to 8 or 16 KBs
int FILE_CHUNK_SIZE = 1024 * 4;
byte[] chunk = new byte[FILE_CHUNK_SIZE];
int bytesRead = 0;
while ((bytesRead = bis.read(chunk)) != -1) {outStream.write(chunk, 0, bytesRead);}
bis.close();
outStream.flush();
outStream.close();
}
catch (Exception e) {e.printStackTrace();}
}
Change
res.setHeader("Content-Disposition", "attachment;filename=report.pdf");
To
res.setHeader("Content-Disposition", "inline;filename=report.pdf");
You should also set the Content Length
FileCopyUtils is handy:
#Controller
public class FileController {
#RequestMapping("/report")
void getFile(HttpServletResponse response) throws IOException {
String fileName = "report.pdf";
String path = "/path/to/" + fileName;
File file = new File(path);
FileInputStream inputStream = new FileInputStream(file);
response.setContentType("application/pdf");
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "inline;filename=\"" + fileName + "\"");
FileCopyUtils.copy(inputStream, response.getOutputStream());
}
}

Resources