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.
Related
I have two objects a Books and an Authors. The author is a property of the Book.
Book pojo:
#Entity
#Table(name = "BOOK")
public class Books {
private Long bookId;
private String bookTitle;
private Authors author;
// Getter and Setter
}
Authors pojo:
#Entity
#Table(name = "AUTUORS")
public class Authors {
private Long authorId;
private String authorFullName;
//getter and setter
}
I need to make a form with two inputs for entering book title and Author name.
Like the following:
<form action="#" class="form" enctype="multipart/form-data" method="post"
th:action="#{/management/add-book-form}" th:object="${book}">
<div class="form-row ">
<div class="form-group col-md-3">
<input type="text" class="form-control" th:field="*{book. getBookTitle()}"
placeholder="Author full name">
<input type="text" class="form-control" th:field="*{book. getAuthor()}"
placeholder="Author full name">
</div>
</div>
</form>
delete placeholder property from input , and access to field direct by field name:
<form action="#" class="form" enctype="multipart/form-data" method="post"
th:action="#{/management/add-book-form}" th:object="${book}">
<div class="form-row ">
<div class="form-group col-md-3">
<input type="text" class="form-control" th:field="*{bookTitle}" >
<input type="text" class="form-control" th:field="*{author.authorFullName}">
</div>
</div>
</form>
*{...} expressions automatically use the th:object. So the expression *{bookTitle} roughly translates to ${book.bookTitle} and *{author.authorFullName} to ${book.author.authorFullName}
This should work for you:
<input type="text" th:field="*{bookTitle}" />
<input type="text" th:field="*{author.authorFullName}" />
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 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.
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 -> Hi I have different bootstrap modals in one page general.jsp.Modals are wrapped through c:if condition.So only one modal should be enable on general.jsp on click of button.For this I am delegating one ajax request to controller and adding Boolean variable to model attribute and returning it.
But the problem is that boolean variable is not appearing in requestScope because of which <c:if test="${requestScope.isAddCategoryAttribute}"> is not able to execute and modal is not enabling to jsp .How do I handle such scenario using ajax in spring mvc?
2-> If condition is true and modal is enabled , then I have to submit data through modal, which is having its input field binded through CategoryAttribute entity , CategoryAttribute is a collection entity of a Category class.
But the problem is that , in general.jsp page category Object is already binded and populated in UI. And here modal is present in the same page general.jsp with different form tag.
So how would I handle posting data of collection entity inside modal .So that it will persist the collection data of binded entity class?
Any sample code in controller side would be helpful to deal such situation thanks in advance
This is my Category class
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "CATEGORY")
public class Category implements Serializable {
#OneToMany(mappedBy = "category", targetEntity = CategoryAttribute.class, cascade = { CascadeType.ALL }, orphanRemoval = true)
(name = "name")
#BatchSize(size = 50)
protected Map<String, CategoryAttribute> categoryAttributes = new HashMap<String, CategoryAttribute>();
setter getter and many more attribute
}
This is CategoryAttribute class which is used in modal
#Entity
#Inheritance(strategy = InheritanceType.JOINED)
#Table(name = "CATEGORY_ATTRIBUTE")
public class CategoryAttribute implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "CATEGORY_ATTRIBUTE_ID")
protected Long id;
#Column(name = "NAME", nullable = false)
protected String name;
#Column(name = "VALUE")
protected String value;
#ManyToOne(targetEntity = Category.class, optional = false)
#JoinColumn(name = "CATEGORY_ID")
})
protected Category category;
setter getter
}
This is my general.jsp which is having already data populated related to category and it has button which is causing to open modal and submit the category attribute data
<form:form action="saveCategory" method="post" id="categoryForm"
modelAttribute="category">
<div class="tab-content">
<div id="general" class="tab-pane fade in active">
<div class="bodycontainer">
/** have some input fields which is already populated and bind with category object
</div>
/** this file have buttons which is causing to open below bootstrap modal
<%#include file="advanced.jsp"%>
</div>
</div>
</form:form>
<div class="listgrid-toolbar-footer"></div>
<c:if test="${requestScope.isAddCategoryAttribute}">
<div class="modal fade" id="modalCategoryAttribute" tabindex="-1"
role="dialog" aria-labelledby="myModelCattLabel"
aria-hidden="true">
<div class="modal-dialog" aria-hidden="true">
<div class="modal-content">
<form:form action="submitCategoryAttribute" modelAttribute="category">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h3 class="modal-title">Add Cattegory Attribute</h3>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading">
<fieldset class="Key">
<legend class="ActiveDateRange">Key</legend>
<div class="form-group">
<label for="key">Key*:</label>
<div class='input-group date' id='name'>
<form:input path="categoryAttributesMap['check'].name"
cssClass="form-control" />
<!-- <input type="text" class="form-control" /> -->
</div>
</div>
</fieldset>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<fieldset class="Description">
<legend class="ActiveDateRange">Description</legend>
<div class="form-group">
<label for="key">Attribute Value*:</label>
<div class='input-group date' id='attributeValue'>
<form:input path="categoryAttributesMap['check'].value"
cssClass="form-control" />
<!-- <input type="text" class="form-control" /> -->
</div>
</div>
</fieldset>
</div>
</div>
</div>
<div class="modal-footer">
<span class="text-muted"><input type="submit"
id="addCategoryAttrButton" class="btn btn-primary"
value="Save" /></span>
</div>
</form:form>
</div>
</div>
</div>
</c:if>
Advance.jsp
<div id="listgridthree" class="listgrid-toolbar">
<ul>
<li>
<button type="submit" id="category_attribute" class="btn btn-primary">Add</button>
<button type="submit" class="btn btn-primary">Edit</button>
<button id="delete" type="submit"
class="btn btn-primary disabled">Delete</button>
</li>
</ul>
</div>