GWT - image from database - java

I'm actually working on a GWT based website.
Now I'm stuck on how I should display images stored in a database on my website.
Basically I've a bytearray in my database, which I fetch using hibernate.
Now should I probably create an ... tag out of that data, but I don't know how
I'm using GWT in Java and Hibernate

Here is the solution. First you should encode the byte array by using com.google.gwt.user.server.Base64Utils.toBase64(byte[]) . But this method does not work for IE 7. and IE8 has 32kb limit.. IE9 does not have this limit.
here is the method on the server
public String getImageData(){
String base64 = Base64Utils.toBase64(imageByteArray);
base64 = "data:image/png;base64,"+base64;
return base64;
}
Here is the client method ;
#Override
public void onSuccess(String imageData) {
Image image = new Image(imageData);
RootPanel.get("image").add(image);
}

I don't know how GWT works, albeit you can map a servlet/controller which returns resourceStream.
For example if you map a servlet "imageViewer" which takes imageId param, request to image would become
/imageViewer?imageId=1234
Hibernate object would have reference to the blob, so you can return that.
Reference on UI would be
<img src="/imageViewer?imageId=1234"/>
Update: You may not be able to use Model as it is to return image, you would need an explicit controller or servlet which returns stream data.
In servlet you would do something like
// get reference to input stream
InputStream in = hibnerateObject.getImage();
// set MIME type etc
response.setContentType(mimeType);
OutputStream out = response.getOutputStream();
while ((len = in.read(buf)) >= 0)
out.write(buf, 0, len);
in.close();
out.close();

There is Image Widget in GWT. You can't do it client-side but you can call RPC to communicate with the server. Then it is simple CRUD application. In server connect to database with hibernate and return the Image to the client or it's url and on the client-side do something like that :
#Override
public void onSuccess(String imageUrl) {
Image image = new Image(imageUrl);
RootPanel.get("image").add(image);
}
#Override
public void onFailure(Throwable caught) {
Window.alert(caught.getMessage());
}
That's all. Happy coding

I used the same approach as Gursel Koca suggested but could only get it to work using the Apache Base64 library, not (ironically) the GWT Base64Utils
String base64 = Base64.encodeBase64String(array);
base64 = "data:image/"+type+";base64," + base64;
return base64;
Also note that if you are updating an existing image or an image placeholder, the setURL method will overwrite your stylesheet, so make sure to grab that first:
String styleName = profilePicture.getStyleName();
profilePicture.setUrl(base64String);
profilePicture.setStyleName(styleName);

Related

Base64encoding and base64decoding in dart and Java

Is base64encode and decode in dart is same for Java. In my flutter app I want to upload an image. I convert that image to string by base64Encode(file. readAsBytesSync()). And then I passed it to backend. Backendcode is in JAVA. I want to decode this image file in java for save into a folder. How it is possible. Is I decode image gives same result.? I want to fetch it back also. Please help
Putting all my comments as an answer here are 2 utility functions
public static BufferedImage decode(String base64Image)throws Exception
{
Base64.Decoder decoder=Base64.getDecoder();
ByteArrayInputStream decoded=new ByteArrayInputStream(decoder.decode(base64Image));
return ImageIO.read(decoded);
}
public static void writeImage(ByfferedImage img,File file)throws Exception
{
ImageIO.write(img,"png",file);
}

How to send a InputStream in play framework in an java only project without chunked responses?

In a Java (only) Play 2.3 project we need to send a non-chunked response of an InputStream directly to the client. The InputStream comes from a remote service from which we want to stream directly to the client, without blocking or buffering to a local file. Since we know the size before reading the input stream, we do not want a chunked response.
What is the best way to return a result for an input stream with a known size? (preferable without using Scala).
When looking at the default ok(file, ..) method for returning File objects it goes deep into play internals which are only accessible from scala, and it uses the play-internal execution context which can't even be accessed from outside. Would be nice if it would work identical, just with an InputStream.
FWIW I have now found a way to serve an InputStream, which basically duplicates the logic which the Results.ok(File) method to allow directly passing in an InputStream.
The key is to use the scala call to create an Enumerator from an InputStream: play.api.libs.iteratee.Enumerator$.MODULE$.fromStream
private final MessageDispatcher fileServeContext = Akka.system().dispatchers().lookup("file-serve-context");
protected void serveInputStream(InputStream inputStream, String fileName, long contentLength) {
response().setHeader(
HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + fileName + "\"");
// Set Content-Type header based on file extension.
scala.Option<String> contentType = MimeTypes.forFileName(fileName);
if (contentType.isDefined()) {
response().setHeader(CONTENT_TYPE, contentType.get());
} else {
response().setHeader(CONTENT_TYPE, ContentType.DEFAULT_BINARY.getMimeType());
}
response().setHeader(CONTENT_LENGTH, Long.toString(contentLength));
return new WrappedScalaResult(new play.api.mvc.Result(
new ResponseHeader(StatusCode.OK, toScalaMap(response().getHeaders())),
// Enumerator.fromStream() will also close the input stream once it is done.
play.api.libs.iteratee.Enumerator$.MODULE$.fromStream(
inputStream,
FILE_SERVE_CHUNK_SIZE,
fileServeContext),
play.api.mvc.HttpConnection.KeepAlive()));
}
/**
* A simple Result which wraps a scala result so we can call it from our java controllers.
*/
private static class WrappedScalaResult implements Result {
private play.api.mvc.Result scalaResult;
public WrappedScalaResult(play.api.mvc.Result scalaResult) {
this.scalaResult = scalaResult;
}
#Override
public play.api.mvc.Result toScala() {
return scalaResult;
}
}

Apache Wicket: File download that would not lock the page

I want to create a link that would initiate a file download which would be asynchronous to the page itself, i.e. I want the page not to be locked during the file download. Should I make it be initiated outside wicket? Or is there something inside wicket that would let me set up a resource stream which would bypass the page locks?
Things I tried:
DownloadLink - locks the page, as stated in its doc. This was my starting point.
ResourceLink - did not state the locking explicitly in the doc, so I tried this, but it also locked the page.
At this point I've investigated the code of both links a bit and noticed they both schedule the download via ResourceStreamRequestHandler. Expecting that his kind of behavior could be just handler-specific I've attempted to schedule a custom handler I've written:
private void sendFile(final File file) throws IOException {
IRequestHandler fileDownloadHandler = new IRequestHandler() {
#Override
public void respond(IRequestCycle requestCycle) {
WebResponse response = (WebResponse) requestCycle.getResponse();
OutputStream outStream = response.getOutputStream();
response.setContentType("audio/x-wav");
response.setContentLength((int)file.length());
String fileName = "Somethingsomething.wav";
// sets HTTP header
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
byte[] byteBuffer = new byte[1024];
DataInputStream in = null;
try {
in = new DataInputStream(new FileInputStream(file));
int length = 0;
// reads the file's bytes and writes them to the response stream
while ((in != null) && ((length = in.read(byteBuffer)) != -1))
{
outStream.write(byteBuffer,0,length);
}
in.close();
outStream.close();
} catch (IOException e) {
throw new PortalError("IOException trying to write the response", e);
}
}
#Override
public void detach(IRequestCycle requestCycle) {
}
};
getRequestCycle().scheduleRequestHandlerAfterCurrent(fileDownloadHandler);
}
This did not quite work either, so I've investigated further. I've noticed that unlike I expected, the "scheduled" request handlers would not get executed on a separate request, as I expected, but on the same one. I figured that it must be that the page gets locked for the first handler and then remains locked while the second one is executing as well. So I've attempted to force the download handler into a separate request (via an ajax behaviour):
public void startDownload(AjaxRequestTarget target) throws DownloadTargetNotFoundException{
target.appendJavaScript("setTimeout(\"window.location.href='" + getCallbackUrl() + "'\", 100);");
}
#Override
public void onRequest() {
sendFile(getFile());
logger.debug("Download initiated");
}
I've found this here and hoped it could potentially be what I've been looking for. However, unsurprisingly so, the page gets locked still (I would imagine because the behaviour still has to be retrieved from the page, for which the page lock has to be acquired).
I'm at a loss where I should be looking next, especially after all this time trying to get a simple download link working. I was considering creating another web filter one layer above wicket, which could be signaled from within wicket to create the download after the wicket filter is finished with its work (and hence the page lock is already released), but that seems a bit excessive for a task like this.
Any suggestions are welcome.
You have to download from a resource, see
http://wicketinaction.com/2012/11/uploading-files-to-wicket-iresource/ and read http://wicket.apache.org/guide/guide/resources.html

How to set HTTP header in Apache JClouds?

I'm using Apache JClouds to connect to my Openstack Swift installation. I managed to upload and download objects from Swift. However, I failed to see how to upload dynamic large object to Swift.
To upload dynamic large object, I need to upload all segments first, which I can do as usual. Then I need to upload a manifest object to combine them logically. The problem is to tell Swift this is a manifest object, I need to set a special header, which I don't know how to do that using JClouds api.
Here's a dynamic large object example from openstack official website.
The code I'm using:
public static void main(String[] args) throws IOException {
BlobStore blobStore = ContextBuilder.newBuilder("swift").endpoint("http://localhost:8080/auth/v1.0")
.credentials("test:test", "test").buildView(BlobStoreContext.class).getBlobStore();
blobStore.createContainerInLocation(null, "container");
ByteSource segment1 = ByteSource.wrap("foo".getBytes(Charsets.UTF_8));
Blob seg1Blob = blobStore.blobBuilder("/foo/bar/1").payload(segment1).contentLength(segment1.size()).build();
System.out.println(blobStore.putBlob("container", seg1Blob));
ByteSource segment2 = ByteSource.wrap("bar".getBytes(Charsets.UTF_8));
Blob seg2Blob = blobStore.blobBuilder("/foo/bar/2").payload(segment2).contentLength(segment2.size()).build();
System.out.println(blobStore.putBlob("container", seg2Blob));
ByteSource manifest = ByteSource.wrap("".getBytes(Charsets.UTF_8));
// TODO: set manifest header here
Blob manifestBlob = blobStore.blobBuilder("/foo/bar").payload(manifest).contentLength(manifest.size()).build();
System.out.println(blobStore.putBlob("container", manifestBlob));
Blob dloBlob = blobStore.getBlob("container", "/foo/bar");
InputStream input = dloBlob.getPayload().openStream();
while (true) {
int i = input.read();
if (i < 0) {
break;
}
System.out.print((char) i); // should print "foobar"
}
}
The "TODO" part is my problem.
Edited:
I've been pointed out that Jclouds handles large file upload automatically, which is not so useful in our case. In fact, we do not know how large the file will be or when the next segment will arrive at the time we start to upload the first segment. Our api is designed to make client able to upload their files in chunks of their own chosen size and at their own chosen time, and when done, call a 'commit' to make these chunks as a file. So this makes us want to upload the manifest on our own here.
According to #Everett Toews's answer, I've got my code correctly running:
public static void main(String[] args) throws IOException {
CommonSwiftClient swift = ContextBuilder.newBuilder("swift").endpoint("http://localhost:8080/auth/v1.0")
.credentials("test:test", "test").buildApi(CommonSwiftClient.class);
SwiftObject segment1 = swift.newSwiftObject();
segment1.getInfo().setName("foo/bar/1");
segment1.setPayload("foo");
swift.putObject("container", segment1);
SwiftObject segment2 = swift.newSwiftObject();
segment2.getInfo().setName("foo/bar/2");
segment2.setPayload("bar");
swift.putObject("container", segment2);
swift.putObjectManifest("container", "foo/bar2");
SwiftObject dlo = swift.getObject("container", "foo/bar", GetOptions.NONE);
InputStream input = dlo.getPayload().openStream();
while (true) {
int i = input.read();
if (i < 0) {
break;
}
System.out.print((char) i);
}
}
jclouds handles writing the manifest for you. Here are a couple of examples that might help you, UploadLargeObject and largeblob.MainApp.
Try using
Map<String, String> manifestMetadata = ImmutableMap.of(
"X-Object-Manifest", "<container>/<prefix>");
BlobBuilder.userMetadata(manifestMetadata)
If that doesn't work you might have to use the CommonSwiftClient like in CrossOriginResourceSharingContainer.java.

How to pass java Inputstream to Javascript

I'm developing an application with jquerymobile and Spring MVC. I'm getting an image in a controller as Inputstream and the next step is to pass this image to Javascript for show in a dialog with JqueryMobile.
How can I pass this java Inpustream image to javascript?
PS. The controller is called throught jquerymobile ajax so i have onSuccess method waiting to make something with returned data from controller.
Why not load that image from java using Jquery on a div?
var url = 'myimage.com/image_java_url?'+dataToSend
$('#myDiv').load(url, function(response, status, xhr) {
if (status = "success"){
$('#myDiv').html(response);
}
});
I assume you are creating a REST-endpoint to recieve an image. If so, you could make your Spring-endpoint take HttpServletResponse as an argument and stream the image out to the servlet outputstream.
Wrap the inputstream in a BufferedInputStream for to let it handle the buffering for you.
To get hold of the HttpServletResponse just add it as an argument to your method,
#RequestMapping(value = "/something")
public void helloWorld(HttpServletResponse response) {
InputStream imageStream = .....;
OutputStream oSteam = response.getOutputStream();
InputStream stream = new BufferedInputStream(imageStream );
int b = -1;
while((b = stream.read())> -1){
oSteam.write(b);
}
I haven't had much experience with Spring, but I would use the javax.ws.rs.core.Reponse class in Java EE. This will allow you to construct a http response using Response.ResponseBuilder, wrapping your InputStream.
i.e.
Response.ok(inputStream, MEDIA_TYPE.APPLICATION_OCTET_STREAM).build();

Categories

Resources