Solved

JSF application that needs to create and display graphics on request

Posted on 2006-06-30
15
1,014 Views
Last Modified: 2008-01-09
Hello,

I have a JSF application that needs to create and display graphics on request.

I need to do the following:

1) User selects attributes and pushes a button.
2) Server side generates a graph in a BufferedImage
3) The image from the BufferedImage is displayed in an image (h:graphicImage or ui:image) component.

I need an explanation and code example that goes through this process in detail. (Everything I found so far does not provide enough details to understand the process)

To date, I have been able to generate the BufferedImage graphic, but have not been successful in getting the image to display in the graphics component.

Thank you in advance for you help.
0
Comment
Question by:awilner
  • 6
  • 5
  • 4
15 Comments
 
LVL 15

Expert Comment

by:bpmurray
ID: 17019064
You don't explain how you managed to create the bufferedImage - I'll assume it's a bean of some sort. This means you can use something like:

      <h:graphicImage id="foo" value="bufferedImageBean.image" ... />

This will call the getImage() method of the bufferedImageBean object.
0
 
LVL 27

Expert Comment

by:rrz
ID: 17019204
I think you should use a servlet. Something like  this.

package test;
import javax.imageio.ImageIO;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ImgServlet extends HttpServlet {
      public void doGet(HttpServletRequest request,
                        HttpServletResponse response) throws IOException, ServletException
        {
             ServletOutputStream sos = response.getOutputStream();
             BufferedImage bi = new BufferedImage(100,100,BufferedImage.TYPE_INT_BGR);
             Graphics2D off = bi.createGraphics();
             off.setColor(Color.blue);
             off.fill3DRect(0,0,100,100,true);
             response.setContentType("Image/png");
             ImageIO.write(bi,"png",sos);
      }

}

So, for example,  if you map the ImgServlet to  /myImg  in your  context's web.xml file, then you can use
<h:graphicImage value="/myImg" />


0
 

Author Comment

by:awilner
ID: 17020179
Thank you for your response,

The part that leaves me hanging here is this:

So, for example,  if you map the ImgServlet to  /myImg  in your context's web.xml file, then you can use <h:graphicImage value="/myImg" />

I know the answers are probably intuitively obvious, but:
The questions I still have are:
1) How do I "map the ImgServlet to /myImg in your context's web.xml file"??
2) It looks like the graphics is entirely contained within the servlet,

How do I pass parameters (plot variables like location and size) to the servlet?
3) What initiates the actual execution of the servlet?  How do I control when the plot is drawn?

I went through this servlet stuff a month or two ago and ran into the same types of issues.  It seemed that I was able to get an image generated when the application started, but not "on demand".
I was wondering you can help me answer the quesstion that still remains - how do I initiate the drawing in response to a button press?
Thanks agains.
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 15

Expert Comment

by:bpmurray
ID: 17020571
Add this to your web.xml:

        <servlet id="myServlet">
            <servlet-name>My Graphics Servlet</servlet-name>
            <servlet-class>com.foo.faces.webapp.GraphicsServlet</servlet-class>
            <load-on-startup>-1</load-on-startup>
      </servlet>
        ---
      <servlet-mapping>
            <servlet-name>My Graphics Servlet</servlet-name>
            <url-pattern>/myImg/*</url-pattern>
      </servlet-mapping>



Then when you have <h:graphicImage value="/myImg/graphicname" /> in your page, your servlet is called and you can see that the graphic you want is "graphicname". In the doGet method, you can get the URL it was called with as:
        String uri = req.getRequestURI();

From the end of that you can extract the name. The "on demand" happens because the client sends a request for that graphic, which is interpreted by the appserver and directed to the servlet. You can pass in params too - value="/myImg/graphicname?height=120&width=1100&color=red" will send you the URL as before in the request url, and the request params will contain the params.
0
 
LVL 27

Accepted Solution

by:
rrz earned 340 total points
ID: 17020573
>1) How do I "map the ImgServlet to /myImg in your context's web.xml file"??
    <servlet>
        <servlet-name>imgServlet</servlet-name>
        <servlet-class>yourPackage.ImgServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>imgServlet</servlet-name>
        <url-pattern>/myImg</url-pattern>
    </servlet-mapping>
>2) It looks like the graphics is entirely contained within the servlet,
Yes, in my example it is, but you can put code in a bean and then call the bean from the servlet.
>How do I pass parameters (plot variables like location and size) to the servlet?  
You can append a query string  (see last answer as well)
<h:graphicImage value="/myImg?size=123&location=345" />
>3) What initiates the actual execution of the servlet?  How do I control when the plot is drawn?  
The browser requests the image from the servlet. The image is returned by the servlet in its response.
>how do I initiate the drawing in response to a button press?  
>1) User selects attributes and pushes a button.  
You could have a form on your  page that submits the parameters to the server. If the server receives the parameters then it can put them in a scope or hold them in a bean. When the servlet receives a request it can access the data and draw the  graphic.  
If you need help, then you should post some bare bones code( leave out the JSF) and we will help you with it.    rrz
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 17020674
> post some bare bones code( leave out the JSF)
Actually, it's important to stress that this is bypassing the JSF stuff. Your page ends up with the generated HTML <img src="/myImg/whatever"> which causes the servlet to be called to deliver the graphics content. This is external to the JSF lifecycle.
0
 

Author Comment

by:awilner
ID: 17021555

I've added a servlet class to the project, included the reference in the web.xml file and
have the component value attribute set to the url-pattern for the servlet.
I assume this should be all the setup I need.  

The remaining question:

>>3) What initiates the actual execution of the servlet?  How do I control when the plot is drawn?  
>The browser requests the image from the servlet. The image is returned by the servlet in its response.

I assume that the browser will request the image when the page containing the h:graphicImage component is displayed,
and that each time the page is re-displayed, a new version of the image will be generated and displayed.
Is this correct??

I have placed the component on the main startup page of an existing project.
I would expect the image to be displayed when the main page is first displayed, but it is not..

Alsio, I have a button action that returns a null string and that should redisplay the page as well, but I do not see the image then, either.

Let me know if my assumptions are correct.
I added this to an existing project for testing so there may be an issue with something else in the project.
I will create a new project with the following:
1) Main page with an h:graphicImage component and a button.
2) A second page with another h:graphicImage component and a button.
Pushing the the button on either page will cause the navigation to the other page.

I should expect to see an image displayed on each page.  Is that correct??

Let me know if there is anything else I need for this test.

If I have problems, I will post the code.

0
 
LVL 15

Assisted Solution

by:bpmurray
bpmurray earned 160 total points
ID: 17021649
Yes, you should see the display on each page.

Just to check that everything is setup correctly, have a look at the rendering of the page - does it generate the expected <img> tag? If so, the non-display is because of the server failure. Check that you have the correct pattern in the web.xml. Just in case there's any confusion: the pattern is the root of the name of the graphic, e.g. "/myImg/*", and the value is the specific file name, i.e. value="/myImg/foo.img".
0
 
LVL 27

Expert Comment

by:rrz
ID: 17021709
>I would expect the image to be displayed when the main page is first displayed, but it is not..  
First try browsing to the servlet directly by typing into the browser's address bar.  If that doesn't work show your code, your web.xml entries and the url you typed.
0
 

Author Comment

by:awilner
ID: 17021716


OK, it looks like I can make things work with the 2-page scenario in my last post.

I get an image when the first page initially loads and I get an image when I change between pages.

My basic problem was looking at this from a server-side perspective in the past and not really understanding
the servelet definition and servlet mapping in the web.xml file (Not coming from a web background).

This gets me to where I need to be for now.

A couple of follow-up questions:
1) Is there any way to combine functions within a single servlet?  What I mean by that is - could I have more than 1
task per servlet with different mappings?  If so, how are they separated?

2) Is there any way that a server-side event can force a redraw of the graphics component?
It looks like a client-side initiated refresh/redraw is required.

Also, a comment was made that this basically sidesteps the JSF lifecycle.  
Can you think of an instance where that might be an issue?
I'm thinking that this should basically parallel the JSF model and will update whenever the whole page updates.

0
 
LVL 27

Expert Comment

by:rrz
ID: 17021768
>1) Is there any way to combine functions within a single servlet?  
Yes, but why not have two servlets ?  Anyway you could use doGet and doPost  separately. Or you could use parameters to satisfy  conditionals.
>2) Is there any way that a server-side event can force a redraw of the graphics component?  
Tell us more details.  What event ?  Do you want to keep polling the server ?  
>Can you think of an instance where that might be an issue?  
When and how are you changing the graphic ?
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 17022964
>Can you think of an instance where that might be an issue?
>I'm thinking that this should basically parallel the JSF model and will update whenever the whole page updates.
No, it's not an issue. I use it all the time for non-lifecycle stuff. Where it breaks down is if you need something from the component tree to calculate which graphic you need. However, you can work around that by adding appropriate params to the value of the graphic component, i.e. value=${mybean.graphicname}, where mybean.getGraphicname() generates the appropriate thing.
0
 

Author Comment

by:awilner
ID: 17024375
Thank you both very much, for taking me through to the resolution. I got it working.
rrz@871311 provided the model I used; bpmurray gave a lot of the info and some good points.
Hope you don't mind me spliting the points.
Thanks again.
0
 
LVL 15

Expert Comment

by:bpmurray
ID: 17024705
Thanks, awilner: I actually didn't expect any, but of course I'll graciously accept them :-)
0
 
LVL 27

Expert Comment

by:rrz
ID: 17025268
> I got it working.  
Good, thanks for the points.    
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This tutorial shows how to create a greeting card by combining two image layers and a text layer on a PC using a free image editing app.
February 24, 2017 — On February 23, Travis Ormandy, a vulnerability researcher at Google, reported on Twitter (https://twitter.com/taviso/status/834900838837411840) that massive stores of data have been leaked by CloudFlare, a company that provide…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question