I have an image byte array which I need to send to a servlet on a server using HTTP client. We know how to send normal text data but unable to send the image data.
We created a string data from image byte array using the following code:
String imageData = new String(imagebyteArr);
And sent the above String to servlet through HTTP client, but when we again retrieve byte array from string using below code:
imageByteArr = imageData.toByteArray();
The resultant byte array is modified one, where in -127 is replaced on 63.
How to solve this unexpected behavior?
Strings get encoded. You have 2 posibilities: encode binary data as base64 (for example) send the base64 and decode on server side or binary upload with a PUT request.
I would totally discourage you with taking image byte array and converting to String as you will have to worry about character encoding.
One thing to do is send the byte array directly using ByteArrayEntity, as follows:
HttpPost post = new HttpPost(url);
post.setEntity(new ByteArrayEntity(bytes));
post.setHeader("Content-type", ""application/octet-stream");
Don't forget to set your Content-Type to the correct image appropriately.
Related
I am trying to implement the scrape method for an UDP tracker but I keep getting 0 seeders/leechers as response. I am still getting a 2 as the action so no error is reported.
I have hardcoded a hash here just to show that it has no effect on the result I am getting.
final ByteArrayOutputStream byteStream =new ByteArrayOutputStream();
final DataOutputStream dataStream =new DataOutputStream(byteStream);
dataStream.writeInt(connectResponse.get("connectionId0"));
dataStream.writeInt(connectResponse.get("connectionId1"));
dataStream.writeInt(2);
dataStream.write(connectResponse.get("transactionId"));
bencodeWriter.write(byteOut.toString());
dataStream.writeChars("1D19CC96C1A4965D184E4B215942DBC0A09FF8F2");
dataStream.close();
final byte[] scrapeBytes= byteStream.toByteArray();
I tried different trackers but get the same response. What might be the problem?
Edit: Added the hex dump of all the requests and responses:
Connect Request:
Connect Response:
Scrape Request:
Scrape Response:
In the Scrape request;
the transaction_id=0x36 is sent as a single byte instead of 4 bytes=0x00000036
and the info_hash is sent as a 80 bytes string that is hex-encoded were every character is prepended by a zero-byte 0x00 instead of as a raw 20 bytes string.
I.E. 0x0031004400310039... instead of 0x1D19...
The Scrape response has no peers, as there is no torrents with the info_hashes sent in the request.
I need to send larger video files (and other files) to server with base64 encode.
I get out of memory exception, because I want to store the file in the memory (in byte[]) then encode it to string with Base64.encodeToString. But how can I encode the file and send it out on-the-air and/or using less memory? Or how can I do this better?
To the request I using now MultipartEntityBuilder after I build it, I send it out to the server with post method and with the file I need to send other data too. So I need to send both in one request and the server only accepts files with base64 encoded.
OR
Because I using Drupal's REST module to create content from posts, it's another solution for me, if I can send normal post with a normal form. (like the browser does) The problem is, I can't find, just only one solution. When you call the <endpoint>/file url and you pass four things, these are:
array("filesize" => 1029, // file size
"filename" => "something.mp4", //file name
"uid" => 1, // user id, who upload the file
"file" => "base64 encoded file string")
After this request I get an fid, which is the uploaded file's id. I need to send this with the real content, when I create node. If I can send the file with normal post mode (without encode) like the browser does at form send, it would be better.
I need to send larger video files (and other files) to server with base64 encode.
You should consider getting a better server, one that supports binary uploads.
I get out of memory exception, because I want to store the file in the memory (in byte[]) then encode it to string with Base64.encodeToString.
That will not work for any significant video. You do not have heap space for this.
But how can I encode the file and send it out on-the-air and/or using less memory? Or how can I do this better?
You can implement a streaming converter to base64 (read the bytes in from a file and write the bytes out to a base64-encoded file, where you are only processing a small number of bytes at a time in RAM). Then, upload the file along with the rest of your form data.
In my application I need to use the rest api of a web service. For now I need to send an xml message. The problem is, some of the characters in this xml are polish diacritics. Now, the code of my message sending looks like this
WebResource r = client.resource(resourceAddress);
String response = r.accept(
MediaType.APPLICATION_XML_TYPE,
MediaType.APPLICATION_JSON_TYPE,
MediaType.TEXT_HTML_TYPE
)
.type(MediaType.TEXT_XML_TYPE)
.header("Authorization", authorizationString)
.post(String.class, event);
Java Strings are UTF-16 and my XML should be UTF-8 encoded. Is there a way to tell Jersey to change somehow the encoding before serialization? Or maybe there is some other way, so I can send this String data as UTF-8 and not UTF-16 using Jersey client api?
I am trying to make a Http POST request using apache HTTP client. I am trying to copy contents of an HTTP POST request (received at my application) to another HTTP POST request (initiated from my application to another URL). Code is shown below:
httpPost = new HttpPost(inputURL);
// copy headers
for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements();) {
String headerName = e.nextElement().toString();
httpPost.setHeader(headerName, request.getHeader(headerName));
}
BufferedInputStream clientToProxyBuf = new BufferedInputStream(request.getInputStream());
BasicHttpEntity basicHttpEntity = new BasicHttpEntity();
basicHttpEntity.setContent(clientToProxyBuf);
basicHttpEntity.setContentLength(clientToProxyBuf.available());
httpPost.setEntity(basicHttpEntity);
HttpResponse responseFromWeb = httpclient.execute(httpPost);
Basically, I am trying to implement a proxy application which will get a url as parameter, froward the request to the URL and then serve pages etc in custom look and feel.
Here request is HttpServletRequest. I am facing problem in setting content length. Through debugging I found out that clientToProxyBuf.available() is not giving me correct length of input stream and I am getting Http error 400 IE and Error 354 (net::ERR_CONTENT_LENGTH_MISMATCH): The server unexpectedly closed the connection in chrome.
Am I doing it wrong? Is there any other way to achieve it?
The available() function doesn't provide the actual length of the content of the stream, rather
Returns the number of bytes that can be read from this input stream without blocking. (From javadoc)
I would suggest you to first read the whole content from the stream, and then set that to the content, rather than passing the stream object. That way, you will also have the actual length of the content.
It was rather simple and very obvious. I just needed to get content length from header as:
basicHttpEntity.setContentLength(Integer.parseInt(request.getHeader("Content-Length")));
Question on HttpResponse object in servlets. Can the contents of a HttpResponse be only read once?
If so do I need to user a filter and some form of "javax.servlet.http.HttpServletResponseWrapper" in order to read the content of a HttpResponse object as I need to read its content to retrieve XML/JSON from the response? At the moment Im getting the below exception when I go to read the HttpResponse object.
Content has been consumed
at org.apache.http.entity.BasicHttpEntity.getContent(BasicHttpEntity.java:84)
Thanks,
John
This is not a problem in the server/servlet side. It's a problem in the client side. The servlet doesn't send HttpServletResponse object to the client or something, it just sends a byte stream only once. You just need to read it only once into a reuseable object such as a byte[] or String, depending on the actual content and and then reuse/copy exactly this object in the remnant of the code.
InputStream input = httpResponse.getEntity().getContent();
ByteArrayOutputStream output = new ByteArrayOutputStream(); // Or some file?
IOUtils.copy(input, output);
byte[] content = output.toByteArray();
// Now you can reuse content as many times as you want.
Do you want to read the content of the response or request? Usually we write the content of the response and do not read it, unless you have an special case here.