Spring and serving files from outside of the web server - spring

I want spring to serve certain files from the /tmp... directory, the specific directory isn't determined until shortly after the server starts so using <mvc:resources location="/images/**" mapping="/absolute/path/to/image/dir"/> won't seemingly work.

As Dave Newton noted - stream them from a controller. A very basic implementation:
#RequestMapping("/static/temp/{path}")
public void getResource(#PathVariable path, OutputStream os) {
//TODO proper IO management
InputStream is = new BufferedInputStream(new FileInputStream("/temp/" + path));
IOUtils.copy(is, os);
}

I do something like this:
#RequestMapping(value="/staticFile/{id}", method = RequestMethod.GET)
public void getPhotoRide2(HttpServletResponse response, #PathVariable int id) {
try {
FileInputStream in = new FileInputStream("your file");
OutputStream out = response.getOutputStream();
response.setContentType("your mime type");
byte[] buf = new byte[1024];
int count = 0;
while ((count = in.read(buf)) >= 0) {
out.write(buf, 0, count);
}
in.close();
out.flush();
out.close();
} catch (Exception e) {}
}

Related

How to sanitize request object in the #restcontroller

I'm doing a static code analysis using checkmarx, which gave me medium vulnerabilities for #RequestBody.
Will place a sample code below, could someone help me fixing this issue.
#RestController
#RequestMapping("/api")
#Slf4j
#Validated
public class Myclass {
#Autowired
SplitClass split;
#PostMapping(path = "/something", consumes = "application/json", produces = "application/json")
public int splitter(#RequestBody SplitRequestVO **splitReq**) {
int response = 0;
try {
int value = split.methodName(splitReq);
if(value == 1) {
response = 1;
}else {
response = 0;
}
}catch(Exception e) {
log.error("Excpetion in the MY Class controller" +e.getMessage());
}
return response;
}
}
Every time it is showing error with this util class. please check whats wrong in this class.
#Slf4j
public class FileUtil {
private FileUtil() {
throw new IllegalArgumentException("FileUtil.class");
}
public static void createFileFromBytes(String fileName, byte[] bytes) throws IOException {
File file = new File(fileName);
try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytes);
fos.flush();
} catch (IOException exc) {
log.error("Exception in creating file from bytes : "+exc.getMessage());
}
}
public static void deleteFile(String fileName) {
log.info("Entry into deleteFile method.");
try {
File file = new File(fileName);
if (file.exists()) {
Files.delete(file.toPath());
if (log.isDebugEnabled())
log.debug("file deleted:" + fileName);
}
} catch (Exception e) {
log.error("Exception in deleting the file : "+e.getMessage());
}
log.info("Exit from deleteFile method ");
}
public static byte[] getBytesFromFile(File file) throws IOException {
log.info("Entry into getBytesFromFile method");
byte[] bytes = null;
try (InputStream is = new FileInputStream(file)) {
long length = file.length();
if (length > 2147483647L) {
log.error("File Too large:" + file.getName());
}
bytes = new byte[(int) length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0)
offset += numRead;
if (offset < bytes.length)
throw new IOException("Could not completely read file " + file.getName());
} catch (Exception e) {
log.error("Exception in getBytesFromFile : "+e.getMessage());
}
log.info("Exit from getBytesFromFile method ");
return bytes;
}
public static byte[] getBytesFromFile(String fileName) throws IOException {
File file = new File(fileName);
return getBytesFromFile(file);
}
}
Here im facing the vulnerability issue to fix in the block letters. Appreciated foy help.
Thanks in advance.

How to return an Image to browser in rest API in JAVA?

I want to an image while I hit an API like localhost:8080:/getImage/app/path={imagePath}
While I hit this API it will return me an Image.
Is this possible?
Actually, I have tried this but it is giving me an ERROR.
Here is my code,
#GET
#Path("/app")
public BufferedImage getFullImage(#Context UriInfo info) throws MalformedURLException, IOException {
String objectKey = info.getQueryParameters().getFirst("path");
return resizeImage(300, 300, objectKey);
}
public static BufferedImage resizeImage(int width, int height, String imagePath)
throws MalformedURLException, IOException {
BufferedImage bufferedImage = ImageIO.read(new URL(imagePath));
final Graphics2D graphics2D = bufferedImage.createGraphics();
graphics2D.setComposite(AlphaComposite.Src);
// below three lines are for RenderingHints for better image quality at cost of
// higher processing time
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graphics2D.drawImage(bufferedImage, 0, 0, width, height, null);
graphics2D.dispose();
System.out.println(bufferedImage.getWidth());
return bufferedImage;
}
My ERROR,
java.io.IOException: The image-based media type image/webp is not supported for writing
Is there any way to return an Image while hitting any URL in java?
You can use IOUtils. Here is code sample.
#RequestMapping(path = "/getImage/app/path/{filePath}", method = RequestMethod.GET)
public void getImage(HttpServletResponse response, #PathVariable String filePath) throws IOException {
File file = new File(filePath);
if(file.exists()) {
String contentType = "application/octet-stream";
response.setContentType(contentType);
OutputStream out = response.getOutputStream();
FileInputStream in = new FileInputStream(file);
// copy from in to out
IOUtils.copy(in, out);
out.close();
in.close();
}else {
throw new FileNotFoundException();
}
}
i didn't test it due to i don't have the environment in this machine, but logically it should work like the following, read it as input stream and let your method returns #ResponseBody byte[]
#GET
#Path("/app")
public #ResponseBody byte[] getFullImage(#Context UriInfo info) throws MalformedURLException, IOException {
String objectKey = info.getQueryParameters().getFirst("path");
BufferedImage image = resizeImage(300, 300, objectKey);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
return IOUtils.toByteArray(is);
}
UPDATE
depending on #Habooltak Ana suggestion there is no need to create an input stream, the code should be look like the following
#GET
#Path("/app")
public #ResponseBody byte[] getFullImage(#Context UriInfo info) throws
MalformedURLException, IOException {
String objectKey = info.getQueryParameters().getFirst("path");
BufferedImage image = resizeImage(300, 300, objectKey);
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", os);
return os.toByteArray();
}
Just return a file object with correct HTTP-Headers (Content-Type and Content-Disposition) will work in most cases/environments.
Pseudocode
File result = createSomeJPEG();
/*
e.g.
RenderedImage rendImage = bufferedImage;
File file = new File("filename.jpg");
ImageIO.write(rendImage, "jpg", file);
*/
response().setHeader("Content-Disposition", "attachment;filename=filename.jpg;");
response().setHeader("Content-Type", "image/jpeg");
return ok(result);
See also:
file downloading in restful web services
what's the correct way to send a file from REST web service to client?

Should inputstream be closed explicitly when uploading file in jersey multipart?

I use Jersey multipart to upload file in controller
Here is the typical code case:
#Path("/file")
public class UploadFileService {
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(
#FormDataParam("file") InputStream uploadedInputStream,
#FormDataParam("file") FormDataContentDisposition fileDetail) {
String uploadedFileLocation = "d://uploaded/" + fileDetail.getFileName();
// save it
writeToFile(uploadedInputStream, uploadedFileLocation);
String output = "File uploaded to : " + uploadedFileLocation;
return Response.status(200).entity(output).build();
}
// save uploaded file to new location
private void writeToFile(InputStream uploadedInputStream,
String uploadedFileLocation) {
try {
OutputStream out = new FileOutputStream(new File(
uploadedFileLocation));
int read = 0;
byte[] bytes = new byte[1024];
out = new FileOutputStream(new File(uploadedFileLocation));
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have read many example code online, and the inputstream is not closed.
My question is that should I close the uploadedInputStream explicitly or manually? And why?

jaxrs.ResteasyClient download file

Request a webAPI that gives me a ZIP file. Now my question:
How to download that file with jaxrs.ResteasyClient. Here is what I have but it does not work for me.
// In
Reader reader = client.target(url).request().get().readEntity(Reader.class);
BufferedReader bufferedReader = new BufferedReader(reader);
// Out
File out = new File("C:\\tmp\\test.zip");
FileWriter fileWriter = new FileWriter(out);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
String s = null;
while (true) {
s = bufferedReader.readLine();
if (s == null) {
break;
}
bufferedWriter.write(s);
}
bufferedWriter.flush();
bufferedWriter.close();
bufferedReader.close();
I have no idea if this makes sense, but I do not find any good documentation about reading a file instead of a bean object.
Resolved this issue by not using jaxrs.ResteasyClient. Apache HTTPClient was my friend!
private void getFileByURL(String url, String target) throws URISyntaxException, IOException {
HttpClientBuilder builder = HttpClients.custom().build();
CloseableHttpClient client = builder.build();
HttpResponse response = client.execute(new HttpGet(new URI(url)));
BufferedInputStream bufferedInputStream = new BufferedInputStream(response.getEntity().getContent());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File(target)));
int inByte;
while ((inByte = bufferedInputStream.read()) != -1) {
bufferedOutputStream.write(inByte);
}
bufferedInputStream.close();
bufferedOutputStream.close();
EntityUtils.consume(response.getEntity());
}

Uploading file using Spring REST API

I have my controller like this, i am using POSTMAN REST client for upload pdf file. setting content-type: multipart/form-data;boundary=randomBoundaryNotInAnyOfParts
It is creating the file but not writing anything in it. Am i missing something here?
#RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
public #ResponseBody String upload(HttpServletRequest request) {
InputStream is = null;
OutputStream out = null;
try {
is = request.getInputStream();
byte[] b = new byte[1024];
out = new FileOutputStream(new File("C:\\tmp\\upload.txt"));
out.write(b);
} catch (IOException e) {
e.printStackTrace();
} finally{
try{
if(out != null){
out.close();
}
if(is != null){
is.close();
}
}catch(IOException io){
io.printStackTrace();
}
}
return null;
}
Thanks,
Vinay
Your byte[] is empty hence it is writing nothing in the file. Get content of the request into the byte[] and then write it into file.
Or you can use BufferedWriter also it is more fast.
Thanks,
Brijesh

Resources