How to display a dynamically-generated image (barcode) on a web page? - java

I have a barcode that I am dynamically generating, and want to pass to a gsp that will later become a pdf. I do not need to persist the barcode for any of my own purposes, and would like to simply pass the image from the controller to the gsp.
Is there a way to render an image that is passed as a variable rather than specifying a src?
Thanks in advance.
EDIT:
Since I am generating the pdf from the gsp, I am flushing the output stream of the response then, and therefore cannot do it with the image also, or I get an error.
Furthermore, using javascript/jQuery does not work since the page is never rendered directly by the browser.
It may look like the only option I have is to persist the images temporarily somewhere, and then delete them...

I answered a similar question recently, perhaps its answer will work for you. I'll paste a portion of it here. It's basically Oded's "outside of this..." suggestion.
class BarcodeController {
def index = {
def img // byte array, set this to the binary contents of your image
response.setHeader('Content-length', img.length)
response.contentType = 'image/png' // or the appropriate image content type
response.outputStream << img
response.outputStream.flush()
}
}
You could then access your image in the src of an tag like this:
<img src="${g.link(controller: 'barcode', action: 'index')}"/>
This answer seems to fit the last comment you made on the question (about a similar solution using PHP).

You can use a data URI scheme for the src attribute.
The data URI scheme is a URI scheme that provides a way to include data in-line in web pages as if they were external resources.
Here is an example from the wikipeida article:
<img src="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP
C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA
AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J
REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq
ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0
vr4MkhoXe0rZigAAAABJRU5ErkJggg==" alt="Red dot" />
Outside of this, if you are using a server side technology, you can stream the image data from a script (with the correct mime-type) and point the src attribute to it.
Here is a related SO question for grails.

Just want to contribute to this age-old question. I got this working by adding the following lines to BuildConfig.groovy:
In the plugins section:
plugins {
// other plugins here
// ...
compile ":barcode4j:0.3"
compile ":rendering:1.0.0"
}
In the dependencies section:
dependencies {
// other dependencies here
// ...
compile 'avalon-framework:avalon-framework:4.1.5'
}
Then I added a controller based on code examples I found on the net. I needed specifically a DataMatrix generator, but adding others should be easy just adding methods to the controller. Sorry for the bad quality code (I'm a Groovy newbie):
package myproject
import org.krysalis.barcode4j.impl.datamatrix.DataMatrix
import java.awt.Dimension
class BarcodeController {
// a valid PNG image, base64 encoded
static invalidBarcodeImgBase64 = """iVBORw0KGgoAA...=="""
// Needs index.gsp for testing
def index() {
['uuid': UUID.randomUUID(), 'fecha': new Date()]
}
def dataMatrix(String value) {
if ((null == value) || (value.length() < 1) || (value.length() > 2000)) {
def img = invalidBarcodeImgBase64.decodeBase64()
response.setHeader('Content-length', new Integer(img.length).toString())
response.contentType = 'image/png'
response.outputStream << img
response.outputStream.flush()
} else {
def generator = new DataMatrix()
generator.dataMatrixBean.setMinSize(new Dimension(16, 16))
renderBarcodePng(generator, value, [antiAlias: false])
}
}
def datamatrix(String value) {
dataMatrix(value)
}
}
Finally here's index.gsp in the barcode view for testing:
<%# page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<title>DataMatrix</title>
</head>
<body>
<g:img dir="barcode" file="dataMatrix?value=${uuid}"/>
<br />
<br />
<g:img dir="barcode" file="dataMatrix?value=${fecha}"/>
<br />
<br />
<g:img dir="barcode" file="dataMatrix?value=Nothing to see here"/>
</body>
</html>

Related

Play! 2.3.1 - displaying HTML source code instead of page

My Application class looks like this:
public class Application extends Controller {
public static Result index() {
return ok(index.render("<p>This is a paragraph</p>"));
}
and my index.scala.html file looks like:
#(htmlcode: String)
#main("Example") {
#htmlcode
}
and my main.scala.html file is fairly simple, with the standard !DOCTYPE declaration, html, head, body tags, etc.
...
<body>#content</body>
...
But when I run my application, the index page displays the source code <p>This is a paragraph</p> instead of just This is a paragraph. The source file looks like
...
<body>
<p>This is a paragraph</p>
</body>
...
How would I have the page render the code instead of just displaying it?
It is simply converting/protecting the values you are giving it. All the HTML markup should be done in the template (scala.html) file and not in the controller.
BTW this question comes pretty closes to this other question : How to pass raw html to Play framework view?
Simply use the Html() function
#main("Example") {
#Html(htmlcode)
}

Escaping html tags in html report

I have to write an HTML report from a java class which contains the source code of web pages. So the problem is that as soon as the source of a web page is encountered it is thought of by the browser as being the the end of html tags on the main report page and so the output is not renderd correctly. An example is shown below :
<html>
<body>
<li>
<pre>
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html>
<head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
The page was not found on this server.
</body>
</html>
</pre>
</li>
</body>
</html>
I want that everything inside the pre tags must be taken as normal text and not html markup. I tried replacing < with < , > with > , & with & etc.. but it doesnt seem to work. Any tips on how to make this possible?
EDIT :
This is what i tried (a is the part inside pre tags)
File aFile = new File(filename);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(aFile,aFile.exists()));
a.replaceAll("<","<");a.replaceAll(">",">");a.replaceAll("\"","&;quot;");a.replaceAll("&","&");
out.write(a + "\r\n");
out.close();
}
EDIT 2:
So this correct solution involved a=a.replaceAll(...), but another thing to note is that if i replace < with &gt and later on i replace & with &amp (like i do in the above example), It will againn mess my output(< will become <). So the order must also be changed(replcae & first and then <).
In Java, String objects are immutable. That means a.replaceAll doesn’t change a but returns a new String object in which the replacement took place.
So to fix this, you need to work with the returned object instead:
a = a.replaceAll("&","&").replaceAll("<","<");
And you actually only need to replace the & and < for your specific application.
do:
a = a.replaceAll("<","<");
instead of :
a.replaceAll("<","<");
and same for others...
As replaceAll method doesn't change the string, it rather returns a new one
Well.. replaceAll may work.. However, I'll always prefer to use StingEscapeUtils as ..
a = StringEscapeUtils.escapeHtml4(a)
The sequence you post in the comment:
a.replaceAll("<","<");
a.replaceAll(">",">");
a.replaceAll("\"","&;quot;");
a‌​.replaceAll("&","&");
won't work, since the replaceAll() method doesn't change the String it is called on. It can't, Strings are immutable in Java.
Also, as #Rishabh points out, your last replace call will mess up the previous replaces, so you need to change the order.
You need to do
a = a.replaceAll("&","&");
a = ...
Or, just do them all without saving the intermediate result:
a = a.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll("\"","&;quot;");
Also, you should probably use the replace() method instead of replaceAll(), there is no need to use regexes in this case.
Replace this line:
a.replaceAll("<","<");a.replaceAll(">",">");a.replaceAll("\"","&;quot;");a.replaceAll("&","&");
As this:
a = a.replaceAll("<","<").replaceAll(">",">").replaceAll("\"","&;quot;").replaceAll("&","&");

Java custom tag with JS

I have custom tag which contains form with text input and submit. I want to validate this text input using JS, so my custom tag output should look like:
<script type="text/javascript">
function validate(form) {
var text = form.textInput;
// validation code
}
</script>
<form onsubmit='return validate(this);'>
<input type='text' name='textInput'/>
<input type='submit'/>
</form>
(Note, this code simplified!)
My problem appears when I want to use this tag twice or more times at page - I want to print form at page again, but not JS validation code! Validation code must be unique at the page. How can I archive that? My custom tag extends javax.servlet.jsp.tagext.TagSupport
I found the most suitable solution for me.
Class javax.servlet.jsp.tagext.TagSupport contains protected field pageContext which presents... page context! I can easily access context attributes of javax.servlet.jsp.PageContext. So, I put next code in my custom tag:
public int doStartTag() throws JspException {
if (pageContext.getAttribute("validated") == null) {
// validation code writing
pageContext.setAttribute("validated", true);
}
...
}
If condition would be reachable only once per page rendering.
Hope it would be useful for someone.
I suggest you to try to embed that JavaScript function in some .js file an import that file. If you don't want to do that, for some reason you should try to define that function dynamically, if it is not defined:
if (typeof window.validateMyForm === 'undefined') {
window.validateMyForm = function(form) {
var text = form.textInput;
// validation code
}
}
As you guess this should define function only if it is not already defined.
First answer is correct, but that means that programer must know where in code are already inserted custom tags and according to that this whether to set that parameter to true or false. And what about code changes, you will have to always go thought whole page and revise all used tags on a page.
Make the custom tag to accept a parameter that toggles the validation on or off, and of course have it generate different code depending on the value of the parameter.

Delaying Output of JSP Custom Tag?

I want to delay the output of a custom tag.
The reason being: I want to add a tag to the head of the document that will compile a list of styles and scripts to include in the page. The subsequent tags in the page would add to the list of elements and the list would be printed once the body of the page has been generated.
Is this possible or is there a better way to do it. (I don't want to have to know what links are going to be added during the page compilation.)
Thanks
With JSPContext pushBody() and popBody() you can get some control over the order of output.
<%
Writer body = new StringWriter();
out = pageContext.pushBody(body);
// following code will write to 'body' and not to client
%>
...
<%
out = pageContext.popBody();
// normal output again
%>
...
<% // write the captured output %>
<%= body %>
Even though it works it might be better to work around as it is very confusing.
I have asked this question on a variety of sites and didn't get the answer I was looking for (although some were creative, Thanks!) so I ended up doing quite a bit of research on my own for the "best" way to do this. This is what I came up with:
I created three custom tags so my html would look like the following:
<html:page>
<html:head>
...
</html:head>
<html:body>
...
</html:body>
</html:page>
The page tag creates a variable in the REQUEST_SCOPE called "headercontents" in the doStartTag() method that can compile a list of output that I want to place in the head of the document.
The head element simply adds all of its body contents to this variable.
The body element does nothing as of now, just has a tag file with a simple .
Any element in the body can now use the "headercontents" variable to post information to the head of the html page. (Thus linking any stylesheets or scripts that it needs in the head rather than in the body).
Then finally in the page tag's doEndTag() method it prints the contents of the "headercontents" variable then prints the contents of itself (the contents of the html:body tag).
The result is that the document can load and rearrange itself as needed. This is still a rudimentary version but I'll perfect it and post the source code sometime in the future.

How I do get an image blob from JSP to JavaScript?

I retrieved a blob along with some other data from a table, say name and image:
name = varchar, image = blob
I set this to an object in my filter and pass it to the JSP file:
request.setAttribute("info", object);
In the JSP file I get that data:
request.getAttribute("info");
Now that I have the data from that object how do I go about passing that info to my JS file and render the image as a source for the JS file?
I'm trying:
<div>
<script type="text/javascript" src="jsFile.js></script>
</div>
var name = <%=info.name%>;
var image = <%=info.image%>
It just doesn't seem to be working. What is the correct method of doing this?
This isn't going to work. Leave the blob there in the server side. JavaScript on the client side can't do anything sensible with binary data. All it needs is an URL of the image so that it can reference it in the src attribute of a HTML <img> element, so that the webbrowser can in turn do its job of downloading and displaying the image. Best would be to include the image identifier in the URL. The name is unique for the image, right? Use that in the URL instead.
The first step is to let JS create a HTML <img> element with the proper src attribute which points to an URL which returns the image. Assuming that you're preparing the data like follows
String name = "foo.png";
String imageURL = "imageservlet/" + name;
request.setAttribute("imageURL", imageURL);
and are printing it in JSP(!) as if it are JS variables as follows
<script>
var imageURL = '${imageURL}';
// ...
</script>
(please note that those singlequotes are thus mandatory to represent them as a JS string variable)
so that they end up in the generated HTML source like follows (rightclick page in browser and do View Source to verify it)
<script>
var imageURL = 'imageservlet/foo.png';
// ...
</script>
then you can create the image as follows
var img = document.createElement("img"); // or getElementById("someId")?
img.src = imageURL;
// ... add to document?
(please note that this is just an example, I have no utter idea what the functional requirement is and what you would like to do with this image element, even more, perhaps JS code isn't needed at all for the concrete functional requirement)
so that it ends up like this in HTML:
<img src="imageservlet/foo.png" />
Now, the second step is to create a servlet which listens on an URL pattern of /imageservlet/*, retrieves the image as an InputStream from the database by the passed-in indentifier and writes it to the OutputStream of the response along a set of correct response headers. Long story short, I've posted several answers before as to how to do it, they contains kickoff code snippets:
How to retrieve and display images from a database in a JSP page?
Writing image to servlet response with best performance
You can access your data from the script if you set the variables in a script block before your jsFile.js. Ie:
<div>
<script type="text/javascript">
var name = <%=info.name%>;
var image = <%=info.image%>;
</script>
<script type="text/javascript" src="jsFile.js></script>
</div>
I'm not sure how you intend to handle the binary (BLOB) image data however? Typically this would be written to an image file on the server and referenced via an img tag:
<img src="/path/to/myimage.jpg" />
Instead of passing your blob data to the JSP file, I would suggest having the server (your servlet) pass a URL to the JSP which the browser can use to get the image via an img tag. You can either write the blob data to a URL or write a servlet that writes out Content-type: image/jpeg (or similar) data when passed an id, ie:
<img src="http://www.yourserver.com/GetImage?imageId=xxx" />

Categories

Resources