How to use two java bean to display data in a jsp - spring

I want to display user's detail in a jsp. user's email, name is in one bean. which i am getting in a PagedListHolder. now i need date too which is in another bean . how can i add this date to PagedListHolder. i am using spring mvc framework
public String listUsers(Map<String, Object> map, #RequestParam(value="p", required=false) Integer p) {
PagedListHolder pagedListHolder = new PagedListHolder(usersService.listUsers());
map.put("date11", userActivity.getLastSeen_time());
int page = p;
pagedListHolder.setPage(page);
int pageSize = 2;
pagedListHolder.setPageSize(pageSize);
map.put("pagedListHolder", pagedListHolder);
System.out.println(":::::::::");
return "userListView";
}
in jsp i am using it as
<c:forEach items="${pagedListHolder.pageList}" var="user">
<tr onmouseover="ChangeColor(this, true);" onmouseout="ChangeColor(this, false);" onclick="DoNav('${pageContext.request.contextPath}/secure/detailUserView');">
<td>${user.name}</td>
<td>${user.email}</td>
<td>`DATE`</td>
</tr>
</c:forEach>
in jsp in place of DATE i need to display date which is in date bean

If the pagedListHolder stored as "pagedListHolder" in the map is available using ${pagedListHolder}, then the date, stored as "date11" in the map, must also be available using ${date11}.
You can format it using <fmt:formatDate value="{date11}"/>.

Related

Spring boot and BigDecimal or Double serialization problem

İ can not handle BigDecimal initialization properly , i have an entity which has a BigDecimal field like this:
#Entity
public class Menu{
...
#Digits(integer=6, fraction=2)
private BigDecimal price;
...
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
...
other generated getters and setters toString etc.
...
}
And in frontend i use thymeleaf, in html form (which adds and updates new menu item) i have this input for Big Decimal value:
<div class="form-group">
<label for="price">Enter Price</label>
<input type="number" class="form-control" step="0.01" id="price" name="price" th:field="*{price}" placeholder="enter Price" value=" ">
</div>
And for restrict the user to enter more than 2 digit precision on price value, i have a js code like this:
$('#price').keypress(function (e) {
var character = String.fromCharCode(e.keyCode)
var newValue = this.value + character;
if (isNaN(newValue) || parseFloat(newValue) * 100 % 1 > 0) {
e.preventDefault();
return false;
}
});
The question is : when user enters 10.25 value in the form , thymeleaf renders it like 10.2499998.. . Even other rest endpoints returns this entity with value in json like 10.249999. But when i looked at my database (postgresql and offcourse i use jpa) this value seems just fine which is 10.25.
So i know when initializing new BigDecimal value the constructor must be like new BigDecimal("10.25") with string in parameter.But all i have is the default getters and setters and my controller is simple post controller for entity saving like this:
#PostMapping("/additem")
public String addItemPost(#ModelAttribute(value="menu") #Valid Menu menu,Model model,BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "addmenuitem";
}
this.menuService.saveMenuItem(menu);
return "redirect:/restaurant/menu";
}
The problem 2 is : I tried to change BigDecimal with Double value and after that, the input form takes value as we suggest and i see that value everywhere correctly.But if i write more digit after comma , the js function blocks me to write more than 2 digit but real value again becomes 10.2499999.. .
It must be something with spring's strategy of taking values from thymeleaf form, and than initialize those values into entity , but i never do that manually neighter couldn't debug it.
So ı don't know the problem is if my javascript function or my input form or the variable type.Please help.
Any help will be appreciated.
I found the problem and writing here if anyone encounter a problem like this.
My Problem was not in localhost , but occured on heroku.So i realized that in heroku postgresql db my BigDecimal columns did not updated and in localhost they were changing whenever i re-run because of jdbc table creation strategy choice.
I made the entity attribute Double and changed remote db columns to double precision than problem solved.

How to add ajax to dynamically created primefaces input fields

I want to create a page to allow users to update a mysql table. This table can be changed by client admins so I have to read the table schema and create fields on the fly. I got the basic code for doing that from How to create dynamic JSF form fields and the ajax code from How to add ajax validation to programmatically generated primefaces component.
To create a proof of concept page I use the following code (note, I'm using primefaces):
for (int idx = 1; idx < 3; idx++) {
UIInput input = new InputText();
input.setId("text" + idx);
ValueExpression targetExpression = facesContext.getApplication().getExpressionFactory().createValueExpression(facesContext.getELContext(), "#{viewMakeFields.value}", String.class);
input.setValueExpression("value", targetExpression);
AjaxBehavior ab = new AjaxBehavior();
ab.setAsync(true);
ab.setProcess("text"+idx);
input.addClientBehavior("blur", ab); // "change" doesn't work either
form.getChildren().add(input);
}
Then, in the getter and setter, I'm getting the component ID to identify which field is changed:
public static String getCallingComponentID() {
UIComponent component = UIComponent.getCurrentComponent(FacesContext.getCurrentInstance());
return component.getId();
}
public String getValue() {
String id = getCallingComponentID();
System.out.println("getValue " + id);
return text1;
}
public void setValue(String text1) {
String id = getCallingComponentID();
System.out.println("setValue " + id);
this.text1 = text1;
}
The ajax isn't firing and when I click the submit button I get (and I know mixing partial and full submits isn't good):
INFO: getValue text1
INFO: getValue text2
INFO: getValue text1
INFO: getValue text2
INFO: setValue j_id1
INFO: setValue j_id1
INFO: getValue text1
INFO: getValue text2
I see two possible solutions: get ajax working so that the component calling the setter has the correct id or get the form submit to identify which child is calling the setter. The former is preferable since I want to disable the save button until something has changed but I'm willing to accept the latter at this point. Any help would be much appreciated.
Turns out this code does work. Somewhere in my meandering the error changed and I didn't understand the significance of that. Replacing head with h:head in the xhtml file that I was adding the fields to makes ajax work.

Is this class thread safe: com.orionserver.http.OrionHttpJspPage

We use JDeveloper 10.1.3.4 to develop a web application. We deploy the application on OC4J running on linux. We put java code in the jsp page directly. In the jsp page, we have general java code, for example,
<% String invoice_id = ""; %>
Here the variable invoice_id is an instance variable in jsp. We also have tag such as and to handle database transactions. We have such a jsp called paymentApproved.jsp. This jsp is called by a third party gateway. In other words, the jsp is called from outside of our application. My question is, in such a scenario, is this jsp paymentApproved.jsp thread safe? I checked the translated jsp page, the class extends com.orionserver.http.OrionHttpJspPage, and the logic is in this method:
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException
Specifically, I am not sure whether an instance variable defined in such a jsp is thread safe while multiple requests coming in to call the page? Or is there anyway to test it? (I know it's a bad idea to put java code in jsp. But it's my boss's project, not mine. )Thanks
Jsp code:
<%# include file="mainHeader.jsp"%>
<%
String inv_id = "";
%>
<jbo:ApplicationModule id="AM_Payment" definition="test.AM_Payment" releasemode="Stateless" />
<jbo:DataSource id="dsinv" appid="AM_Payment" viewobject="InvoiceView1"/>
<%
SimpleDateFormat dtformat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat tmformat = new SimpleDateFormat("HH:mm:ss");
String invoicedateStr = dtformat.format(new java.util.Date());
oracle.jbo.domain.Date invoicedate = new oracle.jbo.domain.Date(invoicedateStr);
String invoicetime = tmformat.format(new java.util.Date());
inv_id = invoicedateStr+invoicetime;
%>
<BR><BR>
<table>
<tr><td>Invoice id: <%=inv_id%></td></tr>
</table>
<hr>
<%
long startTime = System.nanoTime();
int[] dummy = new int[10];
for (int i=0; i<999999999; i++) {
for (int j=0; j<10; j++) {
dummy[j] = i;
}
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
double seconds = (double)Math.round( (duration/1000000000.0d) *100.0d)/100.0d;
String sec = Double.toString(seconds);
%>
<table>
<tr><td>Invoice id: <%=inv_id%></td></tr>
<tr><td> </td></tr>
<tr><td>Process time: <%=sec%> seconds</td></tr>
</table>
<hr>
<jbo:ReleasePageResources releasemode="Stateless"/>
</body>
</html>
Leaf
<% String invoice_id = ""; %>
Here the variable invoice_id is an instance variable in jsp.
No, it's not. It's a local variable of the service method of the JSP.
is this jsp paymentApproved.jsp thread safe?
How coud we tell without seeing a single character of this JSP?
Putting Java code in a JSP is an extremely bad idea. Scriptlets shouldn't be used, for years and years. Use JSPs as pure view components, whose only role is to generate HTML markup from beans stored in te request by a controller written in Java.

How to populate Form from Spring dropdown when form is submitted

My code lists the data that I would like to see, but when I hit submit it fails to populate the backing form with exception below. How can I make the bindings work? The exception I get is of Mismatch type, trying to insert a String in List when expecting Objects. Which makes sense.
Example
<tr>
<td><form:select id="myTypes" path="myTypes" multiple="false">
<form:option value="NONE" label="--- Select ---" />
<form:options items="${form.myTypes}" itemValue="id" itemLabel="label"/>
</form:select>
</td>
<td><form:errors path="myTypes" cssClass="error" /></td>
This is how form looks like
public class MyForm {
List<MyType> myTypes;
public List<MyType> getMyTypes() {
return myTypes;
}
public void setMyTypes(List<MyType> myTypes) {
this.myTypes = myTypes;
}
}
And of course MyType has id and label.
Link to above sample code and exception below
HTTP Status 500 - Request processing failed; nested exception is org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'Form' on field 'myTypes': rejected value [8768743658734587345]; codes [typeMismatch.Form.myTypes,typeMismatch.myTypes,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [myForm.myTypes,myTypes]; arguments []; default message [myTypes]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'myTypes'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.x.x.MyTypeEntity] for property 'myTypes[0]': no matching editors or conversion strategy found]
Solution:
Make sure you are mapping to Single element and not to the list :)
It should be something like
<form:select path="someEntity[${status.index}].myType.id">
HTH
I think the problem is that Spring does not know how to convert the selected option value (which is a String posted towards your app as an HTTP parameter named "myTypes" when you submit the form) to a MyType object. You should configure a Formatter< MyType > and register it to the Spring FormatterRegistry (see Spring doc) to let Spring know how to convert the incoming String to a MyType object.
public class MyTypeFormatter implements Formatter<MyType> {
#Override
public MyType parse(String text, Locale locale) throws ParseException {
return myTypeService.getType(text); // for example
}
public String print(MyType t, Locale locale) {
return t.getId();// for example
};
}
By the way, if I may, since your dropdown list is not multiple, it means that you are going to select just one of the available MyType options. The path of the < form:select > should be named "myType" instead of "myTypes" and especially, it should refer to a MyType attribute within your Form object and not to a List< MyType > attribute. Maybe you should name your first list of available MyType objects "availableTypes" and create a second attribute named "selectedType" to bind the MyType object corresponding to the selected option on the GUI.

Use ResultSet object in JSP without JSTL

I want to pass my query's result i.e ResultSet to JSP just for the display as i am using MVC framework.
My Servlet Code:
Connection c=Connectivity.dbConnect();
PreparedStatement ps=c.prepareStatement("select role from login where userid=? and password=?");
ps.setString(1,userid);
ps.setString(2,pass);
ResultSet rs=ps.executeQuery();
if(rs.next())
{
if(rs.getString(1).equals("admin"))
{
ps=c.prepareStatement("select * from user where userid=?");
ps.setString(1,userid);
rs=ps.executeQuery();
Result r=ResultSupport.toResult(rs);
request.setAttribute("res",r);
rs.close();
c.close();
return mapping.findForward("us");//to User.jsp
}
}
I've used ResultSupport.toResult() to forward it to JSP (forwarded by 'us' mapping) but that requires JSTL code in JSP :
User.jsp -
<c:forEach var="data" items="${requestScope.res.rows}">
<h1>${data.userid}</h1>
<h2>${data.name}</h2>
<h2>${data.password}</h2>
<h2>${data.emailid}</h2>
</c:forEach>
Moreover if i directly pass ResultSet like request.setAttribute("ResultSet",rs); i wouldn't be able to close the connection in JSP.
This Code works fine but i do NOT want to use JSTL/EL or Lists , i want to use scriplets in JSP that can handle Result or ResultSet attribute from Servlet.
You can overcome your issue like this:
1) In your database manipulation class use a POJO to add in results from ResultSet.
Contacts myContact = new Contacts();
myContact.setOffice(rs.getString("office1"));
myContact.setMail(rs.getString("xx#xx.com"));
2) Then use a List to store your results
List<Contacts> myList = new ArrayList<Contacts>();
myList.add(myContact);
3) Pass the list to your request/session Object and close ResultSet/Connection there
request.setAttribute("LIST",myList);
rs.close();
conn.close()
4) In JSP get the List and iterate over it anyway you want
ArrayList<Contacts> myList = (ArrayList<Contacts>) request.getAttribute("LIST");
for(Contacts obj: myList){
out.print(obj.getMail());
....
....
}

Resources