Can not get data table row selection in PrimeFaces, jsf? - eclipse

I'm working on a project. I need to get a list from MySql database and list it. I'm using JSF 2.1 Primeface 3.5 and Eclipse Juno. I run my code but it doesn't work. You can see my codes in below
//LOGIN CLASS
import parts
#ManagedBean
#SessionScoped
public class Login {
private String username, password;
private PreparedStatement ps, ps2;
private ResultSet rs, rs2;
private List<Application> applications = new ArrayList<Application>();;
private Application selectedApplication;
// GETTERS SETTERS
public String login() {
Connection object = new Connection();
try {
ps = nesne
.getCon()
.prepareStatement(
"select Username, Password from company where Username=? and Password=?");
ps.setString(1, getUsername());
ps.setString(2, getPassword());
rs = ps.executeQuery();
while (rs.next()) {
getList();
return "application";
}
} catch (Exception e) {
System.err.println(e);
}
return "confirm";
}
private List<Application> getList() {
Baglanti nesne = new Baglanti();
try {
ps2 = nesne
.getCon()
.prepareStatement(
"select ApplicationName from application where CompanyID=(select ID from company "
+ "where Username=? and Password=?)");
ps2.setString(1, getUsername());
ps2.setString(2, getPassword());
rs2 = ps2.executeQuery();
while (rs2.next()) {
Application obj = new Application();
obj.setApplicationName(rs2.getString("ApplicationName"));
applications.add(obj);
}
} catch (Exception e) {
System.err.println(e);
}
return applications;
}
APPLICATION CLASS
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean
#SessionScoped
public class Application {
private int ID;
private int CompanyID;
private String Type;
private Date Date;
private String ApplicationName;
private int CurrentMessageCount;
private int MaxMessage;
private String isPro;
//GETTERS SETTERS
application.xhtml
<!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:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Login Confirmed</title>
</h:head>
<h:body>
<h1 class="ui-widget-header ui-corner-all" align="center">Application
List</h1>
<br />
<h:form id="form">
<p:growl id="msgs" showDetail="true" />
<p:dataTable id="applications" var="application"
value="#{login.applications}">
<p:column headerText="Application" style="width:24%">
<h:outputText value="#{login.applications}" />
</p:column>
<p:column style="width:4%">
<p:commandButton id="selectButton" icon="ui-icon-search"
title="View">
<f:setPropertyActionListener value="#{application}"
target="#{login.selectedApplication}" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
I can login properly after that ı saw this page.
Now where is my mistake?

Your var="application" is conflicting with the implicit EL object referring the application context (the ServletContext). You can find here a list of all implicit EL objects. Memorize them. You should never declare an EL variable on exactly those names.
Give it a different name. E.g. var="app", var="_application", etc.

In data table var property mean that every item from database will be accesible as this "var" value. i.e:
You have class Foo:
class Foo{
int number;
String text;
//Setters and getters
}
And another class which handle list of Foo objects (your model as CDI Bean):
#Named
class Boo{
List<Foo> list = new ArrayList<>();
//Getter and setters
}
So to list it all in jsf page you should use it like this:
<p:dataTable id="list" var="listobject" value="#{boo.list}">
<p:column headerText="Number" style="width:24%">
<h:outputText value="#{listobject.number}" />
</p:column>
<p:column headerText="Text" style="width:24%">
<h:outputText value="#{listobject.String}" />
</p:column>
</p:dataTable>
So summary "var" value is accessor string to boo object.
Look also:
PrimeFaces datatable demo and here
Mkyong datatable tutorial

Related

How to get query parameters in JSTL instead of scriplets

I have been trying to display a table in JSP for which I am using this while loop code as given below, the problem is that it is difficult for me to convert my scriptlets into JSTL especially the rs.getInt("id") and I am using JSTL so that I can encode the URL together.
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/login";
String username = "root";
String password = "your-password";
String query = "select * from employeesloginaccount";
Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
%>
<tr>
<td><%=rs.getInt("id")%></td>
<td><%=rs.getString("first_name")%></td>
<td><%=rs.getString("last_name")%></td>
<td>
<c:url value ="${pageContext.request.contextPath}/downloadFileServlet" var = "myURL">
<c:param name = "id" value = "<%=rs.getInt(id)%>"/>
</c:url>
<form method="get"
action="<c:import url = "${myURL}"/>">
<input style="text-align: center" type="submit" value="Save">
</form>
</td>
</tr>
<%
}
I think it might be worth considering this answer from BalusC on the question, "How to avoid Java code in JSP files?"
The use of scriptlets (those <% %> things) in JSP is indeed
highly discouraged since the birth of taglibs (like JSTL) and
EL (Expression Language, those ${} things) over a decade ago.
The major disadvantages of scriptlets are:
Reusability: you can't reuse scriptlets.
Replaceability: you can't make scriptlets abstract.
OO-ability: you can't make use of inheritance/composition.
Debuggability: if scriptlet throws an exception halfway, all you get is a blank page.
Testability: scriptlets are not unit-testable.
Maintainability: per saldo more time is needed to maintain mingled/cluttered/duplicated code logic.
Your specific problem here is Maintainability.
What you should be doing is seperating the logic of your application so that you can have a high level of reusability/testability/debuggability/maintainability etc.. Let's start by creating a java class for your database connection, maybe something like this:
public class DBConnection {
private static String url = null;
private static Connection conn = null;
public static Connection getConnection(){
try{
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://localhost:3306/login";
conn = DriverManager.getConnection(url,"root","your-password");
} catch (Exception e) {
System.out.println(e);
}
return conn;
}
}
Then you can use this class whenever you want to connect to your database and do something from other classes, in the examples below we will create an object to handle your employee data and then use that to get information from your database:
public class EmployeeObject {
int id;
String firstname;
String lastname;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
Now that we have this object class, let's say you have another class called Employees, and in this class you have a method which gets employee info from the employeesloginaccount table:
public class Employees {
public List<EmployeeObject> getEmployeeInfo(){
//this class will return a list of EmployeeObjects from the database.
ArrayList<EmployeeObject> employees = new ArrayList<EmployeeObject>();
//get connection from our DBConneciton class we created earlier
try(Connection conn= DBConnection.getConnection()){
PreparedStatement pst = conn.prepareStatement("select * from employeesloginaccount;");
ResultSet rs = pst.executeQuery();
while (rs.next()) {
//for each result in database, create an EmployeeObject
EmployeeObject employee = new EmployeeObject();
int id = rs.getInt("id");
employee.setId(id);
String fname = rs.getString("first_name");
employee.setFirstname(fname);
String lname = rs.getString("last_name");
employee.setLastname(lname);
employees.add(employee); // add each EmployeeObject to the arrayList of EmployeeObject's
}
} catch (SQLException e) {
e.printStackTrace();
}
return employees; //return all the results
}
}
Then you create a Servlet which will get this information, let's make it easy and put our code in the doGet method of the servlet so that whenever we visit the URL for this Servlet we will call this code (in this case i called my Servlet Test, with url mapping /Test:
#WebServlet("/Test")
public class Test extends HttpServlet {
private static final long serialVersionUID = 1L;
public Test() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Employees e = new Employees(); //instantiate the Employees class
List<EmployeeObject> employees = e.getEmployeeInfo(); //get employee info from database
request.setAttribute("employees", employees); //set this list of employees to the request so we can access it in our jsp
RequestDispatcher rd = request.getRequestDispatcher("example.jsp"); //change to whatever your jsp is that you want to view the information
rd.forward(request, response);
}
}
And finally in our jsp page where we can view this information:
<!DOCTYPE HTML>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<html>
<head>
<title>Example Page</title>
</head>
<body>
<table style="width:100%;">
<thead>
<tr>
<td>id</td>
<td>Firstname</td>
<td>Lastname</td>
</tr>
</thead>
<tbody>
<!-- for each item in our employees list create a variable called "employee" -->
<c:forEach items="${employees}" var="employee">
<tr>
<td>${employee.id}</td>
<td>${employee.firstname}</td>
<td>${employee.lastname}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
Let me know if that helps you or if you have any questions. :)

org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.faces.flow.FlowScoped

I´m trying to develop a simple example of new functionality of JSF 2.2, #FlowScope, I develop it with eclipse luna, glassfish 4.0, I guess the code is right cause I caught it on the web, probably the error is with the configuration of the project. Could anyone give me an Idea of what could be? Pleas ask me further information if it´s hard to understand with these few information but actually I don´t know what more I can write to help and this is my first question on stackoverflow.
public class NestedFlowBuilder implements Serializable {
private static final long serialVersionUID = 1L;
#Produces
#FlowDefinition
public Flow defineCallingFlow
(#FlowBuilderParameter FlowBuilder flowBuilder) {
String flowId = "secondJavaFlow";
flowBuilder.id("", flowId);
flowBuilder.viewNode(flowId, "/java-calling-flow/start-page.xhtml")
.markAsStartNode();
flowBuilder.viewNode("results",
"/java-calling-flow/results-page.xhtml");
flowBuilder.returnNode("return").fromOutcome("/return-page-for-java-calling-flow");
flowBuilder.returnNode("home").fromOutcome("/index");
flowBuilder.flowCallNode("go-to-nested")
.flowReference("", "thirdJavaFlow")
.outboundParameter("paramForNestedFlow",
"#{javaCallingFlowBean.param1}");
return(flowBuilder.getFlow());
}
#Produces
#FlowDefinition
public Flow defineNestedFlow
(#FlowBuilderParameter FlowBuilder flowBuilder) {
String flowId = "thirdJavaFlow";
flowBuilder.id("", flowId);
flowBuilder.viewNode(flowId,
"/java-nested-flow/start-page.xhtml")
.markAsStartNode();
flowBuilder.viewNode("results",
"/java-nested-flow/results-page.xhtml");
flowBuilder.returnNode("return-to-previous-start")
.fromOutcome("secondJavaFlow");
flowBuilder.returnNode("return-to-previous-results")
.fromOutcome("results");
flowBuilder.inboundParameter("paramForNestedFlow",
"#{javaNestedFlowBean.param3}");
return(flowBuilder.getFlow());
}
package coreservlets;
import java.io.Serializable;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.flow.FlowScoped;
import javax.inject.Named;
#Named
#FlowScoped("thirdJavaFlow")
public class JavaNestedFlowBean implements Serializable {
private static final long serialVersionUID = 1L;
private String param3, param4;
public String doFlow() {
if (param3.equalsIgnoreCase(param4)) {
FacesContext context = FacesContext.getCurrentInstance();
FacesMessage fMessage =
new FacesMessage("Params must be distinct");
fMessage.setSeverity(FacesMessage.SEVERITY_ERROR);
context.addMessage(null, fMessage);
return(null);
} else {
return("results");
}
}
public String getParam3() {
return param3;
}
public void setParam3(String param3) {
this.param3 = param3;
}
public String getParam4() {
return param4;
}
public void setParam4(String param4) {
this.param4 = param4;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Java Calling Flow Start PAge</title>
</head>
<body>
<h:form>
<h:messages globalOnly="true" styleClass="error"/>
<h:panelGrid columns="3" styleClass="formTable">
Param 1:
<h:inputText value="#{javaCallingFlowBean.param1}" id="param1"
required="true"
requiredMessage="Param 1 is required"/>
<h:message for="param1" styleClass="error"/>
Param 2:
<h:inputText value="#{javaCallingFlowBean.param2}" id="param2"
required="true"
requiredMessage="Param 2 is required"/>
<h:message for="param2" styleClass="error"/>
<f:facet name="footer">
<h:commandButton value="Show Results"
action="#{javaCallingFlowBean.doFlow}"/><br/>
</f:facet>
</h:panelGrid>
</h:form>
</body>
</html>
I get this error:
javax.el.ELException: /java-calling-flow/start-page.xhtml #17,40 value="#{javaCallingFlowBean.param1}": org.jboss.weld.context.ContextNotActiveException: WELD-001303 No active contexts for scope type javax.faces.flow.FlowScoped
http://courses.coreservlets.com/Course-Materials/pdf/jsf/jsf2/JSF-2.2-Faces-Flow-2.pdf from pag 33

Spring form submit validation for foreign key

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";
}

Getter gets called as many times as there are values in ArrayList for h:dataTable and Eclipse says "Method must have signature "String method ..." [duplicate]

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.

JSF view displaying outdated value

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?