Solved

JSF application that needs to create and display graphics on request

Posted on 2006-06-30
15
1,007 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
 
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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Moving applications to the cloud or switching services to cloud-based ones, is a stressful job.  Here's how you can make it easier.
What is Backup? Backup software creates one or more copies of the data on your digital devices in case your original data is lost or damaged. Different backup solutions protect different kinds of data and different combinations of devices. For e…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

744 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now