I am using this webservice to upload a file using jersey
public class upload {
#POST
#Path(value = "upload")
#Consumes("image/jpg")
public Response uploadPng(File file) throws IOException {
file = new File("C:/Users/Marwa/Desktop/Capture.jpg");
String uploadedFileLocation = "C:/Users/Desktop/" + file.getName();
DataInputStream diStream =new DataInputStream(new FileInputStream(file));
long len = (int) file.length();
byte[] fileBytes = new byte[(int) len];
int read = 0;
int numRead = 0;
while (read < fileBytes.length && (numRead =diStream.read(fileBytes, read,fileBytes.length - read)) >= 0) {
read = read + numRead;
}
// save it
writeToFile(diStream, uploadedFileLocation);
System.out.println("File uploaded to : " + uploadedFileLocation);
return Response.status(200).entity(file).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();}}}
When I execute my code i get a 405 error !!
Are there any suggestions to this issue?
public Response uploadPng(FormDataMultiPart multiPart) throws IOException {
You should pass the FormDataMultiPart parameter in the method which you are calling while uploading file.
Not sure if this is perfect solution. But solved similar problem by following approach.
First thing, you should use
public Response uploadPng(FormDataMultiPart multiPart) throws IOException {
Next to avoid 405 error add
#Produces(MediaType.TEXT_PLAIN)
above uploadpng method.
Related
I am trying to combine 2 files in one zip file
myMainMethod
private void downloadFileByTypeInner(StaticDocument file, String productCode, int productVersion) throws IOException, TechnicalException {
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpServletResponse response = (HttpServletResponse) ec.getResponse();
String distrib = MultinetFrontHelper.getDefaultDitrib();
String realPath = findRealPath(ec, file.getPath().replace("{DISTRIB}", distrib));
String downloadName = file.getDownloadFileName() != null ? file.getDownloadFileName() : file.getPath();
if (file.getAction() == null || file.getAction().trim().isEmpty() || file.getAction().equals("download")) {
List<java.io.File> l = new ArrayList<>();
java.io.File f = new java.io.File(realPath);
l.add(f);
if(file.getDependOnCodeFiles() != null){
String[] paths = file.getDependOnCodeFiles().split(",");
for (String codefile : paths) {
StaticDocument file2 = libraryBusinessService.getFileByCodeType(codefile, productCode, productVersion);
if((file2 != null)) {
l.add(new java.io.File(findRealPath(ec, file2.getPath())));
}
}
downloadName = downloadName.substring(0,downloadName.lastIndexOf("."))+".zip";
}
InputStream pathStream = DownLoadHelper.getStreamAllFiles(l.toArray(new java.io.File[0]), downloadName);
if (pathStream != null) {
if(downloadName.indexOf('/')!=-1) {
downloadName = downloadName.substring(downloadName.lastIndexOf('/')+1);
}
DownLoadHelper.downLoadFile(response, pathStream, downloadName);
} else {
logger.error("Le fichier " + realPath + " est introuvable!");
throw new TechnicalException(CodeError.CODE_ERTEMO0001, null);
}
} else if (file.getAction().equals("open")) {
final FacesContext ctx = FacesContext.getCurrentInstance();
final ExternalContext extContext = ctx.getExternalContext();
try {
extContext.redirect(file.getPath());
} catch (final IOException ioe) {
throw new FacesException(ioe);
}
}
}
getStreamAllFiles
public static InputStream getStreamAllFiles(final File[] listDoc, String nameZIP) throws IOException {
InputStream stream = null;
if (listDoc != null) {
if (listDoc.length == 1) {
stream = new ByteArrayInputStream(FileUtils.readFileToByteArray(listDoc[0]));
} else if (listDoc.length > 1) {
try( ByteArrayOutputStream baos = new ByteArrayOutputStream();ZipOutputStream zos = new ZipOutputStream(baos)){
for (int i = 0; i < listDoc.length; i++) {
try(InputStream fis = new ByteArrayInputStream(FileUtils.readFileToByteArray(listDoc[i]));BufferedInputStream bis = new BufferedInputStream(fis)){
zos.putNextEntry(new ZipEntry(listDoc[i].getName()));
byte[] bytes = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(bytes)) != -1) {
zos.write(bytes, 0, bytesRead);
}
}
}
zos.closeEntry();
stream = new ByteArrayInputStream(baos.toByteArray());
}
}
}
return stream;
}
downLoadFile
public static void downLoadFile(HttpServletResponse response,InputStream pathStream,String fileName) throws IOException {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition",
"attachment;filename=" + fileName);
ServletOutputStream out = response.getOutputStream();
IOUtils.copyLarge(pathStream, out);
out.flush();
FacesContext.getCurrentInstance().responseComplete();
IOUtils.closeQuietly(pathStream);
IOUtils.closeQuietly(out);
}
I have this error when trying to open the zip file
I presume you're trying to make a zip file with multiple files. The issues are in your getStreamAllFiles method as you don't close the zip entry after putting the content of the file, and you don't close the ZipOutputStream and the end of the loop, so the file loop should look like:
for (int i = 0; i < listDoc.length; i++) {
try(InputStream fis = new ByteArrayInputStream(FileUtils.readFileToByteArray(listDoc[i]));BufferedInputStream bis = new BufferedInputStream(fis)){
zos.putNextEntry(new ZipEntry(listDoc[i].getName()));
byte[] bytes = new byte[1024];
int bytesRead;
while ((bytesRead = bis.read(bytes)) != -1) {
zos.write(bytes, 0, bytesRead);
}
zos.closeEntry();
}
}
zos.close();
stream = new ByteArrayInputStream(baos.toByteArray());
i.e. move the zos.closeEntry() inside the loop through the files.
Without moving it inside the listDoc.length loop, if you have more than one file you will not be closing the ZipEntry properly at the end of each entry. You also need to issue a close() on the ZipOutputStream, as otherwise it will not write the end-of-zip directory (which is shown as an error End-of-central-directory signature not found if you test the file under a command line tool.
In addition, I'd move the allocation of the byte buffer outside the file loop as you only need to allocate it once, and reuse the same buffer for all the files you're writing.
I have this part of function where it supposed to download file like pdf from server and store in new directory. It does do this but an empty pdf or text file.How to fix it.
`File urlfile = new File(host + "/" + path);
urlfile.getParentFile().mkdirs();
// create outputstream for request and inputstream for data
// download
FileOutputStream outS = new FileOutputStream(urlfile);
DataInputStream instream = new DataInputStream(newsocket.getInputStream());
// get rid of head part to get to actual file
String l = null;
String lastmodtime = null;
boolean done = false;
while (!(l = DAA.readLine()).equals("")) {
if (!done && l.contains("Last-Modified:")) {
lastmodtime = l.substring(l.indexOf(' ') + 1, l.length());
done = true;
System.out.println(l);
}
}
// read in bytes to correct file name
try {
byte[] inbytes = new byte[16384];
int input;
while ((input = instream.read(inbytes)) != -1) {
outS.write(inbytes, 0, input);
}
}`
You can try this simple code if you want to create a copy of the file or you can even use apache commons io (FileUtils.copyFile(source, dest)) for java copy file operation.
private static void copyFileUsingStream(File source, File dest)
throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
}
I have two problems with my java server-client file communication,
I have the CLIENT sends files over to the server and the SERVER receives the files.
My 2 issues are:
1) whenever i send a file, it is 8 bytes less (i do not know why)
2) the file transfer is not complete (with 8 bytes less) unless i close the socket, which i do not want. i want my connection to be persistent, so how can i send a EOF from the client to the server.
here is my client who sends files
public void sendFiles(String file) {
try {
File myFile = new File(file);
long length = myFile.length();
byte[] buffer = new byte[8192];
System.out.println(length);
FileInputStream in = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(in);
BufferedOutputStream outF = new BufferedOutputStream(sock.getOutputStream());
out.print("%SF%" + length + "$" + myFile.getName() + "#");
out.flush();
int count;
while ((count = in.read(buffer)) > 0) {
outF.write(buffer, 0, count);
}
outF.flush();
in.close();
bis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
SERVER who receives files.
I'm passing the name and the length of the file but only using the name of the file. however, i don't know if i need to use the length of the file or not, in case of EOF or something. Please advice
Also, The code hangs in
while ((count = this.sock.getInputStream().read(buffer)) > 0) {
due to no EOF which i do not know how to implement
public void recvFile(String fileName, int length) {
try {
byte[] buffer = new byte[8192];
FileOutputStream outF = new FileOutputStream("/Users/Documents" +fileName);
BufferedOutputStream bos = new BufferedOutputStream(outF);
int count = length;
while ((count = this.sock.getInputStream().read(buffer)) > 0) {
bos.write(buffer, 0, count);
}
bos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
UPDATE: I have removed the flush() as advised that it is not needed. Also, i have tested this code in a different class and it worked but it doesn't work here with client-server chat. Could anyone tell me why?
Any help or hints would be appreciated.
Thank you.
I would suggest to you send the file size first and/or properties of the file... You can try HTTP which is wide use for this task...
Another suggestion would be for you to open another connection on other TCP port just to send the file (this is actually how FTP sends files)
I suspect the problem you have is in code you haven't shown.
In this example you can send multiple messages or files over the same stream.
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.SocketChannel;
/**
* Created by peter on 1/25/15.
*/
public class DataSocket implements Closeable {
private final Socket socket;
private final DataOutputStream out;
private final DataInputStream in;
public DataSocket(Socket socket) throws IOException {
this.socket = socket;
this.out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
this.in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
#Override
public void close() throws IOException {
out.flush();
socket.close();
}
// message format is length as UTF-8 encoded name, 32-bit int followed by data.
public void writeMessage(String description, byte[] bytes) throws IOException {
out.writeUTF(description);
out.writeInt(bytes.length);
out.write(bytes);
out.flush();
}
public byte[] readMessage(String[] description) throws IOException {
description[0] = in.readUTF();
int length = in.readInt();
byte[] bytes = new byte[length];
in.readFully(bytes);
return bytes;
}
public void writeFile(File file) throws IOException {
long length = file.length();
if (length > Integer.MAX_VALUE) throw new IllegalArgumentException("length=" + length);
out.writeUTF(file.toString());
out.writeInt((int) length);
byte[] buffer = new byte[(int) Math.min(length, 32 * 1024)];
try (FileInputStream fis = new FileInputStream(file)) {
for (int len; (len = fis.read(buffer)) > 0; ) {
out.write(buffer, 0, len);
}
}
out.flush();
}
public void readFile(File dir) throws IOException {
String fileName = in.readUTF();
int length = in.readInt();
byte[] buffer = new byte[(int) Math.min(length, 32 * 1024)];
try (FileOutputStream fos = new FileOutputStream(new File(dir, fileName))) {
while (length > 0) {
int len = in.read(buffer);
fos.write(buffer, 0, len);
length -= len;
}
}
}
// todo convert to a unit test
public static void main(String[] args) throws IOException {
// port 0 opens on a random free port.
ServerSocket sc = new ServerSocket(0);
DataSocket ds1 = new DataSocket(new Socket("localhost", sc.getLocalPort()));
DataSocket ds2 = new DataSocket(sc.accept());
sc.close();
// now ds1 and ds2 are connected.
File f = File.createTempFile("deleteme","");
f.deleteOnExit();
try (FileOutputStream fos = new FileOutputStream(f)) {
fos.write(new byte[10001]);
}
// send a request
ds1.writeMessage("Send me the file", new byte[0]);
String[] desc = { null };
byte[] data = ds2.readMessage(desc);
if (!desc[0].equals("Send me the file")) throw new AssertionError();
// return a response
ds2.writeFile(f);
f.delete();
if (f.exists()) throw new AssertionError();
ds1.readFile(new File(""));
if (f.length() != 10001) throw new AssertionError("length="+f.length());
ds1.close();
ds2.close();
System.out.println("Copied a "+f.length()+" file over TCP");
}
}
I want to upload an image to FTP Server. Currently i am using JDeveloper 12c(12.1.3.0).
My Code:
private static final int BUFFER_SIZE = 4096;
public String fileUploadMethod(String imagePath){
String ftpUrl = "ftp://";
String host = "http://192.168.0.42";
String user = "XXXXXX";
String pass = "XXXXXX";
String filePath = "783771-1.jpg";
String uploadPath = imagePath;
ftpUrl =ftpUrl + user +":"+ pass+"#"+host+"/"+filePath+";";
System.out.println("Upload URL: " + ftpUrl);
try {
URL url = new URL(ftpUrl);
URLConnection conn = url.openConnection();
OutputStream outputStream = conn.getOutputStream();
FileInputStream inputStream = new FileInputStream(uploadPath);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
inputStream.close();
outputStream.close();
System.out.println("File uploaded");
return "File uploaded";
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
I am getting an error MalFormedURLException i.e. in detail message "unknown protocol:ftp"
Is there any other option to upload an image using JDeveloper.
Any idea regarding this.
Thanks, Siddharth
Your ftpUrl is wrong. Remove http:// in the host variable. Should be ok then
I haven't really tried ftp upload. But I had tried with multipart form upload. As far as I know, MAF doesnt provide Out-Of-Box support for file upload. What I did was essential recreating the HTTP stream for the image upload.
The POC code is attached below. This may be definitely the CRUDEST implementation but I am not sure if there is a better way.
public void doUpload() {
try {
DeviceManager dm = DeviceManagerFactory.getDeviceManager();
String imgData =
dm.getPicture(50, DeviceManager.CAMERA_DESTINATIONTYPE_FILE_URI, DeviceManager.CAMERA_SOURCETYPE_CAMERA,
false, DeviceManager.CAMERA_ENCODINGTYPE_PNG, 0, 0);
imgData = imgData.substring(7, imgData.length());
int start = imgData.lastIndexOf('/');
String fileName = imgData.substring(start+1, imgData.length());
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
String requestMethod = RestServiceAdapter.REQUEST_TYPE_POST;
String requestEndPoint = restServiceAdapter.getConnectionEndPoint("serverBaseUrl");
String requestURI = "/workers/100000018080264";
String request = requestEndPoint + requestURI;
HashMap httpHeadersValue = new HashMap();
httpHeadersValue.put("X-ANTICSRF", "TRUE");
httpHeadersValue.put("Connection", "Keep-Alive");
httpHeadersValue.put("content-type","multipart/form-data; boundary=----------------------------4abf1aa47e18");
// Get the connection
HttpConnection connection = restServiceAdapter.getHttpConnection(requestMethod, request, httpHeadersValue);
OutputStream os = connection.openOutputStream();
byte byteBuffer[] = new byte[50];
int len;
//String temp is appended before the image body
String temp = "------------------------------4abf1aa47e18\r\nContent-Disposition: form-data; name=\"file\"; filename=\"" +fileName+ "\"\r\nContent-Type: image/jpeg\r\n\r\n";
InputStream stream = new ByteArrayInputStream(temp.getBytes("UTF-8"));
if (stream != null) {
while ((len = stream.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
stream.close();
}
FileInputStream in = new FileInputStream(imgData);
if (in != null) {
while ((len = in.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
in.close();
}
//The below String is appended after the image body
InputStream stream2 =new ByteArrayInputStream("\r\n------------------------------4abf1aa47e18--\r\n".getBytes("UTF-8"));
if (stream2 != null) {
while ((len = stream2.read(byteBuffer)) >= 0) {
os.write(byteBuffer, 0, len);
}
stream2.close();
}
int status = connection.getResponseCode();
InputStream inputStream = restServiceAdapter.getInputStream(connection);
ByteArrayOutputStream incomingBytes = new ByteArrayOutputStream() // get and process the response.
while ((len = inputStream.read(byteBuffer)) >= 0) {
incomingBytes.write(byteBuffer, 0, len);
}
String ret = incomingBytes.toString();
incomingBytes.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I want to return file (read or load) from method and then remove this file.
public File method() {
File f = loadFile();
f.delete();
return f;
}
But when I delete a file, I delete it from disk and then exists only descriptor to non-existing file on return statement. So what is the most effective way for it.
You can't keep the File handle of deleted file, rather you can keep the data in a byte array temporarily, delete the file and then return the byte array
public byte[] method() {
File f =loadFile();
FileInputStream fis = new FileInputStream(f);
byte[] data = new byte[fis.available()];
fis.read(data);
f.delete();
return data;
}
// Edit Aproach 2
FileInputStream input = new FileInputStream(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int bytesRead = input.read(buf);
while (bytesRead != -1) {
baos.write(buf, 0, bytesRead);
bytesRead = input.read(buf);
}
baos.flush();
byte[] bytes = baos.toByteArray();
you can construct the file data from byte array
However, my suggestion is to use IOUtils.toByteArray(InputStream input) from Jakarta commons, why do you want re write when already in plate
Assuming you want to return the file to the browser, this is how I did it :
File pdf = new File("file.pdf");
if (pdf.exists()) {
try {
InputStream inputStream = new FileInputStream(pdf);
httpServletResponse.setContentType("application/pdf");
httpServletResponse.addHeader("content-disposition", "inline;filename=file.pdf");
copy(inputStream, httpServletResponse.getOutputStream());
inputStream.close();
pdf.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
private static int copy(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[512];
int count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}