I'm trying to send a zip file using ksoap2 as client... File is arriving but corrupted, I think is something in my code when I encode it in Base64 (I'm using commons code)...
WS
FileInputStream fis = new FileInputStream(path.toString()+zipName.toString());
byte[] toByteArray = IOUtils.toByteArray(fis);
byte[] encodeBase64 = Base64.encodeBase64(toByteArray);
return encodeBase64;
Client
SoapPrimitive soapPrimitive = (SoapPrimitive) soapSerializationEnvelope.getResponse();
String result = soapPrimitive.toString();
byte[] decode = Base64.decode(result);
String formPath = "C:\\Users\\John\\Desktop\\test.zip";
boolean flag = new File(path.toString()).mkdirs();
FileOutputStream fileOutputStream = new FileOutputStream(formPath);
fileOutputStream.write(decode);
fileOutputStream.flush();
fileOutputStream.close();
The file is ok in the server, I can open it but when arrives in the client it's corrupted
thanks...
Related
I am using Java 11. I am reading emails and retrieving their attachments using javax.mail and would like to save the attachments byte array.
So I need to convert a javax.mail.internet.MimeBodyPart (the attachment) to a byte[].
code so far:
private void savePDF(MimeBodyPart attachment, String invoiceNumber) {
byte[] data = attachment.get....
}
More info:
When I try open the PDF, I do the following:
InputStream is = response.getStream();
byte[] bytes = IOUtils.toByteArray(is);
OutputStream output = response.getOutputStream();
fos = new BufferedOutputStream(output);
fos.write(bytes);
This works perfectly when I get the bytes from a 'MultipartFile':
byte[] bytes = multipartFile.getBytes();
However, if I try use the byes from a MimeBodyPart (email attachment), it fails:
byte[] data = attachment.getInputStream().readAllBytes();
More info:
I have also tried, but I get the same error:
BASE64DecoderStream content = (BASE64DecoderStream) attachment.getContent();
byte[] bytes = content.readAllBytes();
bytes = Base64.decodeBase64(bytes);
I have the Spring REST service returns the excel file(XLS) as byte array and need to write the appropriate client code to receive this response and save the file. Was able to get the byte array response but while converting it to excel workbook(HSSFWorkbook) getting the below error
org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0005060000100809, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document.
I tried the following but no luck
verified that the file is valid by saving it in the service before returns in response.
Tried to send the InputStream instead of byte array
Tried using ResponseEntity
etc
service side code
HSSFWorkbook workbook = //code to generate the workbook
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
byte[] response = outputStream.toByteArray();
Any help is greatly appreciated.
Found the issues and fixed it.
Server side code
HSSFWorkbook workbook = //workbook creation call
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
workbook.write(outputStream);
response = outputStream.toByteArray();
headers = new HttpHeaders();
headers.setAccessControlExposeHeaders(Collections.singletonList("Content-Disposition"));
headers.set("Content-Disposition", "attachment; filename=download.xls");
headers.setAccessControlExposeHeaders(Collections.singletonList("Content-Type"));
headers.set("Content-Type","application/vnd.ms-excel");
outputStream.close();
Client side code
String uri = //URI
RestTemplate restTemplate = new RestTemplate();
//input object
ResponseEntity<byte[]> result = restTemplate.postForEntity(uri, input, byte[].class);
if(result!=null && result.getStatusCodeValue() == 200 && result.getBody()!=null && result.getBody().length>0)
{
ByteArrayInputStream inputStream = new ByteArrayInputStream(result.getBody());
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
FileOutputStream outputStream = new FileOutputStream("output\\download.xls");
workbook.write(outputStream);
inputStream.close();
workbook.close();
outputStream.close();
}
I am trying to download a PDF file with HttpClient, it is downloading the PDF file but pages are blank. I can see the bytes on console from response if I print them. But when I try to write it to file it is producing a blank file.
FileUtils.writeByteArrayToFile(new File(outputFilePath), bytes);
However the file is showing correct size of 103KB and 297KB as expected but its just blank!!
I tried with Output stream as well like:
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
fileOutputStream.write(bytes);
Also tried to write with UTF-8 coding like:
Writer out = new BufferedWriter( new OutputStreamWriter(
new FileOutputStream(outFile), "UTF-8"));
String str = new String(bytes, StandardCharsets.UTF_8);
try {
out.write(str);
} finally {
out.close();
}
Nothing is working for me. Any suggestion is highly appreciated..
Update: I am using DefaultHttpClient.
HttpGet httpget = new HttpGet(targetURI);
HttpResponse response = null;
String htmlContents = null;
try {
httpget = new HttpGet(url);
response = httpclient.execute(httpget);
InputStreamReader dataStream=new InputStreamReader(response.getEntity().getContent());
byte[] bytes = IOUtils.toByteArray(dataStream);
...
You do
InputStreamReader dataStream=new InputStreamReader(response.getEntity().getContent());
byte[] bytes = IOUtils.toByteArray(dataStream);
As has already been mentioned in comments, using a Reader class can damage binary data, e.g. PDF files. Thus, you should not wrap your content in an InputStreamReader.
As your content can be used to construct an InputStreamReader, though, I assume response.getEntity().getContent() returns an InputStream. Such an InputStream usually can be directly used as IOUtils.toByteArray argument.
So:
InputStream dataStream=response.getEntity().getContent();
byte[] bytes = IOUtils.toByteArray(dataStream);
should already work for you!
Here is a method I use to download a PDF file from a specific URL. The method requires two string arguments, an url string (example: "https://www.ibm.com/support/knowledgecenter/SSWRCJ_4.1.0/com.ibm.safos.doc_4.1/Planning_and_Installation.pdf") and a destination folder path to download the PDF file (or whatever) into. If the destination path does not exist within the local file system then it is automatically created:
public boolean downloadFile(String urlString, String destinationFolderPath) {
boolean result = false; // will turn to true if download is successful
if (!destinationFolderPath.endsWith("/") && !destinationFolderPath.endsWith("\\")) {
destinationFolderPath+= "/";
}
// If the destination path does not exist then create it.
File foldersToMake = new File(destinationFolderPath);
if (!foldersToMake.exists()) {
foldersToMake.mkdirs();
}
try {
// Open Connection
URL url = new URL(urlString);
// Get just the file Name from URL
String fileName = new File(url.getPath()).getName();
// Try with Resources....
try (InputStream in = url.openStream(); FileOutputStream outStream =
new FileOutputStream(new File(destinationFolderPath + fileName))) {
// Read from resource and write to file...
int length = -1;
byte[] buffer = new byte[1024]; // buffer for portion of data from connection
while ((length = in.read(buffer)) > -1) {
outStream.write(buffer, 0, length);
}
}
// File Successfully Downloaded");
result = true;
}
catch (MalformedURLException ex) { ex.printStackTrace(); }
catch (IOException ex) { ex.printStackTrace(); }
return result;
}
I have a Java Jersey client with which I connect to a server and download an image like this:
WebTarget webTarget = client.target(url);
Response response = webTarget.request().get();
The client response is the following:
InboundJaxrsResponse{ClientResponse{method=GET, uri=resourceURL, status=200, reason=OK}}
When I try to parse the body as an InputStream like this to a file
InputStream imageInputStream = response.readEntity(InputStream.class);
OutputStream outputStream = new FileOutputStream(new File("test.jpg"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
The input stream breaks at ~7000bytes and the content never gets parsed totally.
I have no access to the image server, and if I try to access the URL of the image in the browser, it works and the image gets downloaded.
On top the server has a self signed SSL certificate which I registered to my java keystore, can that be also part of the issue?
I have this issue with GZIP compression:
I need to send by POST method a huge JSON string, which is too big to be accept like URL (Ex: http://localhost/app/send/JSON STRING ENCODED BY BASE64), than it result in HTTP error 403
so, I need to compress my json and I found a way to do it with GZIP compression, which I can decompress with gzdecode() in PHP.
but it doesn't work...
my functions compress() and decompress() works fine inside my Java App, but when I send it to webservice, something goes wrong and gzdecode() doesn't work.
I have no idea what I missing, I need some help
functions used in java app (client)
public String Post(){
String retorno = "";
String u = compress(getInput());
u = URLEncoder.encode(URLEncoder.encode(u, "UTF-8"));
URL uri = new URL(url + u);
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setDoOutput(false);
conn.setRequestMethod(getMethod());
conn.setRequestProperty("Content-encoding", "gzip");
conn.setRequestProperty("Content-type", "application/octet-stream");
BufferedReader buffer = new BufferedReader(
new InputStreamReader((conn.getInputStream())));
String r = "";
while ((r = buffer.readLine()) != null) {
retorno = r + "\n";
}
return retorno;
}
GZIP compress function (client)
public static String compress(String str) throws IOException {
byte[] blockcopy = ByteBuffer
.allocate(4)
.order(java.nio.ByteOrder.LITTLE_ENDIAN)
.putInt(str.length())
.array();
ByteArrayOutputStream os = new ByteArrayOutputStream(str.length());
GZIPOutputStream gos = new GZIPOutputStream(os);
gos.write(str.getBytes());
gos.close();
os.close();
byte[] compressed = new byte[4 + os.toByteArray().length];
System.arraycopy(blockcopy, 0, compressed, 0, 4);
System.arraycopy(os.toByteArray(), 0, compressed, 4,
os.toByteArray().length);
return Base64.encode(compressed);
}
method php used to receive a URL (server, using Slim/PHP Framework)
init::$app->post('/enviar/:obj/', function( $obj ) {
$dec = base64_decode(urldecode( $obj ));//decode url and decode base64 tostring
$dec = gzdecode($dec);//here is my problem, gzdecode() doesn't work
}
post method
public Sender() throws JSONException {
//
url = "http://192.168.0.25/api/index.php/enviar/";
method = "POST";
output = true;
//
}
As noticed in some of the comments.
Bigger data should be send as a POST request instead of GET. URL params should be used only for single variables. As you noticed the URL length is limited to few kB and it's not very good idea to send larger data this way (even though GZIP compressed).
Your GZIP compression code seems to be wrong. Please try this:
public static String compress(String str) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream(str.length());
GZIPOutputStream gos = new GZIPOutputStream(os);
gos.write(str.getBytes());
os.close();
gos.close();
return Base64.encodeToString(os.toByteArray(),Base64.DEFAULT);
}