Download File XML with Spring boot - file

I'm trying to download files with a React front end, but the method in the controller doesn't download it
The method works because it doesn't launch any exception and the byte array works, but when I close the streams the download does not happen
public void downloadFile(#PathVariable("numeroOfferta") String numeroOfferta, #RequestParam(value="file") String file, HttpServletResponse response, HttpServletRequest req) throws IOException {
String filePathToBeServed =
File fileToDownload = new File(filePathToBeServed + file);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename="+file);
response.setStatus(HttpServletResponse.SC_OK);
try(FileInputStream in = new FileInputStream(fileToDownload);
OutputStream out = response.getOutputStream()) {
byte[] buffer = new byte[4096];
while ((in.read(buffer, 0, 4096)) != -1) {
out.write(buffer, 0, 4096);
}
out.flush();
out.close();
in.close();
}
NumeroOfferta is just a String that I need to go inside folders and file contains the name of the file I send from the web page.
I can't understand why it doesn't download the file I choose despite the method works. Thank you for every answer

Simply use Spring MVC ResponseEntity:
public void downloadFile(#PathVariable("numeroOfferta") String numeroOfferta,
#RequestParam(value="file") String file) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData(file, file);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
byte[] content = Files.readAllBytes(new File(filePathToBeServed + file).toPath());
return new ResponseEntity(content, headers, HttpStatus.OK);
}
That's it.

Related

How to save simpleCaptcha wav file in java

I need to save the file to play Simplecaptcha voice file on IOS and succeeded in saving the file in a folder I want.
But I tried to play the wav file in the folder(double click), It wasn't replayed.
Please help me
public static void saveAudio(final HttpServletRequest request, final HttpServletResponse response, final Sample sample) {
String fileName = request.getParameter("fileName");
try {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
AudioSystem.write(sample.getAudioInputStream(), AudioFileFormat.Type.WAVE, baos);
byte audioData[] = baos.toByteArray();
AudioFormat af = new AudioFormat(16000.0F, 16, 1,true, false); // simplecaptcha default setting
ByteArrayInputStream bais = new ByteArrayInputStream(audioData);
AudioInputStream ais = new AudioInputStream(bais, af , audioData.length);
AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File("/audio/"+fileName+".wav"));
} catch (IOException e) {
System.out.println(e);
}
}

Java - Load file as Template + append content in memory and manage byte[]

Im trying load a file in memory with a base information, append lines and include the result into a Zip file. In C# existes MemoryStream but, in java not.
the context of my application is load a stylesheet.css files with a pre-defined styles for add other styles that i get dinamically. Later i want add this content to a zip entry, and i need a byte[] that represent this content.
For the moment, i have the next lines, but i dont know as convert this to byte[]:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource("style.css").getFile());
OutputStreamWriter osw = new OutputStreamWriter( new FileOutputStream( file ) );
BufferedWriter writer = new BufferedWriter(osw);
I tried, with ByteArrayOutputStream but i can't completed all my requirements.
Any idea? im opne to other ideas for get my goal. I looking for CSSParser too, but i didn't see as I can append content and get a File document (byte[]) for to add to my zip file.
Finnaly, i didn't find other solution for my problem that convert the InputStream to ByteArrayOutputStream byte to byte.
I created the following methods:
Load template file into Input Stream and convert.
private ByteArrayOutputStream getByteArrayOutputStreamFor(String templateName) {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream inStream = classLoader.getResourceAsStream( templateName ); //file into resources directory
ByteArrayOutputStream baos = Utils.toOutputStream(inStream);
return baos;
} catch (Exception e) {
String msg = String.format("erro to loaf filetemplate {%s}: %s", templateName, e.getMessage());
throw new RuntimeException( msg, e.getCause() );
}
}
Copy the inputStream into a ByteArrayOutputStream byte to byte
public static final ByteArrayOutputStream toOutputStream(InputStream inStream) {
try {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
int byteReads;
while ((byteReads = inStream.read()) != -1) {
outStream.write(byteReads);
}
outStream.flush();
inStream.close();
return outStream;
} catch (Exception e) {
throw new RuntimeException("error message");
}
}
Finally, I append text to ByteArrayOutputStream
ByteArrayOutputStream baosCSS = getByteArrayOutputStreamFor( "templateName.css" );
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( baosCSS ) );
writer.append( "any text" );
writer.flush();
writer.close();
byte[] bytes = baosCSS.toByteArray()

Appengine not encoding request body in UTF-8

Appengine is not respecting req.setCharacterEncoding('UTF-8') when reading the request body.
This is how I read the request body
StringBuilder sb = new StringBuilder();
BufferedReader reader;
req.setCharacterEncoding("UTF-8");
reader = req.getReader();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
reader.close();
// parse body as JSON
data = new JSONObject(sb.toString());
Request with non-english character are parsed properly when running local test server (mvn appengine:devserver) but the version pushed to production does not parse non-english characters (mvn appengine:update); they are read as ?. This discrepancy is what I'm really confused about.
I also tried setting environment variables like
<env-variables>
<env-var name="DEFAULT_ENCODING" value="UTF-8" />
</env-variables>
in appengine-web.xml, but that doesn't change anything.
What could be causing the prod server to not parse non-english characters?
I don't really know why it wouldn't parse the body properly. I needed to parse the body to validate it before passing it onto my backend to do further processing. So, instead of parsing it in GAE, I relayed the body as a byte array to the backend, and let my backend handle the validation. This was the only working solution I can find.
Make sure you set the content-type header on your request correctly - on the client side, as in:
requestBuilder.setHeader("Content-type", "application/json; charset=utf-8");
I had a similar problem and this is the solution that worked for me. What I learned was that by the time the string is completely built (or appended to the string builder), it's too late because you need to specify the charset while reading the bytes and building the string.
The request.setCharacterEncoding doesn't work well in this regard, for reasons I'm unsure of.
The alternative I used for this was:
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
String body = stringBuilder.toString();
I got the input stream of bytes directly from the request and used a BufferedReader to read characters from this stream. I specified the charset here and this allowed me to build the string, while decoding in the respective charset.

JavaMail MimeBodyPart.SaveFile provide corrupted files

I'm using JavaMail Library to parser email mime message.
I'm trying to extract the attached files and save them to the local disk but the saved files are not valid and their size is different from the original. only *.txt file are saved ok but *.PDF or *.xlsx are not.
Can you please help me to fix the code?
My code is:
private static void Test3() {
String email_string = File_Reader.Read_File_To_String("D:\\8.txt");
MimeMessage mm = Email_Parser.Get_MIME_Message_From_Email_String(email_string);
Email_Parser.Save_Email_Attachments_To_Folder(mm,"D:\\TEST");
}
public static String Read_File_To_String(String file_path) {
byte[] encoded = new byte[0];
try {
encoded = Files.readAllBytes(Paths.get(file_path));
} catch (IOException exception) {
Print_To_Console(exception.getMessage(), true,false);
}
return new String(encoded, m_encoding);
}
public static MimeMessage Get_MIME_Message_From_Email_String(String email_string) {
MimeMessage mm = null;
try {
Session s = Session.getDefaultInstance(new Properties());
InputStream is = new ByteArrayInputStream(email_string.getBytes());
mm = new MimeMessage(s, is);
} catch (MessagingException exception) {
Print_To_Console(exception.getMessage(), true, false);
}
return mm;
}
public static void Save_Email_Attachments_To_Folder(MimeMessage mm, String output_folder_path) {
ArrayList<Pair<String, InputStream>> attachments_InputStreams = Get_Attachments_InputStream_From_MimeMessage(mm);
String attachment_filename;
String attachment_filename_save_path;
InputStream attachment_InputStream;
MimeBodyPart mbp;
for (Pair<String, InputStream> attachments_InputStream : attachments_InputStreams) {
attachment_filename = attachments_InputStream.getKey();
attachment_filename = Get_Encoded_String(attachment_filename);
attachment_filename_save_path = String.format("%s\\%s", output_folder_path, attachment_filename);
attachment_InputStream = attachments_InputStream.getValue();
try {
mbp = new MimeBodyPart(attachment_InputStream);
mbp.saveFile(attachment_filename_save_path);
} catch (MessagingException | IOException exception) {
Print_To_Console(exception.getMessage(), true, false);
}
}
}
You're doing something very strange in Save_Email_Attachments_To_Folder. (Not to mention the strange naming convention using both camel case and underscores. :-)) I don't know what the InputStreams are you're collecting, but constructing new MimeBodyParts based on them and then using the new MimeBodyPart to save the attachment to the file is almost certainly not what you want to do.
What exactly is Get_Attachments_InputStream_From_MimeMessage doing? Why iterate over the message to collect a bunch of InputStreams, then iterate over the InputStreams to save them? Why not iterate over the message to find the attachments and save them as you find them using the MimeBodyPart.saveFile method? Have you seen the msgshow.java sample program?

How to achieve mp3 stream using java Servlet

Goal: build a servlet so that when I type http://xxx.com/servpage?a.mp3 in browser, I can instantaneously start the playing of this mp3 file. Previously if I put the file on goDaddy as a static file, I can do that. My software can play it right away.
Using Servlet, I can ignore what is after ?, just want this page to return the mp3 dynamically (because in the future I may return any other files). What I got is a long wait (>20 seconds), and then got the player to play it.
I followed some examples, and noticed "attachment" in the example. However, if I remove it, the mp3 won't got played even. I am usign Google App Engine though, but just use the input/outputstream to return the http request. Anyone can help?
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException ,IOException {
res.setContentType("audio/mpeg3");
OutputStream os = res.getOutputStream();
res.setHeader("Content-Disposition", "attachment; filename="" + "a.mp3";");
res.setContentLength(1000000);
FileService fileService = FileServiceFactory.getFileService();
boolean lockForRead = false;
String filename = "/gs/" + BUCKETNAME + "/" + FILENAME;
AppEngineFile readableFile = new AppEngineFile(filename);
try{
FileReadChannel readChannel = fileService.openReadChannel(readableFile, lockForRead);
InputStream is = Channels.newInputStream(readChannel);
int BUFF_SIZE = 1024;
byte[] buffer = new byte[BUFF_SIZE];
try {
do {
int byteCount = is.read(buffer);
if (byteCount == -1)
break;
os.write(buffer, 0, byteCount);
os.flush();
} while (true);
} catch (Exception excp) {
} finally {
os.close();
is.close();
}
readChannel.close();
} catch(Exception e){
}
}
Few notes:
You are not doing "streaming". Just a plain file download.
To do blob (file) serving, you do not need to read the blob from BlobStore as you do with AppEngineFile. Just serve it directly with blobstoreService.serve(blobKey). See Serving a Blob for an example.
You can get the BlobKey needed in 2. via fileService.getBlobKey(readableFile).
Update:
Just realized you are using Google Cloud Storage, not BlobStore.
In GS, if ACLs are properly set, files are publicly visible via: http://commondatastorage.googleapis.com/BUCKETNAME/FILENAME
Since you are not doing any authentication, you could publicly share the file on GS and then in your servlet just do a 301 redirect to public URL of the file.

Resources