I am creating an application with Spring 4, Hibernate 4 having Spring security
Users have roles assigned to them, but when I tried to create the user, it not able to save the user it is giving me exception on Browser below the field of role
Failed to convert property value of type [java.lang.String[]] to required type [java.util.Set] for property userRoles; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type
[#org.hibernate.validator.constraints.NotEmpty #javax.persistence.ManyToMany #javax.persistence.JoinTable com.himanshu.blogger.model.Role] for value 2; nested exception is java.lang.StackOverflowError
My User model class
#Entity
#Table(name = "BLOG_USER")
public class User {
#Id
#Column(name = "USER_ID")
private String userId;
#NotEmpty
#Column(name = "PASSWORD")
private String password;
#NotEmpty
#Column(name = "FIRST_NAME")
private String firstName;
#NotEmpty
#Column(name = "MIDDLE_NAME")
private String middleName;
#NotEmpty
#Column(name = "LAST_NAME")
private String lastName;
#Column(name = "EMAIL")
private String email;
#Column(name = "PHONE")
private String phone;
#NotNull
#Column(name = "STATE")
private Integer state = State.ACTIVE.getState();
#Transient
private String stateName;
#NotEmpty
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "USER_ROLE_MAP", joinColumns = { #JoinColumn(name = "USER_ID") }, inverseJoinColumns = {
#JoinColumn(name = "ROLE_ID") })
private Set<Role> userRoles = new HashSet<>();
/*skipped getter, setters and some utility methods*/
Role model class
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="ROLE_ID")
private Integer roleId;
#Column(name="ROLE_TYPE", length=20, nullable=false, unique=true)
private String roleType=RoleType.USER.getRoleType();
/*skipped getters and setters*/
My controller methods for registering new user here I have added a model attribute also to load the roles in registration form
/**
* This method will provide the medium to add a new user.
* By GET method it will identify that it has to load registration page
*/
#RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", false);
return "registration";
}
/**
* This method will be called on form submission, handling POST request for
* saving user in database. It also validates the user input
*/
#RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(#Valid User user, BindingResult result, ModelMap model) {
System.out.println("save user : "+user);
if (result.hasErrors()) {
return "registration";
}
if(!userService.isUniqueUser(user.getUserId())){
FieldError userIdError =new FieldError("user","userId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getUserId()}, Locale.getDefault()));
result.addError(userIdError);
return "registration";
}
userService.saveUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");
//return "success";
return "registrationsuccess";
}
#ModelAttribute("blogRoleList")
public List<Role> initializeProfiles() {
return roleService.findAll();
}
I have registered a convertor to convert role id to Role object
#Component
public class RoleIdtoRoleConverter implements Converter<Object, Role> {
#Autowired
RoleService roleService;
public Role convert(Object roleIdObj) {
System.out.println("covertor called with id " + roleIdObj.toString());
Integer roleId = -1;
try {
roleId = Integer.parseInt((String) roleIdObj);
} catch (NumberFormatException e) {
throw new ConversionFailedException(TypeDescriptor.valueOf(String.class),
TypeDescriptor.valueOf(Role.class), roleIdObj, null);
}
System.out.println("covertor called with id " + roleIdObj.toString());
Role role = roleService.findRoleById(roleId);
System.out.println("Role = " + role);
return role;
}
Registered this convertor in my config class
#Autowired
RoleIdtoRoleConverter roleIdToRoleConverter;
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(roleIdToRoleConverter);
}
Registration JSP file registration.jsp
<form:form method="POST" modelAttribute="user" class="form-horizontal">
<%-- <form:input type="hidden" path="userId" id="useId"/> --%>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="firstName">First Name</label>
<div class="col-md-7">
<form:input type="text" path="firstName" id="firstName" class="form-control input-sm"/>
<div class="has-error">
<form:errors path="firstName" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="lastName">Last Name</label>
<div class="col-md-7">
<form:input type="text" path="lastName" id="lastName" class="form-control input-sm" />
<div class="has-error">
<form:errors path="lastName" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="userId">User ID</label>
<div class="col-md-7">
<c:choose>
<c:when test="${edit}">
<form:input type="text" path="userId" id="userId" class="form-control input-sm" disabled="true"/>
</c:when>
<c:otherwise>
<form:input type="text" path="userId" id="userId" class="form-control input-sm" />
<div class="has-error">
<form:errors path="userId" class="help-inline"/>
</div>
</c:otherwise>
</c:choose>
</div>
</div>
</div>
<c:if test="${!edit}">
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="password">Password</label>
<div class="col-md-7">
<form:input type="password" path="password" id="password" class="form-control input-sm" />
<div class="has-error">
<form:errors path="password" class="help-inline"/>
</div>
</div>
</div>
</div>
</c:if>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="email">Email</label>
<div class="col-md-7">
<form:input type="text" path="email" id="email" class="form-control input-sm" />
<div class="has-error">
<form:errors path="email" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3 control-lable" for="userRoles">Roles</label>
<div class="col-md-7">
<form:select path="userRoles" items="${blogRoleList}" multiple="true" itemValue="roleId" itemLabel="roleType" class="form-control input-sm" />
<div class="has-error">
<form:errors path="userRoles" class="help-inline"/>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-actions floatRight" style="margin-left: 25px">
<c:choose>
<c:when test="${edit}">
<input type="submit" value="Update" class="btn btn-primary btn-sm"/> or Cancel
</c:when>
<c:otherwise>
<input type="submit" value="Register" class="btn btn-primary btn-sm"/> or Cancel
</c:otherwise>
</c:choose>
</div>
</div>
</form:form>
But am not able to figure out it is not able to save the data, I have printed the user object in controller it is showing Roles as blank array, did I am missing some things here, not able to get, any help and suggestions will be got.
Adding Code for saving user
Abstract dao class
public class AbstractDao <PK extends Serializable, T>{
private final Class<T> persistantClass;
#Autowired
SessionFactory sessionFactory;
#SuppressWarnings("unchecked")
public AbstractDao() {
this.persistantClass=(Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
public void persistEntity(T entity) {
this.getSession().persist(entity);
}
/* mor emethods to load data on based on object type */
}
User Dao implimentation calss
#Repository("userDao")
public class UserDaoImpl extends AbstractDao<String, User> implements UserDao{
#Override
public void saveUser(User user) {
persistEntity(user);
}
/* more methods for fetching data from db*/
}
Thanks.
I got the problem with my application.
The problem was with the dao method which was there to get role object from DB,
by mistake while writing the code I did made the call to same method, which executing recursively, so convertor was not able to get the role object from DB.
Related
I got a MVC web page and i try to get a value from a input type="datetime-local" and save the value in th:field. to be able to save these dates and also work with them
But it seams to work only in input="text" tags, not type="datetime-local" because when i debug, the date value of the input that is type="datetime-local"
I need the client to select the Date the event its goint to start
Here is an example of the whole form and the two inputs that save the date.
Client view
[enter image description here][1]
View
<div class="container">
<div class="row">
<div class="col-md-4 mt-5">
<form th:action="#{/guardar/} + ${usuario.id_user}" method="post" th:object="${event}">
<div class="form-group">
<label for="title" >Titulo </label>
<input type="text" id="title" placeholder="Titulo" class="form-control" th:field="*{title}"/>
</div>
<div class="form-group">
<label for="e_description" >Descripción</label>
<input type='text' name="e_description" th:field="*{e_description}" placeholder="Descripcion" class="form-control"/>
</div>
<div class="form-group">
<label for="startDate">Inicio de Evento:</label>
<input type="text" id="time" placeholder="Inicio de Evento" class="form-control" th:field="*{startDate}"/>
</div>
<div class="form-group">
<label for="endDate">Termino de Evento:</label>
<div class="input-group date" id="endDate">
<input type="datetime-local" id="time2" placeholder="Termino de Evento" class="form-control" th:field="*{endDate}"/>
<div class="input-group-addon input-group-append">
<div class="input-group-text">
<i class="fa fa-clock-o"></i>
</div>
</div>
</div>
</div>
<div class="form-group">
<label for="className" >ClassName</label>
<input type="text" name="className" th:field="*{className}" placeholder="className" class="form-control"/>
</div>
<div class="form-group">
<label for="icon">Icono</label>
<input type="text" name="icon" th:field="*{icon}" placeholder="icon" class="form-control" />
</div>
<div class="form-group">
<label for="allDay">¿Todo el día?</label>
<input type="checkbox" value="true" name="allDay" th:field="*{allDay}" />
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
</div>
</div>
</div>
The Controller of /guardar/} + ${usuario.id_user}
#PostMapping("/guardar/{id}")
public String guardar(#Valid Event event, Errors errores,#PathVariable int id,Model model) throws ParseException {
/* if (errores.hasErrors()) {
return "agregar";
}*/
UserPlanD userPlanD = userService.encontrarUsuarioPorId(id);
model.addAttribute("usuario",userPlanD);
event.setUser(userPlanD);
Date inicio_evento = formatter.parse(event.getStartDate().toString());
String termino_evento = event.getStartDate().toString();
event.setStartDate(inicio_evento);
List<Event> eventicos = Arrays.asList(event);
System.out.println("Evento" + event + "y usuario: " + userPlanD);
eventService.guardar(event);
/*userPlanD.setEvents(eventicos);
userService.guardar(userPlanD);*/
return "redirect:/eventos";
}
The Model is the next one:
#Table(name="event_calendar")
public class Event implements Serializable {
//private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id_event")
private Long id_event;
#Column(name = "title")
private String title;
#NotEmpty
private String e_description;
#NotEmpty
#JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS")
#Column(columnDefinition = "DATETIME")
private Date startDate;
#NotEmpty
#JsonFormat(pattern="yyyy-MM-dd HH:mm:ss.SSSSSS")
#Column(columnDefinition = "DATETIME")
private Date endDate;
#NotEmpty
private String className;
#NotEmpty
private String icon;
#NotEmpty
private String allDay;
#ManyToOne
#JoinColumn(name = "id_user")
private UserPlanD user; ```
Here its a debug result of the controller result in the line the got the next code "System.out.println("Evento" + event + "y usuario: " + userPlanD)"
[1]: https://i.stack.imgur.com/QOYfW.png
I have spent the whole day and night trying to find why my form data disappears when validation fails. I also added a redirectAttributes.addFlashAttribute which is suppose to indicate that an error occurred and also survive one redirect. So far none of these are working. I have done my research on stack over and other forums and i seem to be doing the right thing but it is not working for me.
I am not getting an error so i can not even debug to find what is wrong.
<div class="form-group" th:if="${exams.size() lt 6}">
<form method="post" th:object="${newExam}" th:action="#{/exams}" class="inline new-item">
<div th:classappend="${#fields.hasErrors('indexNumber')}? 'error' : ''">
<input type="text" th:field="*{indexNumber}" placeholder="Index Number" />
<div class="error-message" th:if="${#fields.hasErrors('indexNumber')}" th:errors="*{indexNumber}"></div>
</div>
<div th:classappend="${#fields.hasErrors('grade')}? 'error' : ''">
<select th:field="*{grade}" class="form-control input-lg">
<option value="">[Select Grade]</option>
<option th:each="grade : ${grades}" th:value="${grade.values}" th:text="${grade.name}">Grade
</option>
</select>
<div class="error-message" th:if="${#fields.hasErrors('grade')}" th:errors="*{grade}"></div>
</div>
<div th:classappend="${#fields.hasErrors('courseOffered')}? 'error' : ''">
<input type="text" th:field="*{courseOffered}" placeholder="CourseOffered" />
<div class="error-message" th:if="${#fields.hasErrors('courseOffered')}" th:errors="*{courseOffered}"></div>
</div>
<div th:classappend="${#fields.hasErrors('examType')}? 'error' : ''">
<input type="text" th:field="*{examType}" placeholder="ExamType" />
<div class="error-message" th:if="${#fields.hasErrors('examType')}" th:errors="*{examType}"></div>
</div>
<div th:classappend="${#fields.hasErrors('subject')}? 'error' : ''">
<input type="text" th:field="*{subject}" placeholder="Subject" />
<div class="error-message" th:if="${#fields.hasErrors('subject')}" th:errors="*{subject}"></div>
</div>
<div th:classappend="${#fields.hasErrors('gradeYear')}?'error' : ''">
<input type="text" th:field="*{gradeYear}" placeholder="ExamYear" />
<div class="error-message" th:if="${#fields.hasErrors('gradeYear')}" th:errors="*{gradeYear}"></div>
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
Controller
#RequestMapping(value = "/cert_prog", method = RequestMethod.GET)
public String examsList(Model model){
Iterable<Exams> exams = examService.findAll();
if(!model.containsAttribute("newExam")){
model.addAttribute("newExam", new Exams()); }
model.addAttribute("grades", Grade.values());
model.addAttribute("regions", Region.values()); model.addAttribute("schools",schools);
if(!model.containsAttribute("newSchool")){
model.addAttribute("newSchool",new School()); }
model.addAttribute("regions", Region.values());
return "cert_prog"; }
#RequestMapping(value = "/exams", method = RequestMethod.POST) public String addTask(#Valid
#ModelAttribute("newExam") Exams exams, BindingResult result, RedirectAttributes redirectAttributes, Principal principal){
User user = (User)((UsernamePasswordAuthenticationToken)principal).getPrincipal(); exams.setUser(user);
if(result.hasErrors()){
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.exams", result);
redirectAttributes.addFlashAttribute("exams",exams); return "redirect:/cert_prog"; }
examService.save(exams);
return "redirect:/cert_prog"; }
Model
#Entity
public class Exams {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull(message = "The above field must not be blank.")
private String courseOffered;
#NotNull(message = "The above field must not be blank.")
private String examType;
#NotNull(message = "The above field must not be blank.")
private String subject;
#NotNull(message = "The above field must not be blank.")
private String grade;
#NotNull(message = "The above field must not be blank.")
private Long indexNumber;
#NotNull(message = "The above field must not be blank.")
private Long gradeYear;
private boolean isComplete;
In your addTask controller method you have
redirectAttributes.addFlashAttribute("exams",exams)
attribute name as "exams" and you are checking as "newExam" in examsList controller method. This might be the problem.
try this,
redirectAttributes.addFlashAttribute("newExam",exams)
I faced this problem while I was validating my forms, For single entities it worked fine. But when I try to validate a object with nested objects I get this error.
HTTP Status 500 - Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [com.poultry.jp.model.PaymentRequest] during persist time for groups [javax.validation.groups.Default, ]
Following is my controller
#RequestMapping(value = {"user/addMedicineOrder","admin/addMedicineOrder"}, method = RequestMethod.GET)
public String addMedicineOrderGET(#ModelAttribute("medicineOrder") MedicineOrder medicineOrder,Model model) {
List<SupplierReport> supplierReport = supplierService.getSupplierNames();
List<MedicineOrderReport> medicineOrderReport = medicineOrderService.getMedicineOrderDetails();
List<PaymentRequestReport> paymentRequestReport = paymentRequestSerivice.getPaymentRequestDates();
List<MedicineReport> medicineReport = medicineService.getMedicineDetails();
model.addAttribute("medicineOrderReport",medicineOrderReport);
model.addAttribute("supplierReport", supplierReport);
model.addAttribute("paymentRequestReport", paymentRequestReport);
model.addAttribute("medicineReport", medicineReport);
return "addMedicineOrder";
}
#RequestMapping(value = {"user/addMedicineOrder","admin/addMedicineOrder"}, method = RequestMethod.POST)
public String addMedicineOrderPOST(#Valid #ModelAttribute("medicineOrder") MedicineOrder medicineOrder,BindingResult result) {
if (result.hasErrors()) {
return "addMedicineOrder";
} else {
medicineOrderService.save(medicineOrder);
return "redirect:addMedicineOrder.html";
}
}
Following is my Medicine Order Model
public class MedicineOrder {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long medicineOrderId;
#OneToMany(mappedBy = "medicineOrder", cascade = CascadeType.ALL,fetch = FetchType.EAGER,orphanRemoval=true)
private List<MedicineOrderDetails> medicineOrderDetails = new ArrayList<MedicineOrderDetails>();
#ManyToOne
private Supplier supplier;
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date date;
private double total;
private double discount;
private boolean inStock;
#OneToOne(cascade={CascadeType.MERGE , CascadeType.PERSIST})
#JoinColumn(name="paymentRequest_id")
private PaymentRequest paymentRequest;
private boolean isDeleted;
private Date created;
private Date updated;
// Getters and Setters
}
Following is the dependent class Payment Request
public class PaymentRequest{
public static final String FIND_PAYMENT_REQUEST_DATES = "findPaymentReequestDates";
public static final String FIND_PAYMENT_REQUEST_BY_ID = "findPaymentReequestById";
public static final String FIND_PAYMENT_REQUEST_REPORT = "findPaymentRequestReport";
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long paymentId;
private double amount;
#Type(type = "text")
#NotEmpty
private String description;
private String chequeID;
private String status;
#DateTimeFormat(pattern = "yyyy-MM-dd")
#Temporal(TemporalType.DATE)
private Date date;
private boolean isDeleted;
private boolean isPaid;
private Date created;
private Date updated;
//Getters and Setters
}
and Following is where I persist Medicine Order which persist the payment request with it.
#Repository("MedicineOrderRepository")
public class MedicineOrderRepositoryImp implements MedicineOrderRepository{
#PersistenceContext
private EntityManager entityManager;
public MedicineOrder save(MedicineOrder medicineOrder){
for(MedicineOrderDetails order : medicineOrder.getMedicineOrderDetails())
{
order.setMedicineOrder(medicineOrder);
}
medicineOrder.getPaymentRequest().setStatus("Pending");
entityManager.persist(medicineOrder);
entityManager.flush();
return medicineOrder;
}
}
And Finally following the jsp code.
<div class=".col-md-6">
<form:form commandName="medicineOrder" class="form-horizontal"
autocomplete="off">
<form:errors path="*" Class="alert alert-danger" element="div" />
<div class="form-group">
<label for="inputDescription" class="col-sm-2 control-label">Description</label>
<div class="col-sm-3">
<form:textarea path="paymentRequest.description" type="text"
class="form-control" id="inputDescription"
placeholder="Enter Short Description" rows="3" />
</div>
</div>
<div class="form-group">
<label for="inputAmount" class="col-sm-2 control-label">Amount</label>
<div class="col-sm-3">
<form:input path="paymentRequest.amount" type="text"
class="form-control" id="inputAmount" placeholder="Enter Amount" />
</div>
</div>
<div class="form-group">
<label for="supplierId" class="col-sm-2 control-label">Supplier</label>
<div class="col-sm-5">
<form:select path="supplier.supplierId" id="supplierId"
class="form-control">
<form:options items="${supplierReport}" itemLabel="name"
itemValue="supplierId" id="" />
</form:select>
</div>
</div>
<div class="form-group">
<label for="inputTotal" class="col-sm-2 control-label">Total</label>
<div class="col-sm-5">
<form:input path="total" type="text" class="form-control"
id="inputTotal" name="inputTotal" />
</div>
</div>
<div class="form-group">
<label for="inputDiscount" class="col-sm-2 control-label">Discount
</label>
<div class="col-sm-5">
<form:input path="discount" type="text" class="form-control"
id="inputDiscount" />
</div>
</div>
<input type="submit" value="Save Medicine Order"
class="btn btn-primary">
</form:form>
</div>
I was able to resolve this.
Credit goes to this forum, http://forum.spring.io/forum/spring-projects/web/87783-jsr-303-validation-on-child-objects
what I had to do was just add #Valid annotation in my parent class's child object
EX:
#Valid
private PaymentRequest paymentRequest;
I have an Entity as
#Entity
public class Foo {
#Id
#GeneratedValue
private Integer id;
#Size(min = 5,max = 50, message = "Valid title is 5-50 chars")
private String title;
#Lob
#Column(length=1000000)
private String description;
#NotNull(message = "Location must be specified")
private String location;
// getters & setters go here
}
and I have a method to save Foo as
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addDetail(#ModelAttribute("foo") Foo foo) {
fooService.persistFoo(foo);
return "redirect:/";
}
at this point if I submit form with invalid data I get exception as
HTTP Status 500 - Request processing failed; nested exception is javax.validation.ConstraintViolationException: Validation failed for classes [com.rhcloud.pro.entity.Foo] during persist time for groups [javax.validation.groups.Default, ]
Now I want to implement form validation as
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String addDetail(#ModelAttribute("foo") #Valid Foo foo, BindingResult bindingResult) {
if (!bindingResult.hasErrors()) {
fooService.persistFoo(foo);
return "redirect:/";
}else{
return "add";
}
}
and add.jsp is
<form:errors path="foo"/>
<form:form commandName="foo" class="form" id="add">
<div class="form-group form-group-label">
<div class="row">
<div class="col-md-10 col-md-push-1">
<label class="floating-label" for="login-username">Title</label>
<form:input name="title" path="title" cssClass="form-control" />
<span class="form-help form-help-msg text-red"><i class="form-help-icon icon icon-error"></i></span>
</div>
</div>
</div>
<div class="form-group form-group-label">
<div class="row">
<div class="col-md-10 col-md-push-1">
<label class="floating-label" for="login-username">Location</label>
<form:input name="location" path="location" cssClass="form-control" />
</div>
</div>
</div>
<div class="form-group form-group-label">
<div class="row">
<div class="col-md-10 col-md-push-1">
<label class="floating-label" for="login-username">Description</label>
<form:textarea name="description" path="description" cssClass="form-control" />
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-10 col-md-push-1">
<button
class="btn btn-block btn-blue waves-button waves-effect waves-light">Add</button>
</div>
</div>
</div>
</form:form>
now if I submit form with invalid data I don't get exception and I redirect to my add page but I don't see any error messages, but If I give correct data to form then the form is redirected to add page, I can not figure out how to get form validation done correctly.
I want to set values for Set elements of login from JSP .
JSP page:
<form action="Registered" method="post">
<div class="form-group">
<label>Company Name</label>
<s:textfield name="name" value="%{name}" id="name"/>
</div>
<div class="form-group">
<label>Address</label>
<s:textarea name="address" value="%{address}" id="address"/>
</div>
<div class="form-group">
<label>User Name</label>
<s:textfield name="logins[0].userName" value="%{logins[0].userName}" id="userName"/>
</div>
<div class="form-group">
<label>User Id</label>
<s:textfield name="logins[0].userId" value="%{logins[0].userId}" id="userId"/>
</div>
<div class="form-group">
<label>Mail Id</label>
<s:textfield name="logins[0].userMailid" value="%{logins[0].userMailid}" id="userMailid"/>
</div>
Pojo Classes:
public class Client implements java.io.Serializable {
private Set logins = new HashSet(0);
//getter and setter
}
public class Login implements java.io.Serializable {
private Long id;
private Client client;
private String userId;
private String userName;
private String userMailid;
}
Action Class:
public String register() {
Client cl = new Client();
System.out.println(cl.getName() + " " + cl.getAddress());
}
I want to set values of set in to my Action class for Client and Login.
How to do this?
You can use a submit button like this:
<form action="Registered" method="post">
<div class="form-group">
<label>Company Name</label>
<s:textfield name="name" value="%{name}" id="name"/>
</div>
<div class="form-group">
<label>Address</label>
<s:textarea name="address" value="%{address}" id="address"/>
</div>
<div class="form-group">
<label>User Name</label>
<s:textfield name="logins[0].userName" value="%{logins[0].userName}" id="userName"/>
</div>
<div class="form-group">
<label>User Id</label>
<s:textfield name="logins[0].userId" value="%{logins[0].userId}" id="userId"/>
</div>
<div class="form-group">
<label>Mail Id</label>
<s:textfield name="logins[0].userMailid" value="%{logins[0].userMailid}" id="userMailid"/>
</div>
<input type="submit" value="Submit">
</form>
EDIT
A nice tutorial
After make properties file like:
#Global messages
name= name
submit = Submit
I believe you has made Registered.jsp.
An you can run your project!
To bind fildes to Set you should put annotations on this property
public class Client implements java.io.Serializable {
#Element(value = Login.class)
#Key(value = Long.class)
#KeyProperty(value = "id")
#CreateIfNull(value = true)
private Set logins = new HashSet(0);
//getter and setter
//now you need a property for login id, it should be initialized before JSP is populated
private Long loginId;
//getter and setter
}
now binding to the fields of the JSP change to
<s:textfield name="logins(%{loginId}).userName" id="userName"/>
the same for other fields that are bound to a set.
If you are using iterator tag to iterate through a set and you have an instance of Login pushed on top of the value stack then you can get its id instead of using loginId.