2

I'm trying to build a user profile page to show some details about my users.

The url of the page is something like profile.xhtml?username=randomString.

So, what I've to do is loading all the data of randomString's user.

It goes everything fine since it's the moment to show user's image.

I'm using PrimeFaces with graphicImage component, but the problem is that it causes a NEW request to get the image, so the request parameter is actually lost and the getAvatar() method receives a null parameter.

One solution may be making the bean SessionScoped, but it will take data from the first requested user and it will show them even if randomString will change, so I'm asking for help :

How can I show a dynamic image from database that depends on a request parameter?

Thanks :)

EDIT : New code following BalusC's reply

JSF Page :

<c:set value="#{request.getParameter('user')}" var="requestedUser"/>                    
<c:set value="#{(requestedUser==null) ? loginBean.utente : userDataBean.findUtente(request.getParameter('user'))}" var="utente"/>
<c:set value="#{utente.equals(loginBean.utente)}" var="isMyProfile"/>
<pou:graphicImage value="#{userDataBean.avatar}">
    <f:param name="username" value="#{utente.username}"/>
</pou:graphicImage>

(I'm using this vars because I want the logged user's profile to be shown if page request il just profile.xhtml without parameters)

Managed Bean :

@ManagedBean
@ApplicationScoped
public class UserDataBean {

    @EJB
    private UserManagerLocal userManager;

    /**
     * Creates a new instance of UserDataBean
     */
    public UserDataBean() {
    }

    public Utente findUtente(String username) {
        return userManager.getUtente(username);
    }

    public StreamedContent getAvatar(){
        String username = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("username");
        System.out.println(username==null);
        Utente u = findUtente(username);
        return new DefaultStreamedContent(new ByteArrayInputStream(u.getFoto()));
    }
}

What's wrong with it? username is always null!

EDIT 2 : Added reply to BalusC

Yeah, because the getAvatar() method calls findUser() as I need to find the user's entity with the username passed as parameter (<f:param> won't allow me to pass an object!).

So findUser() throws an exception because I'm using entityManager.find() with a null primary key!

Btw, I'm absolutely sure that both #{utente} and #{utente.username} are not null because the panel that contains the image is rendered only if #{utente ne null} and username is its primary key!

So I can't really check the HTML output!

I'm afraid that #{utente} is lost when I call getAvatar() as getting an Image requires a new http request

StepTNT
  • 3,867
  • 7
  • 41
  • 82

1 Answers1

7

Pass it as <f:param>. It will be added during render response.

<p:graphicImage value="#{images.image}">
    <f:param name="id" value="#{someBean.imageId}" />
</p:graphicImage>

The #{images} helper bean can just look like this:

@ManagedBean
@ApplicationScoped
public class Images {

    @EJB
    private ImageService service;

    public StreamedContent getImage() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if (context.getRenderResponse()) {
            // So, we're rendering the view. Return a stub StreamedContent so that it will generate right URL.
            return new DefaultStreamedContent();
        }
        else {
            // So, browser is requesting the image. Get ID value from actual request param.
            String id = context.getExternalContext().getRequestParameterMap().get("id");
            Image image = service.find(Long.valueOf(id));
            return new DefaultStreamedContent(new ByteArrayInputStream(image.getBytes()));
        }
    }

}

As the above helper bean has no request based state, it can safely be application scoped.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the reply! I've already tried that but without success :( I've added more code, because I'm sure that I'm doing something wrong! – StepTNT Apr 28 '12 at 13:14
  • Apparently `#{utente}` or `#{utente.username}` is `null`. What's the generated HTML output of ``? Which PrimeFaces version are you using? – BalusC Apr 28 '12 at 13:41
  • I've added `` before the image, and it shows the right value so they're both not null. Indeed, `getAvatar()` prints that the request parameter is null. I've got no html output because `getAvatar()` calls `findUser()` that throws a `Null PK Exception`. I'm on PF 3.2 – StepTNT Apr 28 '12 at 13:48
  • The `` is not a good test. The `` and `` runs during view build time while output text runs during view render time. You should really check the generated HTML output as I asked. Like so `` – BalusC Apr 28 '12 at 14:01
  • Wait, you got an exception while just opening the page in the browser? – BalusC Apr 28 '12 at 14:03
  • Comment too long, I've added it to the question – StepTNT Apr 28 '12 at 14:10
  • Right, the getter get invoked twice because the first time it needs to check if it's a `StreamedContent` or not so that it can generate the right URL during rendering the ``. I updated the answer. – BalusC Apr 29 '12 at 03:58