I have http response object "httpResponse" which is instance of class javax.ws.rs.core.Response. I have to convert it into a human readable string object for debugging. How can I achieve this?
final InputStream inputStream = (InputStream) httpResponse.getEntity();
final ByteArrayDataSource dataSource = new ByteArrayDataSource(inputStream, ContentType.MULTIPART_FORM_DATA.getMimeType());
final MimeMultipart multipartResponse = new MimeMultipart(dataSource);
I tried doing the below using the inputStream object. The output is all binary. Do I need to do base64 decoding? Thanks.
IOUtils.toString(inputStream, StandardCharsets.UTF_8))
As you said you need decoding.
// string to byte[]
byte[] bytes = "hello".getBytes(StandardCharsets.UTF_8);
// byte[] to string
String s = new String(bytes, StandardCharsets.UTF_8);
Source:
https://mkyong.com/java/how-do-convert-byte-array-to-string-in-java/
Here it is explained not only the conversion from bytes to text, but also the conversion from bytes to image or any kind of binary type.
Related
I am upgrading S3Client in aws cloud service to S3AsyncClient.
I have this function to convert to async:
public PutObjectResponse uploadFileByUrl(String fileUrl, String builderId, PbModel category, String categoryId)
URL url = new URL(fileUrl);
String[] fileNameArray = url.getFile().split("\\.");
var uniqueFileName = prepareFileName(fileNameArray[fileNameArray.length -1]);
URLConnection connection = url.openConnection();
long contentSize = connection.getContentLengthLong();
InputStream inputStream = connection.getInputStream();
return s3Client.putObject(myObjectRequestBuild, RequestBody.fromInputStream(inputStream, contentSize));
}
I have this function to convert to async:
public CompletableFuture<PutObjectResponse> uploadFileByUrl(String fileUrl, String builderId, PbModel category, String categoryId)
URL url = new URL(fileUrl);
String[] fileNameArray = url.getFile().split("\\.");
var uniqueFileName = prepareFileName(fileNameArray[fileNameArray.length -1]);
URLConnection connection = url.openConnection();
long contentSize = connection.getContentLengthLong();
InputStream inputStream = connection.getInputStream();
return asyncClient.putObject(myObjectRequestBuild, AsyncRequestBody.fromPublisher(???));
}
As you can see in second method above when I convert the first function above to async I need to use AsyncRequestBody instead of RequestBody.
AsyncRequestBody doesn't have fromInputStream method but it have fromPublisher method that I want to use, the fromPublisher method get as parameter type of Publisher.
So my question is how to convert my inputStream into an Publisher?
AsyncRequestBody doesn't have fromInputStream method
Correct however, it has a plethora of other ways to create an AsyncRequestBody:
fromByteBuffer(ByteBuffer byteBuffer)
fromBytes(byte[] bytes)
fromFile(File file)
fromFile(Path path)
fromPublisher(org.reactivestreams.Publisher<ByteBuffer> publisher)
fromString(String string)
fromString(String string, Charset cs)
Considering the above, you have a few solutions:
Convert the InputStream to a byte array using IOUtils.toByteArray(inputStream) (or in Java 9+, inputStream.readAllBytes()) and then use fromBytes directly
As above but then convert the byte[] to a ByteBuffer using ByteBuffer.wrap(byteArray) and then use fromByteBuffer
Create a new File object specifying a filename, copy the contents of the InputStream to the file's FileOutputStream using IOUtils.copy(), and then use fromFile(File file)
As above but instead of providing the File object, provide its path to fromFile(Path path) after you've written to it's FileOutputStream
Convert the InputSteam to a Publisher<ByteArray> using DataBufferUtils.readByteChannel from the Spring Framework, Akka StreamConverters etc. and then use fromPublisher
Convert the InputStream to a UTF-8 encoded String then use fromString(String string) (no need to specify the Charset if it is UTF-8 encoded)
Convert the InputStream to a non-UTF-8 encoded String then use fromString(String string, Charset cs), specifying the CharSet
Of course, some of the above are plain redundant in your case e.g. fromFile(Path path) is for files that you've already stored & converting the InputSteam to a Publisher<ByteArray> is going to be a pain but I've included all possible solutions for completeness.
I would approach this using solution #1, resulting in the cleanest, simplest code out of the above.
Convert the InputStream to byte[] using inputStream.readAllBytes() and then use AsyncRequestBody.fromBytes(...).
This should work:
public CompletableFuture<PutObjectResponse> uploadFileByUrl(String fileUrl, String builderId, PbModel category, String categoryId)
URL url = new URL(fileUrl);
String[] fileNameArray = url.getFile().split("\\.");
var uniqueFileName = prepareFileName(fileNameArray[fileNameArray.length -1]);
URLConnection connection = url.openConnection();
long contentSize = connection.getContentLengthLong();
InputStream inputStream = connection.getInputStream();
byte[] fileByteArray = inputStream.readAllBytes();
return asyncClient.putObject(myObjectRequestBuild, AsyncRequestBody.fromBytes(fileByteArray));
}
I receive data from Bluetooth BLE as follow in 250 bytes chunk at most.
onDataReceived(byte[] data) {
my_readline(); // <-- how could I implement this
}
the data are string but chuncked. so what is the proper way to detect lines from incomming byte arrays. or it would be good as well if it is possible to convert received data to inputStream as well.
You could do it with an ByteArrayInputStream and turn that into an BufferedReader. It is not very clean altough it should work.
InputStream inputStream = new ByteArrayInputStream(data);
BufferedReader buffReader = new BufferedReader(new InputStreamReader(inputStream));
You can convert byte array to String,
String inputStr = new String(data, "UTF-8");
And if you want to convert to InputStream,
InputStream dataInputStream = new ByteArrayInputStream(data);
My requirement is to convert the blob in a database field to string to create a json object. I have achieved that.
Now, I need to convert this string back to blob. I wrote the below code. But, it does not work. In my instance, I have the word document stored as blob. I converted it to string but when I converted the string to blob, the document does not open properly.
Please let me know a way to convert the string back to blob.
DocumentTemplateKey documentTemplateKey = new DocumentTemplateKey();
documentTemplateKey.documentTemplateID = "XX";
DocumentTemplateDtls documentTemplateDtls = DocumentTemplateFactory.newInstance().read(documentTemplateKey);
byte[] blobAsBytes = documentTemplateDtls.contents.copyBytes();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(blobAsBytes, 0, blobAsBytes.length);
String pdfBase64String =
org.apache.commons.codec.binary.StringUtils.newStringUtf8(org.apache.
commons.codec.binary.Base64.encodeBase64(bos.toByteArray()));
OutputStreamWriter out = new OutputStreamWriter(System.out);
JsonWriter writer = new JsonWriter(out);
//set indentation for pretty print
writer.setIndent("\t");
//start writing
writer.beginObject(); //{
writer.name("blob").value(pdfBase64String);
byte[] stringAsBytes = org.apache.commons.codec.binary.StringUtils.getBytesUtf8(pdfBase64String);
Blob blob = new Blob(stringAsBytes);
documentTemplateDtls.contents = blob;
documentTemplateDtls.documentTemplateID = "XX12";
documentTemplateDtls.name = "XX12";
DocumentTemplateFactory.newInstance().insert(documentTemplateDtls);
writer.endObject();
writer.flush();
//close writer
writer.close();
Here's your problem:
byte[] stringAsBytes = org.apache.commons.codec.binary.StringUtils.getBytesUtf8(pdfBase64String);
You're getting the bytes of your base64 string, but you ought to be putting it through a base64 decoder.
I'm attempting to encode a String in a client using GZIPOutputStream then decoding the String in a server using GZIPOutputStream.
The client's side code (after the initial socket connection establishment) is:
// ... Establishing connection, getting a socket object.
// ... Now proceeding to send data using that socket:
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String message = "Hello World!";
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(message);
gzip.close();
String encMessage = out.toString();
out.writeInt(encMessage.getBytes().length);
out.write(encMessage.getBytes());
out.flush();
And the server's side code (again, after establishing a connection):
DataInputStream input = new DataInputStream(socket.getInputStream());
int length = input.readInt();
byte[] buffer = new byte[length];
input.readFully(buffer);
GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(buffer));
BufferedReader r = new BufferedReader(new InputStreamReader(gz));
String s = "";
String line;
while ((line = r.readLine()) != null)
{
s += line;
}
I checked and the buffer length (i.e., the coded message's size) is passed correctly, so the right number of bytes is transferred.
However, I'm getting this:
java.util.zip.ZipException: invalid code lengths set
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:122)
at parsing.ReceiveResponsesTest$TestReceiver.run(ReceiveResponsesTest.java:147)
at java.lang.Thread.run(Thread.java:745)
Any ideas?
Thanks in advance for any assistance!
You're calling toString() on the ByteArrayOutputStream - that is incorrect, and it opens up all kinds of character encoding problems that are probably biting you here. You need to call toByteArray instead:
byte[] encMessage = out.toByteArray();
out.writeInt(encMessage.length);
out.write(encMessage);
Detail:
if you use toString(), Java will encode your bytes in your platform default character encoding. That could be some Windows codepage, UTF-8, or whatnot.
However not all characters can be encoded properly, and some will be replaced by an alternative character - a question mark perhaps. Without knowing the details, it's hard to tell.
But in any case, encoding the byte array to a String, and then decoding it to a byte array again when you write it out, is very likely to change the data in the byte array. And there is not need to do it, you can just get the byte array straight away as shown in the code above.
Why on earth are you indulging in all this complication? You can reduce it all to this:
GZIPOutputStream gzip = new GZIPOutputStream(socket.getOutputStream());
DataOutputStream out = new DataOutputStream(gzip);
String message = "Hello World!";
out.writeUTF(message);
out.close();
// ...
GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(socket.getInputStream()));
DataInputStream input = new DataInputStream(gz);
String line = input.readUTF();
I further note that your code doesn't actually compile. I would further note that unless the messages are several orders of magnitude larger, there is no benefit to the GZipping.
Any help appreciated.
I have file in JSON format.
{
"identifier": 123;
"MessageID: "xyzzzzzz"
"Data": "xmlformattedstring"
}
I would like to just Gzip the ("xmlformattedstring") keeping the JSON body intact.
Is it possible to
Sure, you could set the data with something like:
String data = "xmlformattedstring";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(data.getBytes("UTF-8"));
gzos.close();
String base64CompressedString = Base64.getEncoder().encodeToString(baos.toByteArray());
and then use base64CompressedString in your JSON. Basically all this does is compress your string and convert it to base64. Base64 won't be as efficient as pure GZIP but it will be needed to send as an ASCII string like in JSON.