Using finders in views - spring

I don't understand how I can use a finder that takes a parameter to display only the returned data.
For example, I have a finder findPrincipalsByUsernameLike(String username) in Principle entity, how can I use this finder in list.jspx to show the user only his/her data?
Principle.java
#RooJavaBean
#RooToString
#RooJpaActiveRecord(table = "security_principals", finders = { "findPrincipalsByUsernameLike" })
public class Principal {
#NotNull
#Size(min = 5, max = 50)
private String username;
#NotNull
#Size(min = 5, max = 50)
private String password;
private Boolean enabled;
}
users/list.jspx
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<div xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:page="urn:jsptagdir:/WEB-INF/tags/form"
xmlns:table="urn:jsptagdir:/WEB-INF/tags/form/fields" version="2.0">
<jsp:directive.page contentType="text/html;charset=UTF-8" />
<jsp:output omit-xml-declaration="yes" />
<page:find finderName="findPrincipalsByUsernameLike"
id="ff_edu_gju_syria_model_security_principal"
path="/principals/find">
<input data-dojo-props="trim:true" data-dojo-type="dijit/form/TextBox"
id="toolbarFilter" name="filter" type="text" value="${filter}" />
</page:find>
<page:list id="pl_edu_gju_syria_model_security_Principal"
items="${principals}" z="+E0uiC5dOFGeuICZbYdoS6Nz80o=">
<table:table data="${principals}"
id="l_edu_gju_syria_model_security_Principal" path="/security/users"
z="9ue3QOERNh44QuGQIg9JQzmFKnI=">
<table:column id="c_edu_gju_syria_model_security_Principal_username"
property="username" z="REKFqtjHv0gJUiSxe+y1TKytm1w=" />
<table:column id="c_edu_gju_syria_model_security_Principal_password"
property="password" z="4khHEC8FhwrPHVFPG7c4s5cP8L4=" />
<table:column id="c_edu_gju_syria_model_security_Principal_enabled"
property="enabled" z="boq7MuGPymSQN1CCWrQ8INhy1DM=" />
</table:table>
</page:list>
</div>
How can I pass the current username without showing a text area for the user?

You don't have to send the user as request param.
In the Controller method that handles the request just get the user principal from the request.
Spring Security 3.2 introduced great improvements for easier user detail management, take a look to How to get active user's UserDetails

Related

DBUnit error : NoSuchTableException

I tried to write Unit tests for my database Services according to this example (https://github.com/21decemb/spring-boot-dbunit-example). I created dataset and test example. After I run the test I recived: org.dbunit.dataset.NoSuchTableException: orders
dataset.xml:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<!-- CUSTOMER DATA -->
<customers id="1" name="Customer" active="1"/>
<!-- POSITION DATA -->
<positions id="1" name="POSITION1"/>
<positions id="2" name="POSITION2"/>
<positions id="3" name="POSITION3"/>
<!-- ORDER DATA -->
<orders id="1" name="order1" color="RED" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" parent_id="1" active="1"/>
<!--<orders id="2" name="order2" color="WHITE" customer_id="1" position_id="1" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" active="0"/>-->
</dataset>
The second Order Row is commented becacuse I was testing two possibilities. I know that this is because of joins. When I test only 'positions' and 'customers' (simple entities without joins) it works correctly.
My "Order" entity:
#Entity
#Table(name = "orders", schema = Config.dbSchema)
public class Order implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="POSITION_ID")
private Position position;
private short express;
private Date date;
#Column(name="LAST_UPDATE")
private Date lastUpdate;
#Column(name="parent_id")
private Long parentId;
private short active;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="CUSTOMER_ID")
private Customer customer;
#OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
private List<Component> components;
//getters and setters
}
Have anyone any idea on how to fix it?
Thanks in advance.
You have to add this property in the override method setUpDatabaseConfig:
#Override
protected void setUpDatabaseConfig(DatabaseConfig config) {
config.setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
}
In addition probably you need to add the schema name like this:
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<!-- CUSTOMER DATA -->
<schemaName customers id="1" name="Customer" active="1"/>
<!-- POSITION DATA -->
<schemaName positions id="1" name="POSITION1"/>
<schemaName positions id="2" name="POSITION2"/>
<schemaName positions id="3" name="POSITION3"/>
<!-- ORDER DATA -->
<schemaName orders id="1" name="order1" color="RED" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" parent_id="1" active="1"/>
<!--<schemaName orders id="2" name="order2" color="WHITE" customer_id="1" position_id="1" express="0" date="2016-12-11 19:47:39" last_update="2016-12-11 19:47:39" active="0"/>-->
</dataset>

Spring form insert data in model object inside base domain model

I have a model like this:
public class User{
private int id;
private City city;
//Getter - setters
}
public class City{
private int id;
private String name;
//Getter - setters
}
Now on JSP I want to show a form for User model, which should ask for user's city in a dropdown, and corresponding city object should get stored in city object in User model.
For normal fields, I know we can write something like this:
<form:input path="name" />
But how can we bind a model object inside our base model? And how Spring will know, which object it should store in that after user selects any city?
Pretty easy, you need #modelAttribute in your controller method (or simply add it to model) on loading the form and use in your case path should be city.name
Your question is more like how to reference a submodel, spring follows the bean path, in your case, if you wanna post a city with user object, you just need to do this
<form:form method="POST" commandName="user">
<form:input path="city.name" />
<form:input path="attribute of user" />
</form:form>

Binding ManyToMany association with Spring Form

I have a Company entity that has a ManyToMany association with an Acknowledgement entity.
#Entity
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private int id;
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "company_acknowledgement", joinColumns = #JoinColumn(name = "company_id"), inverseJoinColumns = #JoinColumn(name = "acknowledgement_id"))
#OrderBy("name")
private Set<Acknowledgement> acknowledgements = new HashSet<>();
...
}
#Entity
public class Acknowledgement {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private int id;
#Column(length = 50, nullable = false)
private String name;
...
}
Within a form, I want to be able to choose a number of acknowledgements that should be bound to the Company entity (with checkboxes). So when I submit the form with POST to my controller action, my Company object contains a number of Acknowledgement objects.
I tried to change the HashSet to TreeSet as discussed in this question, but without luck. The checked Acknowledgement objects will always exist in my database, so basically I only need to populate the id field for each object.
Here is my controller code:
#Controller
public class CompanyController {
#Autowired
private CompanyService companyService;
#RequestMapping("/company/edit/{companyId}")
public String edit(Model model, #PathVariable int companyId) {
Company company = this.companyService.get(companyId);
model.addAttribute("company", company);
return "company-edit";
}
#RequestMapping(value = "/company/edit", method = RequestMethod.POST)
public String doEdit(Model model, Company company) {
return ""; // TODO: persist company
}
}
And my JSP file (view)
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:url var="actionUrl" value="/company/edit" />
<form:form action="${actionUrl}" commandName="company">
<form:label path="name">Name:</form:label>
<form:input path="name" />
<%-- Other inputs here --%>
<input type="checkbox" name="acknowledgements[]" value="1" />
<input type="checkbox" name="acknowledgements[]" value="2" />
<form:button>Save Changes</form:button>
</form:form>
I tried various things, the above being one of them, but I cannot seem to figure out how to do this. So, how do I map the selected acknowledgements to the the association in my Company entity when submitting the form?
Thank you very much in advance!
In your jsp, you need to iterate the loop as below.
<c:forEach items="${company.acknowledgements}" var="ack" varStatus="count">
<input type="checkbox" name="acknowledgements[${count.index}].name" value="${ack.name}" />
</c:forEach>
EDIT:
Can you try checkboxes
<form:checkboxes path="acknowledgements" items="${company.acknowledgements}" />
Why don't you write your custom request argument resolver ?
For example implementing interface HandlerMethodArgumentResolver
(more: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/method/support/HandlerMethodArgumentResolver.html).
In 'resolverArgument' method (based on request with all arguments) you could build Company entity with selected acknowledgements.
First, you need to load the full list of Acknowledgement in your controller and put it in your model (let's say acknowledgementList). Simply loading the Company will only load that campany's acknowledgements, not the complete list.
Then in the jsp :
<form:checkboxes path="acknowledgements" items="${acknowledgementList}" itemValue="id" itemLabel="name" />
It seems you are missing implementation equals and hashCode method on your Company and Acknowledgement entities.
In your jsp you just write code like :
<form:checkboxes path="acknowledgements" items="${acknowledgementList}" itemValue="id" itemLabel="name"/>
and these guys have full answer :
https://stackoverflow.com/a/8718318/3846688

JSF/Primefaces doesn't validate #AssertTrue

my entity class look like this:
public class TimeFrame implements Serializable {
#NotNull
private Date startTime;
#NotNull
#Future
private Date stopTime;
To have the right order I added:
#AssertTrue(message="Wrong order")
public boolean isTimeFrameValid(){
return this.startTime.before(stopTime);
}
Now, JSF/Primefaces should validate this directly after input.
<p:calendar id="aucstop" required="true" pages="2" value="#{transportbean.stopTime}" >
<p:ajax event="dateSelect" />
<f:validateBean/>
</p:calendar>
For example, when putting a past date into "StopTime" I got immediately a message. The "isTimeValid"-Mothod however is only validated when the whole object ist being created. Any ideas how to validate this directly after input?
GF 3.1.1 PrimeFaces 3.4

Spring + hibernate + form

I have an User entity:
#Entity
#Table(name = "user")
public class User implements Serializable{
private enum Sex {MALE, FEMALE};
#Id #GeneratedValue
private Long id;
#NotNull
private String name;
#NotNull
private String password;
}
Controller:
#Controller
public class HomeController {
#RequestMapping("/addUser")
public String showHomePage(Map<String, Object> map) {
map.put("user", new User());
return "addUser";
}
and form in jsp file
<form:form method="post" action="add" commandName="user">
<form:input path="name"/>
<form:input path="password"/>
<form:input path="confirm-password"/>
</form:form>
This form generates error because there is no confirm-password field in User.class. I could of course add confirm-password field as #Transient to User.class, but what if I would like to add captcha field to my form. Is there a different way to add additional field to form?
It is not a good practice to use your models as form entities. You should have a bean or form class to get the data from the view and another for the model.
Reason is that they have different responsibilities thus needing to to be mapped to different classes. They are often very similar, but that separation promotes a cleaner coding and avoids security breaches, as a user could try to use your model variables from the view by using a request tamperer for example(like fire bug).
These small differences between them like the one you listed above justify the creation of another class.

Resources