Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 875387
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T11:15:39+00:00 2026-05-15T11:15:39+00:00

I am creating a custom component that is an image viewer for a given

  • 0

I am creating a custom component that is an image viewer for a given product number. I access these files using a modified version of BalusC’s ImageServlet:

@WebServlet(name="ImageLoader", urlPatterns={"/ImageLoader"})
public class ImageLoader extends HttpServlet {

    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.

    private static String imagePath = "\\\\xxx.xxx.x.x\\root\\path\\to\\images\\";

    /** 
      * This code is a modified version of the ImageServlet found at balusc.blogspot.com.
     * It expects the parameters id and n.
     * <ul>
     * <li><b>id:</b> the product number</li>
     * <li><b>n:</b> the image number to load.</li>
     */
    public void goGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        String productNumber = URLDecoder.decode(request.getParameter("id"),"utf-8");
        String img = URLDecoder.decode(request.getParameter("n"),"utf-8");

        if (productNumber == null || img == null) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        String path = generatePath(productNumber);

        File image = new File(generatePath(productNumber), generateImageName(img));

        // Check if file actually exists in filesystem.
        if (!image.exists()) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        String contentType = getServletContext().getMimeType(image.getName());

        if (contentType == null || !contentType.startsWith("image")) {
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        // Init servlet response.
        response.reset();
        response.setBufferSize(DEFAULT_BUFFER_SIZE);
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(image.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");

        // Prepare streams.
        BufferedInputStream input = null;
        BufferedOutputStream output = null;

        try {
            // Open streams.
            input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE);
            output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            // Write file contents to response.
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
        } finally {
            close(output);
            close(input);
        }
     }

    private String generateImageName(String n) {
        int imageNum = Integer.parseInt(n);

        StringBuilder ret = new StringBuilder("img-");
        if (imageNum < 10) {
            ret.append("00");
        }
        else if(imageNum < 100) {
            ret.append("0");
        }
        ret.append(n);
        ret.append(".jpg");
        return ret.toString();
    }


    public static String generatePath(String productNumber) {
        Long productNumberLng = Long.parseLong(productNumber);

        StringBuilder ret = new StringBuilder(imagePath);

        Long thousandPath = productNumberLng - (productNumberLng % 1000);
        ret.append(thousandPath);
        ret.append("s\\");
        ret.append(productNumber);
        ret.append("\\");
        ret.append(productNumber);
        ret.append("\\");

        return ret.toString();
    }

    private static void close(Closeable resource) {
        if (resource != null) {
            try {
                resource.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Next I created a composite component:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

  <!-- INTERFACE -->
  <cc:interface>
      <cc:attribute name="productNumber" shortDescription="The product number whose images should be displayed."

                    type="java.lang.Long" />
      <cc:attribute name="listID" shortDescription="This ID is the html ID of the &lt;ul&gt; element." />
  </cc:interface>

  <!-- IMPLEMENTATION -->
  <cc:implementation>
      <div id="#{cc.clientId}">
          <ul id="#{cc.attrs.listID}">
              <ui:repeat value="#{imageLoaderUtilBean.images}" var="image">
                  <li>

                      <h:graphicImage value="#{image.url}" alt="#{image.name}" />
                  </li>
              </ui:repeat>
          </ul>
      </div>
  </cc:implementation>
</html>

As you can see, I’m just grabbing the list of images from a managed bean. The only reason this is really necessary is because I need to know how many images there are for a given product. This can vary greatly (anywhere from 8 to 100). Here is that code:

@ManagedBean
@RequestScoped
public class ImageLoaderUtilBean {

    @ManagedProperty(value = "#{param.id}")
    private Long productNumber;

    private List<EvfImage> images;

    public List<EvfImage> getImages() {

        if (images == null) {
            setImages(findImages());
        }
        return images;
    }

    public void setImages(List<EvfImage> images) {
        this.images = images;
    }    

    public Long getProductNumber() {
        return productNumber;
    }

    public void setProductNumber(Long productNumber) {
        this.productNumber = productNumber;
    }

    private List<EvfImage> findImages() {


        FilenameFilter jpegFilter = new FilenameFilter() {

            @Override
            public boolean accept(File directory, String filename) {
                return filename.toLowerCase().endsWith(".jpg");
            }
        };

        File directory = new File(ImageLoader.generatePath(productNumber.toString()));
        if (!directory.exists()) {
            return new ArrayList<EvfImage>();
        }
        File[] files = directory.listFiles(jpegFilter);

        List<EvfImage> ret = new ArrayList<EvfImage>();

        for (int i = 1; i <= files.length; i++) {
            EvfImage img = new EvfImage();
            img.setName("file.getName()");
            img.setUrl("/ImageLoader?id=" + productNumber + "&amp;n=" + i);
            ret.add(img);
        }

        return ret;
    }

}

There is a simple object for holding the data I iterate over:

public class EvfImage {

    private String url;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}

Finally, I test this composite component using a URL of http://localhost:8080/project-name/testImages.xhtml?id=213123. Here is the code for testImages.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:sdCom="http://java.sun.com/jsf/composite/components/sd">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <sdCom:imageViewer listID="test" />
    </h:body>
</html>

Here is the problem: the only point of interaction between the application and the composite component should be the tag <sdCom:imageViewer listID="test" />. However, this is a leaky abstraction. The managed bean is given the product number based on the request’s id parameter. This is very undesirable. It creates much tighter coupling between the component and the app which is using it. Ideally, I should use the tag as follows: <sdCom:imageViewer listID="test" productNumber="213123"/>. However, I can’t figure out a way to do this and still know how many images I need to create.

Thanks in advance,
Zack

Edit: It would be perfectly acceptable to call a servlet which takes in the product number and returns the number of images which that product has. However, I have yet to find a way to run a loop n times (for loop) as opposed to running it once for each object in a Collection (foreach loop). I’m pretty much happy with any solution which involves removing that @ManagedProperty("#{param.id}") from the backing bean.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T11:15:39+00:00Added an answer on May 15, 2026 at 11:15 am

    A replacement of @ManagedProperty(value="#{param.id}") in ImageLoaderUtilBean would be

    <sdCom:imageViewer listID="test" productNumber="#{param.id}" />
    

    in combination with the following in cc:implementation before ui:repeat:

    <c:set target="#{imageLoaderUtilBean}" property="productNumber" value="#{cc.attrs.productNumber}" />
    

    Where the c: is the (actually discouraged) Facelets’ builtin JSTL library which is to be declared as follows:

    xmlns:c="http://java.sun.com/jsp/jstl/core"
    

    Facelets has no replacement for c:set (yet?).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 457k
  • Answers 457k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer When I alter the CSS in your file using Firebug… May 15, 2026 at 10:46 pm
  • Editorial Team
    Editorial Team added an answer Add a new CSS class: #main_nav { position: relative; top:… May 15, 2026 at 10:46 pm
  • Editorial Team
    Editorial Team added an answer The documentation of SQLInput (link below) has this on the… May 15, 2026 at 10:46 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.