Underscore in OGNL expression not working - struts2

I am surprised that underscore ("_") is not working in OGNL.
In below sample all properties are processed on OGNL/ValueStack, except property name appfull_name due to underscore.
Code sample below
POJO SampleSdmAppsTabObj.java
import java.io.*;
import javax.persistence.*;
#SuppressWarnings("serial")
#Entity
#Table(name="SDM_APPS")
#IdClass(SdmAppsPkeyObj.class)
public class SdmAppsTabObj implements Serializable
{
//#Id
String orgid;
//#Id
String asnid;
String appfull_name;
String description;
public SdmAppsTabObj(){}
public SdmAppsTabObj
(
String inOrgId,
String inAsnId,
String inAppFullName,
String inDescription
)
{
this.OrgId = inOrgId;
this.AsnId = inAsnId;
this.AppFullName = inAppFullName;
this.Description = inDescription;
}
*/
public String getOrgid() { return orgid; }
public String getAsnid() { return asnid; }
public String getAppfullname() { return appfull_name; }
public String getDescription() { return description; }
public void setOrgid(String inOrgId ) { this.orgid = inOrgId; }
public void setAsnid(String inAsnId ) { this.asnid = inAsnId; }
public void setAppfullname(String inAppFullName ) { this.appfull_name = inAppFullName; }
public void setDescription(String inDescription ) { this.description = inDescription; }
//Override equals() and hashCode()
#Override
public boolean equals(Object inObject)
{
if (this == inObject) { return true; }
if (inObject == null) { return false; }
if (!(inObject instanceof SdmAppsTabObj)) { return false; }
SdmAppsTabObj other = (SdmAppsTabObj) inObject;
if( orgid == null )
if( other.orgid != null ) { return false; }
else if( !orgid.equals(other.orgid) ) { return false; }
if( asnid == null )
if( other.asnid != null ) { return false; }
else if( !asnid.equals(other.asnid) ) { return false; }
return true;
}
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((orgid == null) ? 0 : orgid.hashCode());
result = prime * result + ((asnid == null) ? 0 : asnid.hashCode());
return result;
}
}
SdmAppsAction.java
import SdmAppsTabObj;
import SdmAppsPkeyObj;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class SdmAppsAction extends ActionSupport implements ModelDriven<SdmAppsTabObj>{
private static final long serialVersionUID = 1L;
SdmAppsTabObj lSdmAppsTabObj = new SdmAppsTabObj();
public String execute() throws Exception {
return SUCCESS;
}
public SdmAppsTabObj getModel() {
return lSdmAppsTabObj;
}
}
sdm_apps_add.jsp
.....
<h2>Add Apps</h2>
<s:form action="sdmAppsAction" >
<s:textfield name="orgid" label="Org" />
<s:textfield name="asnid" label="Asn" value=""/>
<s:textfield name="appfull_name" label="App name" value=""/>
<s:textfield name="description" label="Desc" value=""/>
<s:submit />
</s:form>
.....
sdm_apps_success.jsp
.....
<h2>Apps Details</h2>
Org : <s:property value="orgid" /><br>
Asn : <s:property value="asnid" /><br>
App name : <s:property value="appfull_name" /><br>
Desc : <s:property value="description" /><br>
.....

The getter of your appfull_name is
public String getAppfullname();
instead of:
public String getAppfull_name();
Also, the name of setter is not correct.

Related

struts2 jquery grid data not loaded when implements model driven

My web application not loading data when I implements model driven in action class. It works fine when remove modeldriven.
action class :
package action;
import action.UserBean;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import service.OrganisationBo;
import model.AtDivision;
import model.AtOrganisation;
public class OraganisationAction extends ActionSupport implements ModelDriven<UserBean> {
private String uname;
private String passwd;
private String sidx;
// Search Field
private String searchField;
// The Search String
private String searchString;
// he Search Operation ['eq','ne','lt','le','gt','ge','bw','bn','in','ni','ew','en','cn','nc']
private String searchOper;
// Your Total Pages
private Integer total = 0;
//Your result List
private List<UserBean> gridModel;
//get how many rows we want to have into the grid - rowNum attribute in the grid
private Integer rows = 0;
//Get the requested page. By default grid sets this to 1.
private Integer page = 0;
// sorting order - asc or desc
private String sord;
private boolean loadonce = false;
// All Record
private Integer records = 0;
private String includepage;
private List<UserBean> myList;
private String oper;
private String id;
private String contact;
private String country;
UserBean ubs = new UserBean();
private AtOrganisation org = new AtOrganisation();
private AtDivision div = new AtDivision();
private List<AtOrganisation> orglist = new ArrayList<AtOrganisation>();
OrganisationBo orgBo;
private String aoId;
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getSidx() {
return sidx;
}
public void setSidx(String sidx) {
this.sidx = sidx;
}
public String getSearchField() {
return searchField;
}
public void setSearchField(String searchField) {
this.searchField = searchField;
}
public String getSearchString() {
return searchString;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
public String getSearchOper() {
return searchOper;
}
public void setSearchOper(String searchOper) {
this.searchOper = searchOper;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<UserBean> getGridModel() {
return gridModel;
}
public void setGridModel(List<UserBean> gridModel) {
this.gridModel = gridModel;
}
public Integer getRows() {
return rows;
}
public void setRows(Integer rows) {
this.rows = rows;
}
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public String getSord() {
return sord;
}
public void setSord(String sord) {
this.sord = sord;
}
public boolean isLoadonce() {
return loadonce;
}
public void setLoadonce(boolean loadonce) {
this.loadonce = loadonce;
}
public Integer getRecords() {
return records;
}
public void setRecords(Integer records) {
this.records = records;
}
public String getIncludepage() {
return includepage;
}
public void setIncludepage(String includepage) {
this.includepage = includepage;
}
public List<UserBean> getMyList() {
return myList;
}
public void setMyList(List<UserBean> myList) {
this.myList = myList;
}
public String getOper() {
return oper;
}
public void setOper(String oper) {
this.oper = oper;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public List<AtOrganisation> getOrglist() {
return orglist;
}
public void setOrglist(List<AtOrganisation> orglist) {
this.orglist = orglist;
}
public String getAoId() {
return aoId;
}
public void setAoId(String aoId) {
this.aoId = aoId;
}
public void setOrgBo(OrganisationBo orgBo) {
this.orgBo = orgBo;
}
public AtDivision getDiv() {
return div;
}
public void setDiv(AtDivision div) {
this.div = div;
}
public AtOrganisation getOrg() {
return org;
}
public void setOrg(AtOrganisation org) {
this.org = org;
}
public String execute() throws Exception {
myList = DAO.buildList();
setRecords(DAO.count());
int to = (getRows() * getPage());
int from = to - getRows();
if (to > getRecords()) {
to = getRecords();
}
if (loadonce) {
setGridModel(myList);
} else {
if (searchString != null && searchOper != null && !searchString.equals("") && !searchOper.equals("")) {
System.out.println("Searching within Database");
if (searchOper.equalsIgnoreCase("cn")) {
// setGridModel(DAO.findbyName(searchString));
}
} else {
System.out.println("Not Searching Anywhere");
//setGridModel(DAO.find(from, to));
System.out.println("dili 4444");
setGridModel(myList);
}
}
total = (int) Math.ceil((double) getRecords() / (double) getRows());
System.out.println("tot " + total);
System.out.println(gridModel.size());
return SUCCESS;
}
#Override
public UserBean getModel() {
return ubs;
}
}
Struts.xml :
<package name="default" extends="struts-default,json-default">
<action name="gridaction" class="action.OraganisationAction" >
<result name="success" type="json"/>
</action>
</package>
</struts>
index.jsp :
<%--
Document : index
Created on : 15 Nov, 2011, 11:45:45 PM
Author : XCoder
--%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib prefix="s" uri="/struts-tags" %>
<%#taglib prefix="sj" uri="/struts-jquery-tags" %>
<%#taglib prefix="sjg" uri="/struts-jquery-grid-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<sj:head jquerytheme="start" jqueryui="true"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<s:url id="remoteurl" action="gridaction"/>
<sjg:grid
id="sjgrid"
caption="Grid Model"
dataType="json"
href="%{remoteurl}"
pager="true"
rowList="10,20,100"
rowNum="5"
navigator="true"
width="999"
navigatorSearchOptions="{sopt:['eq','ne','lt','gt']}"
navigatorAddOptions="{height:280,reloadAfterSubmit:true}"
navigatorEditOptions="{height:280,reloadAfterSubmit:false}"
navigatorEdit="false"
navigatorView="false"
navigatorDelete="true"
navigatorDeleteOptions="{height:280,reloadAfterSubmit:true}"
gridModel="gridModel"
editurl="%{editurl}"
editinline="true"
onSelectRowTopics="rowselect"
>
<sjg:gridColumn name="iduser" formatter="integer" title="iduser" key="true" hidden="true"/>
<sjg:gridColumn name="uname" title="Username" editable="true" align="center"
editrules="{required:true}"
/>
<sjg:gridColumn name="passwd" title="Password" editable="true" align="center"
editrules="{required:true}"
/>
<sjg:gridColumn name="country" title="Country" editable="true" align="center"
edittype="select"
editoptions="{dataUrl:'%{selecturl}'}"
/>
<sjg:gridColumn name="contact" title="Contact No" editable="true" align="center"
editrules="{required:true,number:true,integer:true}"
/>
</sjg:grid>
</body>
</html>
cant we implement model driven with jqgrid or my code is wrong?
EDIT:
Just figure out that modeldriven work fine with old lib set
struts2-convention-plugin-2.1.8,
struts2-core-2.1.8.1,
struts2-jquery-grid-plugin-2.5.0,
struts2-jquery-plugin-2.5.0,
struts2-json-plugin-2.1.8,
xwork-core-2.1.6.
But when I update project into new version of struts grid is not fill with data. New lib set is as follows :
struts2-convention-plugin-2.3.16,
struts2-core-2.3.16,
struts2-jquery-grid-plugin-3.7.1,
struts2-jquery-plugin-3.7.0 ,
struts2-json-plugin-2.3.16.3
xwork-core-2.3.16.
Anyone knows what happening here?

p:selectOneMenu not calling setter on form submit

I'm kinda new to JSF and primefaces and I'm running into a very annoying problem.
I'm making a very basic application to learn a bit more about primefaces. I have a simple form that has several textual input fields, two datepickers and one dropdown (selectOneMenu).
Everything works all values are put in the backing bean when I submit the form, except for the value from the dropdown menu. The setter for that item is never called. And the application does not call the public void saveNewActivity(ActionEvent evt) method on the controller as defined on the commandbutton. When I however remove or comment out the dropdown menu in html it does call that method (but the field for the dropdown menu is obviously null).
I've been trying things for nearly two days, and still can't get this to work properly.
I have the following code (snippets):
My html/jsf code
<div id="newActivitycontent">
<h:form id="newActivityForm">
<h:messages id="messages"/>
<table>
<tr>
<td>Gebruiker:</td>
<td><p:selectOneMenu value="#{plannedActivityController.newActivity.organiser}}"
converter="#{userConverter}">
<f:selectItem itemLabel="Kies een gebruiker" itemValue=""/>
<f:selectItems value="#{plannedActivityController.users}" var="user"
itemLabel="#{user.firstname} #{user.lastname}" itemValue="#{user}"/>
</p:selectOneMenu></td>
</tr>
<tr>
<td>Titel:</td>
<td><p:inputText value="#{plannedActivityController.newActivity.name}"/></td>
</tr>
<tr>
<td>Beschrijving:</td>
<td><p:inputText value="#{plannedActivityController.newActivity.desctription}"/></td>
</tr>
<tr>
<td>Startdatum:</td>
<td><p:calendar value="#{plannedActivityController.newActivity.startDateDate}"/></td>
</tr>
<tr>
<td>Einddatum:</td>
<td><p:calendar value="#{plannedActivityController.newActivity.endDateDate}"/></td>
</tr>
</table>
<p:commandButton id="btnSaveNewActivity" value="Opslaan"
actionListener="#{plannedActivityController.saveNewActivity}"
update=":overviewForm:activityTable messages"/>
<p:commandButton id="btnCancelNewActivity" value="Annuleren"
actionListener="#{plannedActivityController.cancelNewActivity}" onclick="hideAddNewUI()"
update=":overviewForm:activityTable" type="reset" immediate="true"/>
</h:form>
</div>
The controller that is used by that code:
#Named
#SessionScoped
public class PlannedActivityController implements Serializable {
#Inject
private ApplicationModel appModel;
#Inject
private SessionModel sessionModel;
#Inject
private ActivityMapper activityMapper;
#Inject
private UserMapper userMapper;
private ActivityBean newActivity;
private ActivityBean selectedActivity;
private List<ActivityBean> activities;
private List<UserBean> users;
public PlannedActivityController() {
}
#PostConstruct
public void onCreated() {
convertActivities();
onNewActivity();
users = userMapper.mapToValueObjects(appModel.getUsers());
}
public void convertActivities() {
List<PlannedActivity> originalActivities = appModel.getActivities();
this.activities = activityMapper.mapToValueObjects(originalActivities);
}
public void onRowEditComplete(RowEditEvent event) {
System.out.println("row edited : " + event.getObject());
//TODO: save changes back to db!
}
public void onRowSelectionMade(SelectEvent event) {
System.out.println("row selected : " + event.getObject());
selectedActivity = (ActivityBean)event.getObject();
}
//Activity crud methods
public void onNewActivity() {
newActivity = new ActivityBean();
newActivity.setId(new Date().getTime());
}
public void saveNewActivity(ActionEvent evt) {
PlannedActivity newAct = activityMapper.mapToEntity(newActivity);
if(newAct != null) {
appModel.getActivities().add(newAct);
}
convertActivities();
}
public void cancelNewActivity() {
//TODO: cleanup.
}
public void deleteSelectedActivity() {
if(selectedActivity != null) {
activities.remove(selectedActivity);
appModel.setActivities(activityMapper.mapToEntities(activities));
convertActivities();
} else {
//TODO: show error or information dialog, that delete cannot be done when nothing has been selected!
}
}
//Getters & Setters
public ApplicationModel getAppModel() {
return appModel;
}
public void setAppModel(ApplicationModel appModel) {
this.appModel = appModel;
}
public SessionModel getSessionModel() {
return sessionModel;
}
public void setSessionModel(SessionModel sessionModel) {
this.sessionModel = sessionModel;
}
public ActivityMapper getActivityMapper() {
return activityMapper;
}
public void setActivityMapper(ActivityMapper activityMapper) {
this.activityMapper = activityMapper;
}
public UserMapper getUserMapper() {
return userMapper;
}
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
public ActivityBean getNewActivity() {
return newActivity;
}
public void setNewActivity(ActivityBean newActivity) {
this.newActivity = newActivity;
}
public ActivityBean getSelectedActivity() {
return selectedActivity;
}
public void setSelectedActivity(ActivityBean selectedActivity) {
this.selectedActivity = selectedActivity;
}
public List<ActivityBean> getActivities() {
return activities;
}
public void setActivities(List<ActivityBean> activities) {
this.activities = activities;
}
public List<UserBean> getUsers() {
return users;
}
public void setUsers(List<UserBean> users) {
this.users = users;
}
}
My activitybean:
public class ActivityBean implements Serializable {
private Long id = 0L;
private String name;
private String desctription;
private UserBean organiser;
private Calendar startDate;
private Calendar endDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesctription() {
return desctription;
}
public void setDesctription(String desctription) {
this.desctription = desctription;
}
public UserBean getOrganiser() {
return organiser;
}
public void setOrganiser(UserBean organiser) {
this.organiser = organiser;
}
public Calendar getStartDate() {
return startDate;
}
public void setStartDate(Calendar startDate) {
this.startDate = startDate;
}
public Date getStartDateDate() {
if(this.startDate == null) {
return null;
}
return this.endDate.getTime();
}
public void setStartDateDate(Date startDate) {
if(this.startDate == null) {
this.startDate = new GregorianCalendar();
}
this.startDate.setTime(startDate);
}
public String getStartDateString() {
if(this.startDate == null) {
return null;
}
return startDate.get(Calendar.DAY_OF_MONTH) + "/" + startDate.get(Calendar.MONTH) + "/" + startDate.get(Calendar.YEAR) + "";
}
public Calendar getEndDate() {
return endDate;
}
public void setEndDate(Calendar endDate) {
this.endDate = endDate;
}
public Date getEndDateDate() {
if(this.endDate == null) {
return null;
}
return endDate.getTime();
}
public void setEndDateDate(Date endDate) {
if(this.endDate == null) {
this.endDate = new GregorianCalendar();
}
this.endDate.setTime(endDate);
}
public String getEndDateString() {
if(this.endDate == null) {
return null;
}
return endDate.get(Calendar.DAY_OF_MONTH) + "/" + endDate.get(Calendar.MONTH) + "/" + endDate.get(Calendar.YEAR) + "";
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ActivityBean that = (ActivityBean) o;
if (id != null ? !id.equals(that.id) : that.id != null) return false;
return true;
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
My userbean:
public class UserBean {
private Long id;
private String username;
private String firstname;
private String lastname;
private String email;
private String phone;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
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;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
UserBean userBean = (UserBean) o;
if (id != null ? !id.equals(userBean.id) : userBean.id != null) return false;
return true;
}
#Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
}
And the converter used by the selectOneMenu:
#Named
public class userConverter implements Converter{
#Inject
private PlannedActivityController activityController;
#Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String s) {
for (UserBean user : activityController.getUsers()) {
if(user.getId().toString().equals(s)) {
return user;
}
}
return null;
}
#Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object o) {
if(o instanceof UserBean) {
UserBean user = (UserBean)o;
return user.getId().toString();
}
return "";
}
}
The problem is here. Look closer. This is invalid EL syntax.
value="#{plannedActivityController.newActivity.organiser}}"
This should however have thrown a PropertyNotWritableException on submit something like this:
javax.el.PropertyNotWritableException: /test.xhtml #25,39 value="#{plannedActivityController.newActivity.organiser}}": Illegal Syntax for Set Operation
at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
at javax.faces.component.UIInput.updateModel(UIInput.java:822)
at javax.faces.component.UIInput.processUpdates(UIInput.java:739)
at javax.faces.component.UIForm.processUpdates(UIForm.java:281)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1244)
at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1244)
at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1223)
at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
This exception should have been logged to the server log. By default this will however not end up in an error page for the enduser because JSF/PrimeFaces have by default no form of feedback to enduser in case of exceptions which are thrown during ajax requests. You should however be able to see it in actual ajax response body in webbrowser's builtin HTTP traffic monitor.
The JSF utility library OmniFaces offers a FullAjaxExceptionHandler for the very problem of total absence of feedback on exceptions during ajax requests. You may find it useful. When I tried to recreate your problem, I was been presented a clear error page so that I don't need to dig in server log or HTTP traffic monitor for clues.

FacesConverter forClass doesn't work with Composite Component

I've got a simple composite component which has to render a inputText. When a put the value and press commandButton the follow exception is throw:
java.lang.IllegalArgumentException: Cannot convert 1 of type class java.lang.String to class sample.entity.Product
When i use h:inputText instead d:myInputText it's work fine.
Is possible use a FacesConverter and attribute forClass for composite component? I do not like to use converter attribute or converterId of tag f:converter.
Anybody help me?
Page code:
<h:form>
<h:messages />
Product Id: <h:myInputText value="#{productController.product}"/>
<h:commandButton value="Submit" action="#{productController.someAction()}" />
Product Description: <h:outputText value="#{productController.product.description}"/>
</h:form>
Composite code:
<composite:interface>
<composite:attribute name="value"/>
<composite:editableValueHolder name="value" targets="#{cc.clientId}:value"/>
</composite:interface>
<composite:implementation>
<div id="#{cc.clientId}">
<h:inputText id="value" value="#{cc.attrs.value}"/>
<h:message for="#{cc.clientId}:value" />
</div>
</composite:implementation>
ManagedBean code:
#Named("productController")
#RequestScoped
public class ProductController {
private Product product;
public Product getProduct() {
if (product == null) {
product = new Product();
}
return product;
}
public void setProduct(Product product) {
this.product = product;
}
public void someAction() {
System.out.println("Product " + product);
}
}
Converter code:
#FacesConverter(forClass = Product.class)
public class ProductConverter implements Converter {
#Override
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
System.out.println("[DEBUG] getAsObject: " + value);
if (value == null || "".equals(value)) {
return null;
}
//TODO: some logic to get entity from database.
return new Product(new Long(value));
}
#Override
public String getAsString(FacesContext fc, UIComponent uic, Object o) {
System.out.println("[DEBUG] getAsString: " + o);
if (o == null) {
return null;
}
return String.valueOf(((Product) o).getId());
}
}
Entity code:
public class Product {
private Long id;
private String description;
public Product() {
}
public Product(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Override
public int hashCode() {
int hash = 7;
hash = 29 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Product other = (Product) obj;
if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
return false;
}
return true;
}
#Override
public String toString() {
return "Product{" + "id=" + id + '}';
}
}
I use Mojarra 2.1.14, Glassfish 3.1 and CDI.
Best regards.
I was able to reproduce it in Mojarra 2.1.14. This is a bug in Mojarra. It works fine in MyFaces 2.1.9. I've reported it to Mojarra guys as issue 2568. In the meanwhile, there's not really another option than explicitly specifying a <f:converter for> in the client or moving to MyFaces (which has its own set of specific quirks/issues as well though).

Struts 2 jquery grid component with jquery grid column type list which takes list of objects

The problem I have is that I am trying to have a multi select data grid column which will have a List objects (productsEntitled).
I've got the products to display properly by providing a buildSelect custom function to populate my Edit Dialog Box when a user click edit on a record.
When I have the column with the multi select <sjg:gridColumn name="productsEntitledListModel on my grid, the save functionality does not work and does not save. I don't see any errors on the browser console nor on the java console.
Any help will be appreciated as I am unable to find out what the problem is, I de-compiled the entire show case jar and nothing that helps with this issue.
My model look like this:
#Entity
#Table ( name = "USERS")
public class User {
private Long id;
private String name;
private String username;
private String password;
private String sourceIp;
private Device device;
private List<Product> productsEntitled;
This is my grid on a jsp page:
<s:url id="remoteurl" action="loadUsersJson"/>
<s:url id="editurl" action="editGridUserEntry"/>
<s:url id="selectproductsurl" action="loadProductsJson"/>
<sjg:grid gridModel="users"
id="gridUsers"
dataType="json"
width="1150"
href="%{remoteurl}"
draggable="true"
pager="true"
resizable="true"
navigatorAddOptions="{height:525, width:425, readAfterSubmit:true, draggable:true, resizable:true}"
navigatorEditOptions="{height:525, width:425, reloadAfterSubmit:true, draggable:true, resizable:true}"
navigatorDeleteOptions="{height:200, width:200, reloadAfterSubmit:true, draggable:true, resizable:true}"
editurl="%{editurl}"
navigator="true"
navigatorEdit="true"
navigatorAdd="true"
navigatorView="true"
navigatorDelete="true"
rowList="10,15,20"
rowNum="15"
multiselect="false"
onSelectRowTopics="rowselect">
<sjg:gridColumn name="id" editable="true" index="id" hidden="true" key="true" title="ID"/>
<sjg:gridColumn name="name" index="name" editable="true" edittype="text" title="NAME"/>
<sjg:gridColumn name="sourceIp" index="sourceIp" editable="true" edittype="text" title="SOURCE IP"/>
<sjg:gridColumn name="username" index="username" editable="true" edittype="text" title="USERNAME"/>
<sjg:gridColumn name="password" index="password" editable="true" edittype="password" title="PASSWORD"/>
<sjg:gridColumn name="role" index="role" editable="true" edittype="select" editoptions="{value:'Admin:Admin;User:User;'}" title="ROLE"/>
<sjg:gridColumn name="deviceId" jsonmap="device.id" key="true" hidden="true" editable="text" title="DEVICE ID"/>
<sjg:gridColumn name="deviceIp" jsonmap="device.ip" editable="true" edittype="text" title="DEVICE IP"/>
<sjg:gridColumn name="productsEntitledListModel"
width="300"
editable="true"
edittype="select"
editoptions="{dataUrl: '%{selectproductsurl}', multiple:true, buildSelect:customBuildSelect}"
title="PRODUCTS"/>
</sjg:grid>
These are my action classes:
Show the grid:
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class AdminAction extends ActionSupport implements ServletRequestAware {
private static final long serialVersionUID = -1090720652366248768L;
private static final Log logger = LogFactory.getLog(AdminAction.class);
private HttpServletRequest request;
private AuthenticationTicket ticket;
private AdminService adminService;
private List<User> users;
private List<Product> products;
//private List<String>productsAllList;
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public AuthenticationTicket getTicket() {
return ticket;
}
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
public void setTicket(AuthenticationTicket ticket) {
this.ticket = ticket;
}
#Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
public String redirectUsersTab() {
return "users";
}
public String redirectProductsTab() {
return "products";
}
private void initAdminService () {
logger.debug("initAdminService()...");
if (adminService == null) {
adminService = (AdminService)ServiceFinder.getContext(request).getBean("adminService");
}
}
public String loadUsersJson() {
initAdminService();
this.users = adminService.getUsersAll();
return "success";
}
public String loadProductsJson() {
initAdminService();
this.products = adminService.getProductsAll();
return "success";
}
//TODO: clean up
public String getAllProductsList() {
logger.debug("testParam, userId: " + this.userId);
initAdminService();
List<Product> temp = adminService.getProductsAll();
if (userId != null) {
User userTemp = new User();
userTemp.setId(new Long(userId));
List<Product> prodEntitled = adminService.getProductsByUser(userTemp);
logger.debug("Products entitled: " + prodEntitled);
}
//TODO: merge prod and prod entitled to Model to populate the grid
products = temp;
/*
if (temp != null && temp.size() > 0) {
this.productsAllList = new ArrayList<String>();
for (Product p : temp) {
this.productsAllList.add(p.getName());
}
}
*/
//logger.debug("this.productsAllList: " + this.productsAllList);
return "success";
}
}
Class to edit the grid:
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class EditUsersGridAction extends ActionSupport implements ServletRequestAware {
private static final Log logger = LogFactory.getLog(EditUsersGridAction.class);
private static final long serialVersionUID = -5485382508029951644L;
private HttpServletRequest request;
private AdminService adminService;
private String oper = "";
private Long id;
private String name;
private String sourceIp;
private String password;
private String username;
private Long deviceId;
private String deviceIp;
private String devicePortDescription;
private String devicePortLayer;
private String deviceType;
private List<Product>productsEntitled;
private List<GridColumnListModel> productsEntitledListModel;
private List<Product>productsAvailable;
public List<GridColumnListModel> getProductsEntitledListModel() {
try {
if (productsEntitled != null && productsEntitled.size() > 0) {
productsEntitledListModel = new ArrayList<EditUsersGridAction.GridColumnListModel>();
for (Product p : productsEntitled) {
GridColumnListModel tmp = new GridColumnListModel();
tmp.setName(p.getName());
tmp.setValue(p);
productsEntitledListModel.add(tmp);
}
return this.productsEntitledListModel;
}else {
return null;
}
} catch (Exception ex) {
logger.error("Exception in getProductsEntitledString", ex);
return null;
}
}
public void setProductsEntitledListModel(List<GridColumnListModel> productsEntitledListModel) {
this.productsEntitledListModel = productsEntitledListModel;
}
public Long getDeviceId() {
return deviceId;
}
public void setDeviceId(Long deviceId) {
this.deviceId = deviceId;
}
public String getDeviceIp() {
return deviceIp;
}
public void setDeviceIp(String deviceIp) {
this.deviceIp = deviceIp;
}
public String getDevicePortDescription() {
return devicePortDescription;
}
public void setDevicePortDescription(String devicePortDescription) {
this.devicePortDescription = devicePortDescription;
}
public String getDevicePortLayer() {
return devicePortLayer;
}
public void setDevicePortLayer(String devicePortLayer) {
this.devicePortLayer = devicePortLayer;
}
public String getDeviceType() {
return deviceType;
}
public void setDeviceType(String deviceType) {
this.deviceType = deviceType;
}
public String getOper() {
return oper;
}
public void setOper(String oper) {
this.oper = oper;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSourceIp() {
return sourceIp;
}
public void setSourceIp(String sourceIp) {
this.sourceIp = sourceIp;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public List<Product> getProductsEntitled() {
return productsEntitled;
}
public void setProductsEntitled(List<Product> productsEntitled) {
this.productsEntitled = productsEntitled;
}
public List<Product> getProductsAvailable() {
return productsAvailable;
}
public void setProductsAvailable(List<Product> productsAvailable) {
this.productsAvailable = productsAvailable;
}
public HttpServletRequest getRequest() {
return request;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
}
#Override
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
private void initAdminService () {
logger.debug("initAdminService()...");
if (adminService == null) {
adminService = (AdminService)ServiceFinder.getContext(request).getBean("adminService");
}
}
public String execute() throws Exception {
logger.debug("#### IN EditGridUsersAction ###");
initAdminService();
productsAvailable = adminService.getProductsAll();
User user = new User();
user.setName(name);
user.setPassword(password);
user.setUsername(username);
user.setSourceIp(sourceIp);
Device device = new Device();
device.setId(deviceId);
device.setIp(deviceIp);
device.setPortDescription(devicePortDescription);
device.setType(deviceType);
user.setDevice(device);
if (id != null) {
user.setId(id);
}
if (oper.equalsIgnoreCase("add")) {
logger.debug("products selected");
//user.setProductsEntitled(adminService.getProductsAll());
adminService.addUser(user);
} else if ( oper.equalsIgnoreCase("edit")) {
//TODO: convert model to products and add to user
logger.debug("now in edit");
List<Product> tempProd = new ArrayList<Product>();
for (GridColumnListModel gridColModel : productsEntitledListModel) {
tempProd.add(gridColModel.getValue());
}
user.setProductsEntitled(tempProd);
adminService.updateUser(user);
//return "input";
}else if (oper.equalsIgnoreCase("del")) {
logger.debug("in delete");
adminService.deleteUser(user);
}
return "success";
}
public class GridColumnListModel {
private String name;
private Product value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Product getValue() {
return value;
}
public void setValue(Product value) {
this.value = value;
}
}
}

Issue with <s:hidden /> in Struts 2

I am facing an issue with <s:hidden /> The value is not populated.
<s:hidden name="objectName.stringName" /> works.
<s:hidden name="stringName" /> doesn't. I have getters and setters and I tried in debug mode. The getter function is called.
I also tried <s:hidden name="stringName" value="%{stringName}"/> But it did not work.
Could someone please provide any solution to this behaviour ?
EDIT :
Action class :
public class Test extends ActionSupport implements
ParameterAware, SessionAware {
private String stringName;
private ObjectA objectName;
public String getStringName() {
return stringName;
}
public void setStringName(String s) {
this.stringName = s;
}
public String getObjectName() {
return objectName;
}
public void setObjectName(ObjectA oa) {
this.objectName = oa;
}
public String execute() throws Exception {
objectName = POPULATE_THIS_OBJECT_SOMEHOW
this.stringName = objectName.getStringName();
return SUCCESS;
}
}
ObjectA :
public class ObjectA {
private String stringName;
public String getStringName() {
return stringName;
}
public void setStringName(String s) {
this.stringName = s;
}
}

Resources