FTP downloaded image is not displayed correctly - java

I save user uploaded images in FTP.
FTP service is running on server Server-A. The actual problem is when I want to see the uploaded image from the web application running in my local host everything works, but when I deploy the local application to Tomcat running on the same server Server-A, images are not displayed correctly.
The picture when I run the web application in local Tomcat:
The same picture when I run the web application in the remote Tomcat:
You can see that the second image is not displayed correctly. Also want to mention that the FTP is the same one.
I am using Spring with Apache FtpClient library for image upload/download functionality.
Controller source code:
#RequestMapping(value = "/{id:\\d+}/image", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
protected byte[] getUserImage(BaseForm form,
#PathVariable("id") int userId) {
try {
User user = checkToken(form.getToken());
log.info("/users/{id}/image [GET]. User: " + user + ", form: " + form + ", User id: " + userId);
FileWrapper image = service.getUserImage(userId);
if(image != null) {
return ftpService.downloadFtpFile(image.getName());
}
}
catch(Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
FtpService source code:
public byte[] downloadFtpFile(String filePath) throws IOException {
FTPClient client = new FTPClient();
try {
client.connect(host, port);
if(!client.login(username, password)) {
throw new AdminException("Invalid ftp username/password");
}
client.enterLocalPassiveMode();
try(ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
client.retrieveFile(filePath, outputStream);
return outputStream.toByteArray();
}
}
catch(Exception e) {
log.error(e.getMessage(), e);
}
finally {
if(client.isConnected()) {
client.logout();
client.disconnect();
}
}
return null;
}
Thanks in advance!

If you've not set the FTP transfer to be binary (as opposed to ASCII) it will "convert the line endings" (or what it thinks are line endings) which will corrupt the picture.

Related

Send/Receive images via REST

I am using grizzly for java rest service and consuming these web services in an android app.
Its working fine as far as "text" data is concerned.
Now I want to load the images(from server) in my android application, using this rest service and also allow the users to update image from the device.
I have tried this code
#GET
#Path("/img3")
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getFile()
{
File file = new File("img/3.jpg");
return Response.ok(file, MediaType.APPLICATION_OCTET_STREAM).header("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"") // optional
.build();
}
The code above allow me to download the file, but is it possible to display result in broswer? like this
http://docs.oracle.com/javase/tutorial/images/oracle-java-logo.png
Solution of Part 1:
I have made the changes in my code as suggested by Shadow
#GET
#Path("/img3")
#Produces("image/jpg")
public Response getFile(#PathParam("id") String id) throws SQLException
{
File file = new File("img/3.jpg");
return Response.ok(file, "image/jpg").header("Inline", "filename=\"" + file.getName() + "\"")
.build();
}
Requested image will be displayed in browser
Part 2:
The code used to convert back Base64 encoded image
#POST
#Path("/upload/{primaryKey}")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces("image/jpg")
public String uploadImage(#FormParam("image") String image, #PathParam("primaryKey") String primaryKey) throws SQLException, FileNotFoundException
{
String result = "false";
FileOutputStream fos;
fos = new FileOutputStream("img/" + primaryKey + ".jpg");
// decode Base64 String to image
try
{
byte byteArray[] = Base64.getMimeDecoder().decode(image);
fos.write(byteArray);
result = "true";
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return result;
}

To transfer a file from one windows machine(Local) to another windows machine(Server)

I want to write a code which will transfer a file from one machine to another in Linux and Windows platforms.
I used ssh libraries (sftp connections) to transfer file to Linux machine.
Now, I wanted to do same for Windows machine. Can someone please help me with this?
Description: To transfer a file from one windows machine(Local) to another windows machine(Server).
Also, I checked with FTP libraries in java, but I wasn't able to create a directory outside the folder created/shared for ftp.
Below is my code I am using currently for ftp.
FTPClient ftpClient = new FTPClient();
FileInputStream inputStream = null;
try {
// pass directory path on server to connect
ftpClient.connect("172.30.17.17");
// pass username and password, returned true if authentication is
// successful
boolean login = ftpClient.login("Administrator", "Password1!");
if (login) {
System.out.println("Connection established...");
inputStream = new FileInputStream("C:/Demo/abcd.txt");
boolean uploaded = ftpClient.storeFile("uploadedFile3.txt",inputStream);
if (uploaded) {
System.out.println("File uploaded successfully !");
} else {
System.out.println("Error in uploading file !");
}
ftpClient.makeDirectory("C:/Demo1"); //Unable to create this here
System.out.println("Folder Created successfully !");
// logout the user, returned true if logout successfully
boolean logout = ftpClient.logout();
if (logout) {
System.out.println("Connection close...");
}
} else {
System.out.println("Connection fail...");
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Missing bytes when calling HttpServletRequest.getInputSteam() method

I am creating Restful web service that accepts any file and saves it into filesystem. I am using Dropwizard to implement the service and Postman/RestClient to hit the request with data. I am not creating multipart (form-data) request.
Every thing is working fine except the file saved has first character missing. Here is my code for calling the service method and saving it into file system:
Input Request:
http://localhost:8080/test/request/Sample.txt
Sample.txt
Test Content
Rest Controller
#PUT
#Consumes(value = MediaType.WILDCARD)
#Path("/test/request/{fileName}")
public Response authenticateDevice(#PathParam("fileName") String fileName, #Context HttpServletRequest request) throws IOException {
.......
InputStream inputStream = request.getInputStream();
writeFile(inputStream, fileName);
......
}
private void writeFile(InputStream inputStream, String fileName) {
OutputStream os = null;
try {
File file = new File(this.directory);
file.mkdirs();
if (file.exists()) {
os = new FileOutputStream(this.directory + fileName);
logger.info("File Written Successfully.");
} else {
logger.info("Problem Creating directory. File can not be saved!");
}
byte[] buffer = new byte[inputStream.available()];
int n;
while ((n = inputStream.read(buffer)) != -1) {
os.write(buffer, 0, n);
}
} catch (Exception e) {
logger.error("Error in writing to File::" + e);
} finally {
try {
os.close();
inputStream.close();
} catch (IOException e) {
logger.error("Error in closing input/output stream::" + e);
}
}
}
In output, file is saved but first character from the content is missing.
Output:
Sample.txt:
est Content
In above output file, character T is missing and this happens for all the file formats.
I don't know what point I am missing here.
Please help me out on this.
Thank You.

Fail to upload file using ftp4j

I'm using ftp4j as FTP client.
FTPClient client = new FTPClient();
client.connect("86.22.11.178");
client.login("usr", "pwd");
client.changeDirectory("/dir");
client.upload(file);
It works fine at localhost, but it does not work when enclosed in a JSF web application deployed on a web server. I succeeded to do connect and login, when the code reaches to the upload command, it just skips on that and does nothing. No exception is been thrown.
There is full conectivity to the FTP server, it can't be a problem. I have also set chmod 777 permission on the files and they belong to the same owner.
This code worked on a Windows machine, could it be that machines running on Linux have different "rules"?
Your code seems to be correct. Try to find out the FTP error which its throws. Sometimes timeout may happens, which i faced!!!
import org.apache.commons.net.ftp.;
import java.io.;
/**
* This class is used to demonstrate the usage of the Jakarta Commons Net package
*/
public class TestFTP {
/** Creates a new instance of TestFTP */
public TestFTP() {
}
/**
* main - Unit test program
* #param args Command line arguments
*
*/
public static void main(String args[]) {
try {
String ftpHost = "157.227.38.131";
String ftpUserName = "firebird";
String ftpPassword = "tcs#12345";
String ftpRemoteDirectory = "/etc/vlp/uploaded_files";
String fileToTransmit = "c:\\temp\\VLPDYN18022010174439.an";
//Create a Jakarta Commons Net FTP Client object
FTPClient ftp = new FTPClient();
//A datatype to store responses from the FTP server
int reply;
//
//Connect to the server
//
ftp.connect(ftpHost);
//
// After connection attempt, you should check the reply code to verify success.
//
reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
try {
ftp.disconnect();
} catch (Exception e) {
System.err.println("Unable to disconnect from FTP server " +
"after server refused connection. "+e.toString());
}
throw new Exception ("FTP server refused connection.");
}
System.out.println("Connected to " + ftpHost + ". "+ftp.getReplyString());
//
//Try to login
//
if (!ftp.login(ftpUserName, ftpPassword)) {
throw new Exception ("Unable to login to FTP server " +
"using username "+ftpUserName+" " +
"and password "+ftpPassword);
}
System.out.println(ftp.getReplyString());
System.out.println("Remote system is " + ftp.getSystemName());
//
//Set our file transfer mode to either ASCII or Binary
//
//ftp.setFileType(FTP.ASCII_FILE_TYPE);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//
//Change the remote directory
//
if (ftpRemoteDirectory != null && ftpRemoteDirectory.trim().length() > 0) {
System.out.println("Changing to FTP remote dir: " + ftpRemoteDirectory);
ftp.changeWorkingDirectory(ftpRemoteDirectory);
reply = ftp.getReplyCode();
if(!FTPReply.isPositiveCompletion(reply)) {
throw new Exception ("Unable to change working directory " +
"to:"+ftpRemoteDirectory);
}
}
//
//Get the file that we will transfer and send it.
//
File f = new File(fileToTransmit);
System.out.println("Storing file as remote filename: " + f.getName());
boolean retValue=true;
try{
retValue = ftp.storeFile(f.getName(), new FileInputStream(f));
}catch(Exception e){e.printStackTrace();}
if (!retValue) {
throw new Exception ("Storing of remote file failed. ftp.storeFile() returned false.");
}
//Disconnect from the FTP server
//
try {
//ftp.logout();
ftp.disconnect();
} catch (Exception exc) {
System.err.println("Unable to disconnect from FTP server. " + exc.toString());
}
} catch (Exception e) {
System.err.println("Error: "+e.toString());
}
System.out.println("Process Complete.");
System.exit(0);
}
}

how to use FTP File Upload in JSF?

I would like to use org.apache.commons.net.ftp.FTPClient in my JSF application. How client side (Web Browser) upload to my web application server for large file. Even if I use RichFaces File Upload or PrimeFaces File Upload, client browser can use HTTP Protocol. How can I support FTP Protocol to client browser? Could you provide the better way?
Cause : the application user cannot direct access to our Repository Server(SVN). Firstly, they have to upload the files to our application on Web AS. And then, the application checkin/chekout to RepositoryServer. The application user can upload the file which has 500M to 2G at least. That's why, I am thinking, how can I support FTP Protocol to browser client' to be faster. Otherwise, am I thinking wrong?
In order to be able to send a file to a FTP server, you obviously need a FTP client.
However, a webbrowser is a HTTP client, not a FTP client. This is a natural functional design limitation of the webbrowser. JSF look like a magician, but here it really can't do anything for you. It intercepts on HTTP requests/responses only.
Indeed, you're thinking wrong. Just stick to uploading the file the usual HTTP way. If you're absolutely positive that you need FTP for this for some reason, then your best bet is most likely homebrewing a Java Applet for this, but this would after all be plain clumsy.
First do HTTP upload through primefaces to a temporary directory. then through org.apache.commons.net.ftp.FTPClient or through sun.net.ftp.FtpClient upload to the required FTP Server.
Below is an example;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import sun.net.ftp.FtpClient;
/**
*
* #author fali
*/
public class FtpUtil {
public String server, username,password, remote, remotedir, local;
FtpClient ftp;
public static int BUFFER_SIZE = 10240;
public FtpUtil(){
server = "localhost";
username = "anonymous";
password = " ";
remotedir = "/incoming";
remote = "dvs.txt";
local = "C:\\dvs.txt";
}
protected void putFile() {
if (local.length() == 0) {
System.out.println("Please enter file name");
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
File f = new File(local);
int size = (int) f.length();
System.out.println("File " + local + ": " + size + " bytes");
System.out.println(size);
FileInputStream in = new FileInputStream(local);
OutputStream out = ftp.put(remote);
int counter = 0;
while (true) {
int bytes = in.read(buffer);
if (bytes < 0)
break;
out.write(buffer, 0, bytes);
counter += bytes;
System.out.println(counter);
}
out.close();
in.close();
} catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
}
public String Upload(){
String result="";
try{
ftp = new FtpClient(server);
ftp.login(username, password);
System.out.println(ftp.welcomeMsg);
ftp.cd(remotedir);
putFile();
disconnect();
}catch(Exception ex){
System.out.println(ex);
result = "Error : "+ex;
}
return "";
}
protected void disconnect() {
if (ftp != null) {
try {
ftp.closeServer();
} catch (IOException ex) {
}
ftp = null;
}
}
}
In your managedbean/controller;
public String create() {
System.out.println("Request Button Clicked");
try {
// generate reference number
//current.setReferenceno(genReferenceNo());
// add to database
//getFacade().persist(current);
// upload to ftp
FtpUtil fu = new FtpUtil();
fu.Upload();
// show reference number
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("QueueCreated"));
JsfUtil.addSuccessMessage("Your Reference No. is :" + current.referenceno);
current = null;
// try {
// System.out.println("Redirecting");
// FacesContext.getCurrentInstance().getExternalContext().dispatch("/");
// } catch (Exception ex) {
// System.out.println(ex);
// }
return "";
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
return null;
}
}
and some thing like this in your page;
<br />
<ppctu:commandButton action="#{appointmentController.create}" type="Submit" value="Request" />

Categories

Resources