What does it mean that an application is "form based"? I am reading the JSF specification and term turned up.
Form based application, means that for each form, there is a backend bean (java class) that handles the calls to the class.
For instance, you will have a form for login (login.xhtml) and you will present all getter and setters of the values that are needed in the form, in LoginBean.java
All operations (like retrieving data from db) only for this form, will be done in a postconstruct method.
So if login has username and password like this:
<h:inputtext name="name" value="#{loginBean.name}" />
<h:inputtext name="password" value="#{loginBean.password}" />
The LoginBean.java will look:
public class LoginBean{
String name;
String password;
public getName(){return name;}
public getPassword(){return password;}
public setName(String name){
this.name = name;
}
public setPassword(String password){
this.password = password;
}
#PostContruct
public void init(){
this.name = ... //get the name from db
}
}
Related
I want to put POJO bean key value pair to Ignite cache using REST API. I can put string key value pair to cache. but here i want to put a class as key value. How can i create REST url for this.
My config file look like this
<property name="cacheConfiguration">
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<!-- Set a cache name. -->
<property name="name" value="cacheName"/>
<!-- Set cache mode. -->
<property name="cacheMode" value="PARTITIONED"/>
<property name="indexedTypes">
<list>
<value>com.test.EntitlementKey</value>
<value>com.test.Entitlement</value>
</list>
</property>
</bean>
</property>
And Entitilement Class look like this
import org.apache.ignite.cache.query.annotations.QuerySqlField;
public class Entitlement {
#QuerySqlField
private String name;
#QuerySqlField
private String desc;
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getdesc() {
return desc;
}
public void setdesc(String desc) {
this.desc = desc;
}
And EntitlementKey class
public class EntitlementKey {
#QuerySqlField(index = true)
private String eid;
#QuerySqlField
private String id;
public String getEid() {
return eid;
}
public void setEid(String eid) {
this.eid = eid;
}
public String getid() {
return id;
}
public void setid(String id) {
this.id = id;
}
Currently, in master, you can find an implementation of ticket, which allows using internal java types as keys and values.
At this moment if you want to use your custom types, you need to use ConnectorMessageInterceptor interface. Once you implement and configure it, you will start receiving a callback for all keys and values passed back and forth. So you can encode your object as a String somehow and then convert it to a real object inside interceptor. And the opposite: before returning object from the cache you can convert it to some String form.
My project is a spring mvc project.In my project i have a domain Technology which has foreign key reference.When i validating on form submit it threw error....For view part(jsp),i using form:select for viewing department in technology.
How can i validate a foreign reference?????
i tried below code
domain
#Entity
#Table(name = "technology")
public class Technology {
private int id;
#NotEmpty
private String name;
#NotEmpty
private Department department;
private Date createdDate;
private boolean isDelete;
}
message.properties
NotEmpty.technology.department=Required!
Technology.jsp
<form:form method="post" action="add-technology"
commandName="technology" id="technologyForm">
<label>Technology Name</label>
<form:input path="name" /><form:errors path="name" class="error"></form:errors>
<br />
<label>Department</label>
<form:select path="department.id">
<form:option value="0" label="Select" />
<form:options items="${departments}" itemValue="id" itemLabel="name" />
</form:select><form:errors path="department" class="error"></form:errors>
<%-- <form:select path="department.id" items="${departments}" /> --%>
<input type="submit" class="btn btn-primary"/>
</form:form>
controller
#RequestMapping(value = "/add-technology")
public String addTechnology(
#ModelAttribute(value = "technology")#Valid Technology technology,
BindingResult result) {
if(result.hasErrors()){
return "/secure/admin/technology";
}
java.util.Date utilDate = new java.util.Date();
Date sqlDate = new Date(utilDate.getTime());
technology.setCreatedDate(sqlDate);
technologyService.saveTechnology(technology);
return "redirect:/technologies";
}
ERROR
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.validation.UnexpectedTypeException: No validator could be found for type: com.company.product.domain.Department
How can i resolve this problem???
Here you have to implement validator for Technology object
class TechnologyValidator extends Validator {
public boolean supports(Class<?> cls) {
return Technology .class.equals(cls);
}
public void validate(Object target, Errors errors) {
super.validate(target, errors);
Technology tecObj= (Technology ) target;
//here i am assuming Technology name is REQUIRED and
//NotEmpty.technology.name is in message.properties
ValidationUtils.rejectIfEmptyOrWhitespace(errors,"name",
"NotEmpty.technology.name");
Department dept = tecObj.getDepartment();
//as from from your are binding department ID
if (dept==null || dept.getId()==null || dept.getId()==0L ) {
errors.rejectValue("department.id", "NotEmpty.technology.department");
}
}
}
And create bean of this class in Spring-context
#Autowired
TechnologyValidator techValid;
And call this validator in your controller like
#RequestMapping(value = "/add-technology")
public String addTechnology(
#ModelAttribute(value = "technology") Technology technology,
BindingResult result) {
//call validator
techValid.validate(technology, result);
if(result.hasErrors()){
return "/secure/admin/technology";
}
java.util.Date utilDate = new java.util.Date();
Date sqlDate = new Date(utilDate.getTime());
technology.setCreatedDate(sqlDate);
technologyService.saveTechnology(technology);
return "redirect:/technologies";
}
Why is it mandatory to have both getters and setters for a field in RF Proxy interfaces? For some fields (like plain text password), you want setters only.
e.g.
#ProxyFor(value = User.class)
public interface UserProxy extends ValueProxy {
void setPassword(String password);
}
User class has both getters and setters.
public class User implements Serializable {
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
When I set the password on proxy, I get an IllegalArgumentException:
UserProxy user = userRequest.create(UserProxy.class);
user.setPassword("abc")
Above code results in following error:
java.lang.IllegalArgumentException: password
at com.google.web.bindery.autobean.shared.impl.AutoBeanCodexImpl.doCoderFor(AutoBeanCodexImpl.java:525)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.setProperty(AbstractAutoBean.java:276)
...
...
This error goes away if I add a 'getPassword()' method in UserProxy interface but that defeats the purpose. Any suggestion would be helpful.
AFAIK you can have a getter without a setter but not the other way round.
See here and this issue.
This question already has answers here:
Why JSF calls getters multiple times
(9 answers)
How and when should I load the model from database for JSF dataTable
(1 answer)
Method must have signature "String method() ...[etc]..." but has signature "void method()"
(1 answer)
Closed 3 years ago.
I'm really new to JSF, I've been learning it exactly 2 days now. Besides the initial confusion about the concepts, I have issues with eclipse too.
I'm using JSF 2.0 with obviously Eclipse and Tomcat 7.
Firstly, let me describe what I'd want to do: in scope of learning the JSF I want to have a User class, with name, surname, age and Id. Then, I'd like to list pre-defined users and add a submit form. Besides that, there's also a "user detail" option.
Here's my code:
User class:
package com.tutorial;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class User {
private String name;
private String surname;
private int age;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public User(String name, String surname, int age, int id) {
super();
this.name = name;
this.surname = surname;
this.age = age;
this.id = id;
}
public User(){}
}
Users "bean":
package com.tutorial;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
#ManagedBean
#SessionScoped
public class UsersBean {
private List<User> listOfUsers = new ArrayList<User>();
private String passedParameter;
public UsersBean()
{
listOfUsers.add(new User("Tywin", "Lannister", 60, 1));
listOfUsers.add(new User("Tyrion", "Lannister", 30, 2));
listOfUsers.add(new User("Jaime", "Lannister", 31, 3));
}
public List<User> getAll()
{
System.out.println("Called!");
return listOfUsers;
}
public User getDetails()
{
passedParameter = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("userID");
int id = Integer.parseInt(passedParameter);
User selected = null;
for (User u : listOfUsers)
{
if (u.getId() == id)
{
selected = u;
}
}
return selected;
}
public void addUser(User u)
{
u.setId(listOfUsers.size()+1);
listOfUsers.add(u);
}
}
users.xml (partial code):
<f:view>
<!-- http://stackoverflow.com/questions/8083469/method-must-have-signature-string-method-etc-but-has-signature-void -->
<h:dataTable value="#{usersBean.all}" var="u">
<h:column>
<f:facet name="header">
User ID
</f:facet>
#{u.id}
</h:column>
<h:column>
<f:facet name="header">
Name
</f:facet>
#{u.name}
</h:column>
<h:column>
<f:facet name="header">
Details
</f:facet>
<h:link outcome="usersDetails" value="get details">
<f:param name="userID" value="#{u.id}"></f:param>
</h:link>
</h:column>
</h:dataTable>
<h:form>
<h:outputText value="Name"></h:outputText>
<h:inputText value="#{user.name}"></h:inputText>
<h:outputText value="Surname"></h:outputText>
<h:inputText value="#{user.surname}"></h:inputText>
<h:outputText value="Age"></h:outputText>
<h:inputText value="#{user.age}"></h:inputText>
<h:commandButton action="#{usersBean.addUser(user)}" value="Add" type="submit"></h:commandButton>
</h:form>
</f:view>
And finally, usersDetails.xhtml (partial code as well):
<ui:define name="content">
<ui:param name="user" value="#{usersBean.details}" />
<h:outputText value="#{user.name}"></h:outputText>
<h:outputText value="#{user.surname}"></h:outputText>
<h:outputText value="#{user.id}"></h:outputText>
</ui:define>
OK, now the questions:
(1) in users.xhtml (see code above - usersBean.all in datatable), it appears as if this function gets called as many times as there are values in arraylist. The "System.out.println("Called!")" is written as many times as there are values in arraylist. Have I done something wrong? I don't believe it's suppose to be called for each object in arraylist.
(2) in users.xhtml, this part of the code
<h:commandButton action="#{usersBean.addUser(user)}" value="Add" type="submit"></h:commandButton>
is highlighted by eclipse and it reads: "Method must have signature "String method(),..."
Did I call the method the wrong way? Is there an alternative to send object to the UsersBean's addUser function? What would be correct way if Eclipse defines this as wrong?
Thank you very much for your time and answers!
1) In JSF, method (used for bulding view) can be called more than once. For proper testing you can create user list with 20 or more users and check again how many times getAll method will be called. I think it still be the same number (3 in your case).
2) Action method in JSF should return redirection outcome (with type String). It is reason why you have message about "signature String method". Change signature of addUser method from public void addUser(User u) to public String addUser(User u) and return outcome for navigation to new page or null for stay on the same page.
I have two entities and a backing bean in my application. Following, a simplified version of it:
Controller and Models:
class BackingBean {
private List<A> collectionOfA;
private A currentA;
private B currentB;
private String newDescription;
// accessors
public void prepareForUpdate(ActionEvent e) {
currentA = (A) e.getComponent().getAttributes().get("a");
currentB = (B) e.getComponent().getAttributes().get("b");
}
public void save(ActionEvent e) {
// method to save b
b.setName("changing the name");
b.setSomeNumber(2);
b.setDescription(newDescription);
entityManager.merge(b);
}
}
#Entity
class A {
private String name;
#OneToMany
private List<B> bs;
}
#Entity
class B {
private String name;
private String description;
private int someNumber;
}
View:
<div>
<!-- some popup with inputs for updating B -->
<h:inputText value="#{backingBean.currentB}" />
<h:commandLink actionListener="#{backingBean.save}" />
</div>
<ui:repeat value="#{backingBean.collectionOfA}" var="a">
<h:outputText>#{a.name}</h:outputText>
<ui:repeat value="#{a.bs}" var="b">
#{b.name}
#{b.description}
#{b.someNumber}
<h:commandLink actionListener="#{backingBean.prepareForUpdate}">
<f:attribute name="a" value="#{a}" />
<f:attribute name="b" value="#{b}" />
</h:commandLink>
</ui:repeat>
</ui:repeat>
Assuming that, when I click the commandLink for prepareForUpdate(), the popup shows, my problem is this: when I save the currentB entity, every field of the entity is updated in the view. However, an instant after, the field b.description is rendered again with the old value. When I check the database, the description is, in fact, updated, as it is if I refresh the page.
Any thoughts on why this is happening?