File Upload Issues in Jersey RestFull Service - java

I'm using jersey as backend in one of my applications. I am having trouble in uplaoding file using jersey. I have used the common file upload code available on google.
#POST
#Path("/setProfileImage")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_HTML)
public String setProfileImage(
#FormDataParam("profileimage") InputStream uploadedInputStream,
#QueryParam("myemail") String myemail) throws IOException {
String contextRoot = uri.getBaseUri().getPath();
String uploadedFileLocationOrig = httpRequest.getSession().getServletContext().getRealPath("") + "/images/" + myemail + "_orig.png";
FileUtils.copyInputStreamToFile(uploadedInputStream, new File(uploadedFileLocationOrig));
return "true";
}
The code runs without error, but the image copied at the destination is not valid and an empty file is returned when I hit this file using its url.
Any ideas what I'm doing wrong here?

I finally figured it out, the version of Jersey was pretty old i.e. 1.17 and following code worked like a charm for me
#POST
#Path("/setProfileImage")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_HTML)
public String setProfileImage(
final MimeMultipart file,
#QueryParam("myemail") String myemail) throws IOException, javax.mail.MessagingException {
String uploadedFileLocationOrig = httpRequest.getSession().getServletContext().getRealPath("") + "/images/" + myemail + "_orig.png";
FileUtils.copyInputStreamToFile(file.getBodyPart(0).getInputStream(), new File(uploadedFileLocationOrig));
return "true";
}

Related

Response returning status but not data

I have Jersey endpoint that is attempting to create a CSV file and return it via GET; however, all these attempts end up with the same result - the ok status (200) is returned but no file.
#GET
#Path("/research")
#Produces(MediaType.TEXT_PLAIN)
public Response dumpAllResearchAndSupportData() {
QuickDumpBuilderService dumpBuilderService = getQuickDumpService();
List<DevelopmentProposal> researchOtherProposals = dumpBuilderService.getAllResearchRecords();
String csvLocation = dumpBuilderService.buildCSV(researchOtherProposals);
File file = new File(csvLocation);
String filename = "reserach_" + UUID.randomUUID().toString() + ".csv";
return Response.ok(file, MediaType.TEXT_PLAIN).header("Content-Disposition", "attachment; filename=" + filename).build();
}
My CSV file is properly created, but it fails to be returned along with the response.
Notice above, I'm writing the CSV to a temporary location in my tomcat folder and then passing the path to that file back and then attempting to read that from the location here.
Another attempt with the same result where instead of writing the CSV to temp location, I'm just trying to write the ByteArrayOutputStream to the response object.
#GET
#Path("/research")
#Produces(MediaType.APPLICATION_JSON)
public Response dumpAllResearchAndSupportData() {
QuickDumpBuilderService dumpBuilderService = getQuickDumpService();
// Step 1. Retrieve all research and other proposals
List<DevelopmentProposal> researchOtherProposals = dumpBuilderService.getAllResearchRecords();
// Step 2. Create CSV File
ByteArrayOutputStream csvBaos = dumpBuilderService.buildCSV(researchOtherProposals);
// Step 3. Create spreadsheet
ByteArrayOutputStream excelBaos = dumpBuilderService.createExcelSpreadsheet(csvBaos, servlet);
// Step 4. Return spreadsheet
Response.ResponseBuilder response = Response.ok(excelBaos);
return response.build();
Another attempt where I added this "writer" into the response. This attempt generated an error that a "MessageBodyWriter for the ByteArrayStream was not found." That prompted the attempt below.
#GET
#Path("/research")
#Produces(MediaType.TEXT_PLAIN)
public Response dumpAllResearchAndSupportData() {
....
// Step 4. Return spreadsheet
return Response.ok(getOut(csvBaos.toByteArray())).build();
}
private StreamingOutput getOut(final byte[] csvBytes) {
return new StreamingOutput() {
#Override
public void write(OutputStream out) throws IOException, WebApplicationException {
out.write(csvBytes);
out.flush();
}
};
}
I've looked at the following similar answers, and I've attempted all of them with no success.
Not sure what I'm doing wrong - I suspect that it's something to do with how I setup my endpoint and defer to the Java REST API experts here.
File download/save from a Jersey rest api call using ANGULARJS . file is attached with response as "Content-Disposition"
Download CSV file via Rest
jersey - StreamingOutput as Response entity
Thanks for your help.

How multipart form data upload handles large file

I am using quarkus framework for java application.I have created 2 rest apis for consuming file data.
#POST
#Path("file")
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
#Produces(MediaType.APPLICATION_JSON)
public Response uploadFile(byte[] fileData) {
System.out.println("Received file of size = " + fileData.length);
String s = new String(fileData);
return Response.ok().build();
}
#POST
#Path("files")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.APPLICATION_JSON)
public void uploadFile(#MultipartForm FormData fileData) throws IOException {
System.out.println("Received file of size = ");
System.out.println(fileData.file.length());
return Response.ok().build();
}
FormData class looks like this
public class FormData {
#FormParam("file")
#PartType(MediaType.APPLICATION_OCTET_STREAM)
public File file;
}
While both of these rest endpoint works fine for small files. But if i upload file as big as 700MB first endpoint fails with OOM issue while file upload with multipart-form succeed. Can someone explain how memory is managed in case of multipart-form upload?
The second API saves the file to a temp file on the file system. (which I believe is being automatically deleted when the call completes and the File is closed)
The first API saves the file to a byte stream (array) in memory - that's why you're getting an OOM error.

Java-spingboot how to save text document via REST-API?

I am a beginner programmer, help with the implementation of uploading a text file via rest-api java.
I have already implemented the simplest action - unload a file from the server, here is my code:
#GetMapping(value = "/file/{filename:.+}")
public ResponseEntity<Resource> unloadFile(#PathVariable String filename) {
Resource file = storageService.loadAsResource(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFilename() + "\"").body(file);
}
I can test the file unload by simply following the link!
I cannot test the upload. I find it difficult to write tests. Please tell me if I got a working code and maybe there is a better way to upload. My code upload:
#PostMapping(value = "/file")
public ResponseEntity<MultipartFile> uploadFile(MultipartFile file) {
storageService.store(file);
return ResponseEntity.ok().body(file);
}
Thank you so much!
To upload the file/files using spring boot application we use same method that we had for servlet containers. In your controller
#PostMapping("/uploadFile")
public ResponseEntity<Object> uploadFile(#RequestParam("file") MultipartFile file) {
String fileName = yourStorageService.storeFile(file);
String = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.toUriString();
//You can even generate download links.
return new ResponseEntity<Object>(HttpStatus.Ok, "Uploaded", fileDownloadUri);
}
To download the files:
#GetMapping("/downloadFile/{fileName}")
public ResponseEntity<Resource> downloadFile(#PathVariable String fileName, HttpServletRequest request) {
// Load file as Resource from DB or local
Resource resource = fileStorageService.loadFileAsResource(fileName);
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
.body(resource);
For #PostMapping(value = "/file") endpoint , its best to return a success/error status instead of returning the file,if file is larger ..it takes time to return back.
Better to return success state. 200 ok.

Jersey REST image GET issue

i have a simple question.
Lets say that i want to download multiple specific images when i call my GET method in my REST API from a directory, given that i have their names. eg.
../folder
name1.png
name2.png
name3.png
name4.png
And i want to download name2.png, name3.png.
Everything that i could dig up was regarding only 1 image per call, like this:
#Path("/image")
public class ImageService {
private static final String FILE_PATH = "c:\\picture.png";
#GET
#Path("/get")
#Produces("image/png")
public Response getFile() {
File file = new File(FILE_PATH);
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition",
"attachment; filename=image_from_server.png");
return response.build();
}
}
The thing that has come to my mind is to send a zip or something like that. Could anyone tell me if this is possible, and if it is how to do it? Thanks.

How to read uploaded file details in Jersey

I have implemented REST service for upload multiple files into server.But the problem was that i can not get file details if i use FormDataMultiPart in the REST service.I can get the file content.like wise i tried to get file details like following and it gave me an error saying not supported.
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void upload(FormDataMultiPart formParams)
{
Map<String, List<FormDataBodyPart>> fieldsByName = formParams.getFields();
//Assume i am sending only files with the request
for (List<FormDataBodyPart> fields : fieldsByName.values())
{
for (FormDataBodyPart field : fields)
{
InputStream is = field.getEntityAs(InputStream.class);
String fileName = field.getName();
field.getMediaType();
//Those work perfectly
//This gave me an error
FormDataContentDisposition f=field.getEntityAs(FormDataContentDisposition .class);
System.out.println(f.getFileName());
}
}
}
Please let me know how can i get files details like type,name,size for each uploaded files if use FormDataMultiPart.
I was able to access file details finally here is the code snippet.
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
public void upload(FormDataMultiPart formParams)
{
Map<String, List<FormDataBodyPart>> fieldsByName = formParams.getFields();
//Assume i am sending only files with the request
for (List<FormDataBodyPart> fields : fieldsByName.values())
{
for (FormDataBodyPart field : fields)
{
InputStream is = field.getEntityAs(InputStream.class);
String fileName = field.getName();
field.getMediaType();
//This working fine
FormDataContentDisposition f=field.getFormDataContentDisposition();
System.out.println(f.getFileName());
}
}
}

Categories

Resources