How to add text in Facelets - jsf

Im new to web programming so this is a beginner question.
In my web application which is a maven project with JSF framework(university project), I have some pages with just text that displays various information about my fake air line company(only consists of <p> and <h1>). Now, to my question. Should I just "hard code" the information on the JSF Page or should I use beans to get my text and titles from?
The information that will be on my info pages will remain the same and never change.
If this question is inappropriate to ask here, please let me know and Ill remove it.

Since you've stated that the information will never change, storing it in a string in the bean class would work, and use getter methods to retrieve the data
#ManagedBean
#SessionScoped
public final class Airlineimplements Serializable
{
private static final long serialVersionUID = 47493274L;
private String title = "Air Canada";
private String headquarters = "Toronto Ontario Canada";
public Airline()
{
}
public String getTitle()
{
return title;
}
public String getHeadquarters()
{
return headquarters;
}
}
This is #RequestScoped so that you retrieve the information on each request and the information is garbaged after the request.
A #RequestScoped bean will be garbaged by end of every request and recreated on every new request.
Full answer here about #ViewScoped vs #RequestScoped
Difference between View and Request scope in managed beans
Although this should be #SessionScoped which keeps the information for the life of the session.
For the Serializable UID, the serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to ensure that the caller and receiver of a Serialized object have the same loaded classes.
More information about Serializable
http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
Here are some additional tutorials on JSF for beginners
http://www.tutorialspoint.com/jsf/
http://www.vogella.com/tutorials/JavaServerFaces/article.html

Related

How to have one instance of Backing Bean per Browser tab?

My environment: Java 7/JSF 2.1/PrimeFaces 6.1.
My goal: to have a certain page of my application instantiated many times, one for each browser tab, each one with a different context.
My problem: everytime I open a second browser tab requesting from the same url, but with different object id, the previous one is destroyed, so only one backing bean instance is kept alive.
How do I know that: In my backing bean I have one method annotated with #PosConstruct and other with #PreDestroy, so I can track the life cicle of the instances.
My backing bean is annotated as follows:
#ViewController
public class MyBackingBeanMB extends AbstractBackingBeanMB {
private static final long serialVersionUID = 1L;
// many fields and methods
}
The #ViewController annotation is provided by the application framework I have to use. Such an annotation is declared as:
#Named
#Controller
#Stereotype
#ViewScoped // For me, this should do the trick, but...
#Target(value={TYPE})
#Retention(value=RUNTIME)
#Inherited
public #interface ViewController {
}
Update 1:
The #Controller annotation is also provided by the framework I use and is declared as:
#InterceptorBinding
#Inherited
#Target({ TYPE, METHOD })
#Retention(RUNTIME)
public #interface Controller {
}
Any ideas of what could be wrong?
TIA.
After some digging in the Internet I found Apache DeltaSpike, which provider a new kind of managed bean scope, WindowScoped.
Managed beans annotated with #WindowScoped` operate just like I wanted, providing me with the exact behaviour I needed and it is absolutely compatible with the framework I have to use.

using #Model `javax.enterprise.inject.Model` for JSF backing bean? [duplicate]

This question already has answers here:
How to choose the right bean scope?
(2 answers)
Closed 2 years ago.
I'm trying to implement JSF backing beans using CDI beans as suggested by the depreciation of #ManagedBean and it's scope annotations, but I'm struggling with the right use examples, I'm trying to implement view backing bean with #Model (javax.enterprise.inject.Model) which is #Named #RequestScoped.
I found this question but it's using a ViewScope bean, how would I implement the same functionality with RequestScoped (Preferably #Model), What is best practice use of #Model in general?
Edit 1:
I tried creating a new Product in the EditProduct PostConstruct:
#Model
public class EditProduct {
private Product product; // +getter +setter
#Inject
private ProductService productService;
#PostConstruct
public void init(){
product = new Product();
}
public String save() {
productService.save(product);
return "/products?faces-redirect=true";
}
// ...
}
and then setting the product via
<f:viewParameter name="product-id" target="#{editProduct.product}"
converter="#{productConverter}" />
it's working but I'm looking for a best practice.
A request scoped backing bean is meant to keep the application memory footprint as low as possible hence using them for supporting views with #Model annotation makes a lot of sense, the draw back is having to reach for the persistence data storage on every request that deals with data so a best use case for #Model bean is:
Basically every thing.
things like:
Events handling for JSF pages
Lazy loading of data
Validation and converting and other code execution
ETC.... yes every thing else
Those things are easily done best in request scoped beans, but then what are the roles of other beans?
In simplistic terms we can assume:
#ViewScoped to support data heavy pages where user edits data with many interactions and each interaction is a request but hitting the database for each one will be costly.
#SessionScoped for session data, authentication, credentials and configuration for the user.
#ApplicationScoped the state-full singleton of CDI.
.... each other scope has it's uses, but for a good web application #Model should be the default and the others has specific uses cases.
You should be able to also add the #Named annotation and it will be exposed as editProduct.
https://memorynotfound.com/cdi-managed-bean-example-with-named/
EDIT: See comment

using more than one managed bean in same jsf page

If I have page, lets say includes two different customers informations, how can I use two different managed beans (which is same java class) in the same page?
As a summary, in the same page I want to hold information of one customer in one bean, another in another bean.
I want to hold information of one customer in one bean, another in
another bean.
Another bean for same purpose is duplication, and If you are thinking it logical. Every page have its page's state (life). when you try #{bean.customer} it will return same value. Because its object is same.
I would suggest to improve your code use another class for the view, layer your application. like
//Base class
public class Customer {
private String id;
/*
*Other fields
*/
//getter Setters
}
#ManagedBean
#RequestScoped
public class PageBackingBean implements Serializable{
List<Customer> customer = new ArrayList<>(); //can Hold more than one customer
public PageBackingBean(){
Customer cus1 = DataBase.loadByCustomerId(id);
customer.add(cus1);
Customer cus2 = DataBase.loadByCustomerId(id);
customer.add(cus2);
}
}

Saving and using a cookie with CDI

I am trying to save a Cookie upon user request, and to later use that cookie to fill in a text field. I am using Java CDI and a login bean. I am new to all three. For online resources all I can find is
#Inject #CookieParam
private String username;
and
#Inject #CookieParam("username")
private Instance<String> usernameResolver;
...
String username = usernameResolver.get();
For the first one the error message says " Unsatisfied dependencies for type [String] with qualifiers [#Default]"
For the second one the only error I get says "Failed to start context"
How should I fix this problem?
Thanks
As the #CookieParam package name hints, this is specific to JAX-RS, Java EE's other framefork for RESTful web services. This would only work in a JAX-RS managed resource as annotated by #Path. This won't work in a JSF or CDI managed bean as annotated by #ManagedBean or #Named.
If you're using JSF's #ManagedBean to manage the bean, then it's available by EL-evaluating #{cookie.username} as #ManagedProperty.
#ManagedBean
public class Bean {
#ManagedProperty("#{cookie.username}")
private String username;
// ...
}
If you're using CDI's #Named to manage the bean, then you've resort to either a custom annotation, or grabbing it as Cookie from the current FacesContext. As the former is not trivial (but actually a nice idea for OmniFaces though), I'll show only the latter:
#Named
public class Bean {
private String username;
#PostConstruct
public void init() {
Cookie cookie = (Cookie) FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap().get("username");
if (cookie != null) {
username = cookie.getValue();
}
}
// ...
}
Then, in order to save it, the only way is using ExternalContext#addResponseCookie().
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie("username", username, properties);
Don't forget to take into account that a cookie value is very restrictive as to allowed characters. You might want to URL-encode and -decode it upon save and retrieval. JSF utility library OmniFaces offers helper methods which do that implicitly.
username = Faces.getRequestCookie("username");
Faces.addResponseCookie("username", username, -1);
Unrelated to the concrete problem, storing something sensitive like "user name" as a cookie is scary. Are you aware that cookies are manipulatable by the enduser? That the person who's visiting your webpage can easily edit a cookie value representing an "user name" to that of someone else?

Refresh managed session bean in JSF 2.0

After I commit some data into the database I want my session beans to automatically refresh themselves to reflect the recently committed data. How do I achieve this when using managed session beans in JSF 2.0?
Currently I have to restart the web server in order for the sessions to clear and load anew again.
2 ways:
Put them in the view scope instead. Storing view-specific data sessionwide is a waste. If you have a performance concern, you should concentrate on implementing connection pooling, DB-level pagination and/or caching in the persistence layer (JPA2 for example supports second level caching).
#ManagedBean
#ViewScoped
public class FooBean {
// ...
}
Add a public load() method so that it can be invoked from the action method (if necessary, from another bean).
#ManagedBean
#SessionScoped
public class FooBean {
private List<Foo> foos;
#EJB
private FooService fooService;
#PostConstruct
public void load() {
foos = fooService.list();
}
// ...
}
which can be invoked in action method inside the same bean (if you submit the form to the very same managed bean of course):
public void submit() {
fooService.save(foos);
load();
}
or from an action method in another bean (for the case that your managed bean design is a bit off from usual):
#ManagedProperty("#{fooBean}")
private FooBean fooBean;
public void submit() {
fooService.save(foos);
fooBean.load();
}
This of course only affects the current session. If you'd like to affect other sessions as well, you should really consider putting them in the view scope instead, as suggested in the 1st way.
See also:
How to choose the right bean scope?

Resources