h:graphicImage does not display image in JSF - jsf

I have this in my class and I am trying to access it on my web page.
public String carImageURL = "/resources/images/sample_car.jpg";
This is the code I use in my web page that does not work.
<h:graphicImage value="#{carClass.carImageURL}"></h:graphicImage >
When I run the page there is no picture of the car in it.

Change the carImageURL attribute to private scope and write a getter method for it. Also write a slash at the beginning of the image path:
private String carImageURL = "/resources/images/sample_car.jpg";
public String getCarImageURL() {
return carImageURL;
}

Related

JSF redirect to same URL with different parameters

I have the following site structure:
web
|_events
|_view.xhtml
|_news
|_view.xhtml
|_pages
|_view.xhtml
...
When a user clicks a link to, let's say, Event #4, he will be redirected to e.g. http://example.com/events/view.xhtml?itemId=4On the event->view.xhtml page I have a menu with links to some other events (somehow related to the event that is currently viewed). Let's say those are Event #1 and Event #2.
Currently my menu links have value="../event/view.xhtml?itemId=#{row.id}". When it's clicked, the user will be redirected to e.g. http://example.com/events/view.xhtml?itemId=2
But if I use this approach (with "../event/" in the URL), it means that I have to create two more link types, with URLs for news and for pages. And also for every other item type that I make...
Is there any way to put only "itemId=X", i.e. only the new parameter value in the link value? Then I could use one menu template for every item type on my site.
Thanks!
You could use a List in ApplicationScope or SessionScope according to your use case and add all the type there.
Something like
public class Type implements Serializable {
private String name;
private List<Integer> items;
//getters and setters
}
Managed Bean
public class TestBean {
private List<Type> types;
#PostConstruct
public void init(){
//constructTypesAccordingToSomeLogic();
}
//getters and setter
}
View
<ui:repeat value="#{testBean.types}" var="type">
<ui:repeat value="#{type.items}" var="item">
<h:outputLink value="../#{type.name}.xhtml?itemId=#{item}"></h:outpuLink>
</ui:repeat>
</ui:repeat>

jsf menuitem does not set property

i try to set normal property by menu-item, but it is does not work.
jsf:
<p:menuitem value="Names"
url="/master.xhtml"
action="#{navigation.name}">
<f:setPropertyActionListener target="navigation.name"
value="Billy" />
</p:menuitem>
ManagedBean:
#ManagedBean(name="navigation")
#SessionScoped //
public class LinksNavigation {
public LinksNavigation() {
super();
this.milchFleisch = "./menuFleisch.xhtml";
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
}
But it does not work. I dont set with "f:setPropertyActionListener"
value = "Bully". How can i set property Value by menuItem??
Thanks
In setPropertyActionListeneryou have a String instead of an EL expression. Change
target="navigation.name"
to
target="#{navigation.name}"
Also, you need to take a closer look to at the tag documentation for p:menuitem. The attribute action is expecting a method expression. You will get a MethodNotFoundException with the way your code is set up. You need to change
action="#{navigation.name}"
to
action="#{navigation.getName}"
The abbreviated syntax #{navigation.name} is used for value expressions.
You are mixing navigation methods. You cannot have the attributes url and action together for the same p:menuItem. When I tested your code action and setPropertyActionListener were never called when url was present. This behavior suggest that you have to pick one or the other.
COMMENT
Based on your sample, I think you should rethink your approach. Let's pretend for a moment that you decided not to use url="/master.xhtml" and let's go over the sequence of events. After you press the menu item, the expression #{navigation.name} in setPropertyActionListener will first set the value "Billy" to your name property (e.g. navigation.setName("Billy")). Then the expression #{navigation.getName} in the attribute action will call getName(). Now action will have the String value "Billy" and it will try to navigate to Billy.xhtml (assuming no navigation rules in faces-config and you have JSF 2.0). If that's the behavior you're after or if you have rules set up in faces-config and you are not hardcoding the value than that's another story entirely. Just keep this in mind.

Seam - understanding PAGE scope and CONVERSATION scope

I still get confused about the PAGE and the CONVERSATION (temp) scope. Maybe I get some help here.
As fas as I know, variables outjected to the PAGE scope live as long as the user only postbacks the same page. The temporary CONVERSATION scope instead even survives a redirect to the next page.
Here is a little example with two effects that are confusing to me:
First, component and outjections are in CONVERSATION scope and the tempUser data is displayed in a jsf page. But in the save method called from that jsf-page, the injected tempUser is null. Why?
Second, if I do the same but change component and #In/#Outs scopes to PAGE scope, the tempUser gets correctly injected on postback - but gets not saved, for wathever reason, although even the super.update()-method on userHome gets called. Or is there a problem in using the homeEntities that ways (the idea iwa to use them only as DAO wrapper)?
#Name("userAction")
#Scope(ScopeType.CONVERSATION)
public class UserAction implements Serializable {
private static final long serialVersionUID = -4852371546895918692L;
#In(create = true)
private UserHome userHome;
#Out(scope = ScopeType.CONVERSATION)
#In(required = false,scope = ScopeType.CONVERSATION)
User tempUser;
#RequestParameter
private Long userId;
#Factory("tempUser")
public User getUser() {
if (tempUser == null) {
userHome.setUserId(userId);
tempUser = userHome.getInstance();
userHome.clearInstance();
}
return tempUser;
}
public void save() {
userHome.setInstance(tempUser);
userHome.update();
}
}
The xhtml contains a a:form with
<a:commandButton
id="update"
styleClass="button admin"
action="#{userAction.save}"
value="#{messages['user.action.update']}"/>
Thanks for replies. Sorry, if this is two problems in one.

Showing a dynamic image that depends on a Request Parameter

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
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.

Not getting image in h:graphicImage in JSF

I have this very strange error with h:graphicImage
This code works fine :-
<h:graphicImage value="/Common/Images/#{item.templatePicName}"/>
And this one doesn't :-
<h:graphicImage alt="${app:getCommonImagePath(item.templatePicName)}" value="${app:getCommonImagePath(item.templatePicName)}" />
It only shows alt value /Common/Images/Sunset.jpg which is perfectly fine and works in 1st case. Then why doesn't it work in 2nd case? There are no problems with my images. They are present in right directory.
here getCommonImagePath is my custom EL function, whose definition is :
package Common;
public final class AppDeployment {
private AppDeployment(){ //hide constructor
}
private static String commonImageFolderPath = "/Common/Images/";
public static String getCommonImagePath(String picName){
return commonImageFolderPath + picName;
}
}
With JSF you should use #{..} rather than ${..}.
Then check the HTML that is generated to see what the src of the generated image is pointing to.
Then check whether your custom tag is mapped properly.
Its easier to solve if you have a property in your app class that concatenates what you want.
ie:
class App {
private String commonImagePath="/Common/Images/";
//getters and setters
}
Then you would write:
<h:graphicImage alt="#{app.commonImagePath}#{item.templatePicName}" value="#{app.commonImagePath}#{item.templatePicName}" />

Resources