How to save a byte[] as java.sql.Clob? - java

I have a file that I get as a byte[] and I have to persist it in my entity as Clob.
How to save a byte[] as java.sql.Clob?

To get a Clob from byte[] on Oracle, you can do
private Clob createClob(byte[] data, Connection conn) {
CLOB clob = null;
try {
clob = CLOB.createTemporary(conn, false, oracle.sql.CLOB.DURATION_SESSION);
clob.open(CLOB.MODE_READWRITE);
OutputStream out = (OutputStream) clob.setAsciiStream(0L);
out.write(data);
out.flush();
out.close();
}
catch (Exception e) {
logger.error("", e);
}
finally {
try {
if (clob != null && clob.isOpen()) clob.close();
}
catch (SQLException e) {
logger.error("Unable to close CLOB", e);
}
}
return clob;
}
To create a Blob (binary) is almost the same, just replacing clob by blob and OutputStream out = (OutputStream) blob.setBinaryStream(0L);

With Apache commons-io
byte[] data = IOUtils.toByteArray(clob.getAsciiStream());
if you need special encoding or you have some issue try:
byte[] data = IOUtils.toByteArray(clob.getCharacterStream(), "UTF-8");

javax.sql.rowset.serial.SerialClob can accept array of char and create a serializable Clob object.
You can refer here
http://docs.oracle.com/javase/7/docs/api/javax/sql/rowset/serial/SerialClob.html
javax.sql.rowset.serial.SerialBlob can accept array of bytes
You can refer here
http://docs.oracle.com/javase/7/docs/api/javax/sql/rowset/serial/SerialBlob.html

Related

Java - Obtain PDF from URL and return BASE64 string

I have the following task to obtain a PDF from URL and return a BASE64 string.
What I have currently (sorry I am not a Java Expert):
public String readPDFSOAP(String var, Container container) throws StreamTransformationException{
try {
//get the url page from the arguments array
URL url = new URL("URLPDF");
try {
//get input Stream from URL
InputStream in = new BufferedInputStream(url.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[131072];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
String string = new String(response);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}return String;}
But the string can't be returned.
Any help is appreciated.
Thanks,
Julian
Your code is all kinds of wrong. For starters, use the Base64 class to handle encoding your byte array. And no need to assign it to a variable, just return it.
return Base64.getEncoder().encodeToString(response)
and on your last line, outside of your try/catch block, just throw an exception. If you get there then you weren't able to properly retrieve and encoded the response, so no need to return a value. You're in an error condition.
Use java.util.Base64.
PDFs can be pretty large. Instead of reading it into memory, encode the InputStream directly:
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (InputStream in = new BufferedInputStream(url.openStream())) {
in.transferTo(Base64.getEncoder().wrap(out));
}
String base64 = out.toString(StandardCharsets.US_ASCII);
The Base64 encoded version is even larger than the original file. I don’t know what you plan to do with the encoded version, but if you’re planning to write it somewhere, you want to avoid keeping any version of the file—original or encoded—in memory. You can do that by having your method accept an OutputStream as an argument:
public void readPDFSOAP(OutputStream destination,
String var,
Container container)
throws StreamTransformationException,
IOException {
URL url = new URL("https://example.com/doc.pdf");
try (InputStream in = new BufferedInputStream(url.openStream())) {
in.transferTo(Base64.getEncoder().wrap(destination));
}
}
Update:
Since you have said you cannot use a try-with-resources statement:
A try-with-resources statement is just a convenient way to guarantee an InputStream (or other closeable resource) is closed. This:
try (InputStream in = new BufferedInputStream(url.openStream())) {
// code that uses 'in'
}
is (nearly) equivalent to this:
InputStream in = null;
try {
in = new BufferedInputStream(url.openStream());
// code that uses 'in'
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Suppress
}
}
}

Connection Closed error on querying BLOBs from JdbcTemplate

I am querying a BLOB object from database and trying to write it in file system but I keep running into connection closed error. Here's the code
FileOutputStream out;
out = new FileOutputStream(filePathtoCreate+File.separator+filename);
Blob inBlob= jdbcTemplate.queryForObject("select BLOB_CONTENT from Table_A where name = ?" , Blob.class,new Object[] { filename});
InputStream in = inBlob.getBinaryStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (SQLException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
When I run this code I get
java.sql.SQLRecoverableException: Closed Connection
at oracle.sql.BLOB.getDBAccess(BLOB.java:1122)
at oracle.sql.BLOB.getBinaryStream(BLOB.java:265)
I do not get this issue if I go by regular JDBC Connection, so why is this happening and how do I resolve it. Thanks in advance.
You can read Blob inside jdbcTemplate's query with RowMapper, example:
jdbcTemplate.query("select * from Report where id =?",
new Object[]{id}, (resultSet, i) -> {
return toReport(resultSet);
});
private Report toReport(ResultSet resultSet) throws SQLException {
InputStream contentStream = resultSet.getClob("CONTENT")
.getAsciiStream();
String content =
new Scanner(contentStream, "UTF-8").useDelimiter("\\A").next();
report.setContent(content);
Blob blob = resultSet.getBlob("IMAGE");
Query given SQL to create a prepared statement from SQL and a list of arguments to bind to the query, mapping each row to a result object via a RowMapper.

Encode/decode Base64 fails

in my application client-server, on client side I send the file content in following format:
public static String getImageFromURI (Context contesto, Uri uri) {
InputStream is;
ByteArrayOutputStream bos;
try {
is = contesto.getContentResolver().openInputStream(uri);
bos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
for (int readNum; (readNum = is.read(buf)) != -1;) {
bos.write(buf, 0, readNum); //no doubt here is 0
}
} catch (IOException ex) {
Log.d("TAG_F2S", "Sono nel catch IOExcetion con emssage = " + ex.getMessage());
ex.printStackTrace();
return null;
}
return new String (Base64.encode(bos.toByteArray(), Base64.DEFAULT), "UTF-8");
} catch (FileNotFoundException fnfe) {
Log.d("TAG_F2S", "Sono nel catch FileNotFoundExcetion con emssage = " + fnfe.getMessage());
fnfe.printStackTrace();
return null;
} catch (UnsupportedEncodingException uee) {
Log.d("TAG_F2S", "Sono nel catch UnsupportedEncodingExcetion con emssage = " + uee.getMessage());
uee.printStackTrace();
return null;
}
}
and on server side I try to create the file as follow:
byte [] byteFile = java.util.Base64.getDecoder ().decode(contenuto.getBytes("UTF-8"));
Files.write(Paths.get(myPath), byteFile);
But I can't obtain the result cause the exception like this:
java.lang.IllegalArgumentException: Illegal base64 character a
at java.util.Base64$Decoder.decode0(Unknown Source)
at java.util.Base64$Decoder.decode(Unknown Source)
....
What's my error? I don't understand..
Thanks for your help.
EDIT:
The String that i send to the server is the following:
https://codeshare.io/GqQWNA
I found the problem:
when I encode the file content and I send data to the server in POST request, the content is modified replacing alland only '+' characters with ' ' (whitespace).
Operating the following action on server side:
java.util.Base64.getMimeDecoder().decode(contenuto.replace(" ", "+"));
I don't have the problem. Note that i used getMimeDecoder and not getDecoder, otherwise it doesn't work.
Does anyone know the reason for this problem?

special char Android (ø)

i have to retrieve some data from a txt file and then show those data inside my app.
My problem is that if i have the special char 'ø' inside my txt, this is not shown and a '?' is shown instead.
i tried to check data like
if(string.charAt(i) == 'ø') do sth
or
string.replace('ø' , 'O')
but none of them is working and i think that Java could not recognize that char at all.
Do you have any idea?
thanks
edit
this is how i read data
String[] obj = getText(getActivity(), myTXT.txt").split("\n");
where getText is:
public String getText(Context c, String fileName){
ByteArrayOutputStream outputStream = null;
try {
AssetManager am = c.getAssets();
InputStream is = am.open(fileName);
outputStream = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
int len;
while ((len = is.read(buf)) != -1){
outputStream.write(buf,0,len);
}
outputStream.close();
is.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return outputStream.toString();
}
These chars must be in UTF-8 encoding, check for your file while its getting saved whether its incoding. Create an InputStreamReader instance that uses the constructor specifying encoding.
InputStreamReader r= new InputStreamReader(new FileInputStream(myFile),"UTF-8");
// read your contents here.
r.close();

Solr Encoding/Decoding Data

I am trying to send a encoded string to Solr and then decode it on retrieval. My encode looks like:
public static String compress(String inputString) {
try {
if (inputString == null || inputString.length() == 0) {
return null;
}
return new String(compress(inputString.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
private static byte[] compress(byte[] input) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(input);
gzip.close();
return out.toByteArray();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
Then I send the to SOLR, and when I try to get it back (ignoring decoding for now because it fails here)
SolrDocument resultDoc = iter.next();
String content = (String) resultDoc.getFieldValue("source");
System.out.println(content);
If I send a string such as "Hello my name is Chris" the encoded will look like (ignoring what stack overflow changed);
ã�������ÛHÕ……W»≠T»KÃMU»,VpŒ( ,�ìùùG���
Yet what I get back from SOLR is
#31;ã#8;#0;#0;#0;#0;#0;#0;#0;ÛHÕ……W»≠T»KÃMU»,VpŒ( ,#6;#0;ìùùG#22;#0;#0;#0;
which will obviously make decoding fail. I have tried using the Jetty install and Tomcat both with the same issue.
See this entry from the example schema.xml file that comes with the Solr distribution.
<!--Binary data type. The data should be sent/retrieved in as Base64 encoded Strings -->
<fieldtype name="binary" class="solr.BinaryField"/>
Make sure that the field you are using to store your encoded value in the index is using the binary fieldType and that you are using base64 encoded strings.

Categories

Resources