how to display data dynamically on html page via jsp session - java

I have text area that is in bullet format and i want to display that data in html in bullet format via session.
so how to send that data ?? every user data contain and length is different for example ( 1 user use 3 bullets points ans 2 user use 5 bullet points ) how to send that dynamic data on html page and Display. DATABASE IS NOT USED ..

Identify and parse bullet points from each text area(lets say post)
class BulletPoint{
String content;
public BulletPoint(String content){
super();
this.content=content;
}
//put public getters and setters here
}
class Post{
List<BulletPoint> bulletPoints=new ArrayList<>();
//put public getters and setters here
}
#WebServlet("/posts")
class DisplayPostServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
//parse and prepare text area contents to list
//for each text area
//new Post p
//create bulletin list for post
//set bulletins to post
//end for
//simple example
List<Post> posts=new ArrayList<>();
for(int i=1;i<5;i++){
Post newPost=new Post();
for(int j=1;j<=i;j++){
Bulletin bulletin=new Bulletin("bulletin content"+j);
newPost.getBulletins().add(bulletin);
}
posts.add(newPost);
}
//add posts in request scope, and forward to jsp page
request.setAttribute("posts",posts);
request.getRequestDispatcher("/displayPosts.jsp").forward(request, response);
}
}
displayPosts.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<c:forEach var="singlePost" items="${posts}" varStatus="loopIndex">
<ul> Post ${loopIndex}
<c:forEach var="singleBulletin" items="${singlePost.bulletins}">
<li><c:out value="${singleBulletin.content}"/>
</li>
</c:forEach>
</ul>
</c:forEach>
</div>
</body>
</html>

Related

Should l make Spring Model class with one field?

I don't know should i make class with only one field which l will use as #ModelAttribute to get data from jsp? for example:
public class Age {
private int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}}
And then using spring mvc form tag to fill this ModuleAttribute
<form:form action="processForm" modelAttribute="age">
<form:input path="number"/>
</form:form>
First of all, you need to create a controller :
#Controller
public class AgeController {
// this is to create an instance of Age and set in the model.
#RequestMapping("showForm")
public String showForm(Model model) {
model.addAttribute("age", new Age());
return "form"; // return form page.
}
// this is to print the age in the display page.
#RequestMapping("processForm")
public String processForm(#ModelAttribute("age") Age age) {
return "display"; // return display page where you will display the data populated in the form page.
}
}
Now, form page should look like :
<%#taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<!-- When you enter the data here, Spring will set the data in the Age bean by calling respective setter of the data members -->
<body>
<form:form action="processForm" modelAttribute="age">
Enter an age : <form:input path="number" />
<input type="submit" value="Submit" />
</form:form>
</body>
</html>
Now, display page should look like :
<%#taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<body>
The age is : ${age.number} <!-- Here getter is called internally -->
</body>
</html>
On clicking the submit, the display page will show the data.

Why my web application does not redirect correctly?

I am trying to pass an attribute from a java servlet to jsp and write this attribute on jsp file. However it does not redirect to jsp file url but it writes the content of the jsp file. Here is my related codes:
Control.java:
#WebServlet("/Control")
public class Control extends HttpServlet{
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Key key = MacProvider.generateKey();
long time = System.currentTimeMillis();
try{
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, key)
.setSubject("username")
.setIssuedAt(new Date(time))
.setExpiration(new Date(time+6000000))
.claim("password","password")
.compact();
req.setAttribute("jwt", jwt);
req.getRequestDispatcher("/Home.jsp").forward(req,resp);
}catch (Exception e){
e.printStackTrace();
}
}
}
Home.jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
${jwt}
</body>
</html>
Here, browser stays on http://localhost:8080/Control but it writes the content of Home.jsp file which is just a java web token result string.
2) My second question is when I tryed to store this jwt result string in browser local storage and then write it in jsp file in order to check if it stored in browser or not. But it does not prints anything. To do this, I just changed the Home.jsp file as follow:
(I took both of the code snippets from here)
Home.jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<script>
localStorage.setItem("jwt", ${jwt});
console.log(localStorage.getItem("jwt"));
var jjwt = localStorage.getItem("jwt");
document.write(jjwt);
</script>
</body>
</html>
Another try:
<html>
<head>
<script>
function myFunction() {
localStorage.setItem("jwt", ${jwt});
console.log(localStorage.getItem("jwt"));
var jjwt = localStorage.getItem("jwt");
document.getElementById("myText").innerHTML = jjwt;
}
</script>
</head>
<body onload="myFunction()">
<span id="myText"></span>
</body>
</html>
Where am I doing wrong?
1) When you use RequestDispatcher.forward(request,response), your servlet will still have control but your jsp page will be loaded so this is nothing to worry about.
If you want your browser URL to show your JSP page URL, do response.sendRedirect("URL TO LOAD");
2)Since you are using JSP, try accessing the request variables like below and print it
<% String jwt = (String) request.getAttribute("jwt");%>
We need to set it as
localStorage.setItem('jwt', <%=jwt%>);

Passing Java object from JSP to Servlet [duplicate]

This question already has answers here:
Passing an object from JSP page back to Servlet
(3 answers)
Closed 6 years ago.
I have one Java Web Application.
My User_Objects class is given below
public class User_Objects {
public String firstName;
public String middleName;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
}
I forward request with my Java User_Objects to JSP with using following code
User_Objects fillObj = fillData(request);
request.setAttribute("reqObj", fillObj);
RequestDispatcher view = request.getRequestDispatcher("/organization.jsp");
view.forward(request, response);
public User_Objects fillData(HttpServletRequest request) {
User_Objects fillObj = new User_Objects();
try {
fillObj.setFirstName(request.getParameter("txtFirstname"));
} catch (Exception e) {
}
try {
fillObj.setMiddleName(request.getParameter("txtMiddlename"));
} catch (Exception e) {
}
return fillObj;
}
I successfully receive this Object into my JSP form. But I want to send this Object again to the Servlet and When I click on Submit button on my JSP form and try to get this Object into my Servlet using below code
User_Objects obj = (User_Objects) request.getAttribute("reqObj");
request.getAttribute("reqObj") gives me null
My JSP form code is given below
<%# page import="otn.aitc.io.User_Objects" %>
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Organization</title>
<link rel="stylesheet" href="css/jquery-ui.css">
<script src="js/jquery-1.12.4.js"></script>
<script src="js/jquery-ui.js"></script>
<script>
$(function() {
var reqObj = '${reqObj}';
var reqStatus = '${orgStatus}';
var orgJson = '${reqOrgJson}';
orgJson = orgJson.replace("/", "'");
if(reqStatus != "" || orgJson != "") {
if(reqStatus == "false") {
document.getElementById("lblError").style.display = '';
}
else {
document.getElementById("lblError").style.display = 'none';
}
var availableTutorials = [];
if(orgJson != "") {
var parsed = JSON.parse(orgJson);
for(var x in orgJson) {
if(parsed[x] != undefined) {
availableTutorials.push(parsed[x]);
}
}
}
$("#txtOrgName").autocomplete({source: availableTutorials});
}
else {
window.location.href = "index.jsp";
}
});
function validateOrg() {
var orgName = document.getElementById("txtOrgName");
if (orgName.value.trim().length == 0) {
alert("Enter Org Name");
return false;
}
}
</script>
</head>
<body>
<form name="orgname" action="org_name" method="post">
<table align="center">
<tr align="center">
<td colspan="4"><img src="images/logo.jpg" /></td>
</tr>
<tr>
<td>Organization :</td>
<td><input type="text" id="txtOrgName" name="txtOrgName" /><label style="color: red;">*</label></td>
</tr>
<tr>
<td align="center" colspan=2><br/><input type="submit" name="btnOrgName" id="btnOrgName"
value="Validate" onclick="return validateOrg();" /></td>
</tr>
</table>
<p align="center"><label id="lblError" style="color: red;">Error Message.</label></p>
</form>
</body>
</html>
I am using Java with Eclipse.
Don't mix and match the different execution scopes.
The serlvet and the JSP page are executed on server side (actually the JSP page is compiled to a servlet, too). Once the HTTP request is finished all request based objects are discarded, including the request attributes.
In the end it is a templating engine producing HTML text.
This HTML text (with embedded JavaScript) is executed by the client's browser. This execution scope is totally different to your server request scope, which has created this HTML page. So in your JavaScript code all the Java objects used to create that page on server side are unknown and unaccessable.
So you have two alternatives.
While creating the HTML include enough information to recreate your server side object. E.g. if you have a Person object with name and age attributes, you can include name and age as hidden form fields. After submitting the form you can recreate the Person object with the hidden field values coming in as request parameters.
Pro: Simple to implement.
Con: Only feasable for small data. Data is exposed to the client and can be manipulated.
Store the object on server side inside the session.
Pro: Data is not exposed to the client.
Con: Implementation more complex because of possible concurrent access to the session variables (browser can do multiple requests for the same session at the same time).

Forward from JSP to another JSP without using a servlet between them?

I have a JSP page :
employee5_searchByName.jsp
<%#page import="java.util.Iterator"%>
<%#page import="java.util.List"%>
<!-- EMPLOYEE wants to search items by their name -->
<!DOCTYPE html>
<html>
<head>
<title>Employee - Search for items by name</title>
<link rel="stylesheet"
href="./css/styles.css"
type="text/css"/>
<link rel="stylesheet" type="text/css" href="css/jquery.autocomplete.css" />
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1");
</script>
<script src="js/jquery.autocomplete.js"></script>
<style>
input
{
font-size: 120%;
}
</style>
</head>
<body>
<h1>Employee - Search for items by name</h1>
<h1>
Search for items by name
</h1>
<fieldset>
<legend>Please enter the item's name :</legend>
<form action="Employee5_After">
Item's name : <input type="text" name="prod_name" id="myProduct"><br>
<script>
$("#myProduct").autocomplete("autocompleteFromDb.jsp");
</script>
<input type="submit" value="Register">
</form>
</fieldset>
</body></html>
It forwards to this servlet :
Employee5_After
package controller.employee;
/**
* Retrieve the record of a given product by its name
* using hibernate
* #author X
*
*/
#WebServlet("/Employee5_After")
public class Employee5_After extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
// grab the product's name that the user entered
String productName = request.getParameter("prod_name");
// create DB instance
DatabaseInventory inventory = new DatabaseInventory();
// get the details
String details = inventory.getProductDetailsByName(productName);
HttpSession session = request.getSession();
// forward answer to JSP
synchronized(session)
{
if (details != null) // then the product has been found
{
session.setAttribute("foundProd", details);
String addressPath = "/WEB-INF/results/employee/employeeResult5.jsp";
RequestDispatcher dispatcher = request.getRequestDispatcher(addressPath);
dispatcher.forward(request, response);
}
}
}
}
That servlet is doing his stuff , and then forwards to a 2nd JSP ,called :
employeeResult5.jsp
<!-- Employee - get a description of a product by its name -->
<!DOCTYPE html>
<html>
<head><title>The details for the product you requested are below</title>
<link rel="stylesheet"
href="./css/styles.css"
type="text/css"/>
</head>
<body>
<h1>Here are the details from the product you request :</h1>
<h2>${foundProd}</h2>
<h1>We wish you well - bye bye!</h1>
<fieldset>
<legend>Go back to Employee's web-page</legend>
<form action="blablabla">
Press here to continue
</form>
</fieldset>
</body></html>
I guess that I can use the <% and %> in the JSP to do the logic side of the servlet (contacting to DB and retrieve data) . How can I avoid using a servlet in between , and just pass the data from one JSP to another JSP ?
You can use the request.redirect(URL) method to do it.
Or you can use request. forward(req, resp).
See example
Separate the business logic from the font end, there is no need to redirect to an intermediate servlet. The best practice is to put the business logic in a separate class and instantiate that class in the destination page. Here is one example:
mainPage.jsp - create the page similar to your employee5_searchByName.jsp. Now this page posts the data you enter.
Create a backing class called - dbData.java (DatabaseInventory in your case)- put all your database query here and functions to retrieve what your want. A function like public String searchText(String param) (similar to getProductDetailsByName(productName)) which will essentially fetch your search results from database.
Now the most important part - Instantiate this class in your destination SearchResults.jsp page and show whatever data you get in a manner similar to this:
<%#page import="mysource.dbData"%>
<%
searchParam = request.getParameter("searchStr");
dbData data = new dbData();
String result = data.searchText(searchParam);
%>
<HTML>
<BODY>
The result is: <% out.print(result); %>
</BODY>
</HTML>
The industry standard is to follow an MVC Architecture. Following that will create applications which are clear to understand and easy to maintain.
Try this code to forward with parameteres
<jsp:forward page="URL">
<jsp:param nama="param1" value="hello"/>
<jsp:param nama="param2" value="hello2"/>
<jsp:param nama="param3" value="hello3"/>
<jsp:param nama="param4" value="hello4"/>
.
........... and so on
</jsp:forward

Spring MVC and form binding : how to remove an item from a List?

I have a Person model attribute that contains a list of emails.
I've created some JavaScript code that deletes elements from an HTML list of emails. This is pure JavaScript client side code, no AJAX call.
After submitting, I don't understand why I get all the emails in the corresponding #Controller method, even the ones that were deleted in the HTML.
Can anyone please explain?
JSP
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
<link rel="stylesheet" href="<c:url value="/styles/resume.css"/>" type="text/css"></link>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"></link>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script src="/resume/js/jquery.editable-1.0.1.js"></script>
<title>Resumes manager</title>
<script>
$(document).ready(function() {
$('.trash').click(function() {
$(this.parentNode).remove();
});
});
</script>
</head>
<body>
<h1>Personal data</h1>
<form:form modelAttribute="person" action="/resume/person/edit/save" id="personForm" method="post" >
<table>
<tr>
<td>Email addresses:</td>
<td colspan="4">
<ol id="emails">
<c:forEach items="${person.emails}" varStatus="status">
<li><form:hidden path="emails[${status.index}].order" class="emailsDisplayOrder"></form:hidden><form:input path="emails[${status.index}].label"></form:input><form:input type="email" path="emails[${status.index}].value"></form:input><input type="image" src="/resume/images/trash.png" class="trash" value="${status.index}"></input></li>
</c:forEach>
</ol>
</td>
</tr>
</table>
</form:form>
</body>
</html>
Controller
#Controller
#SessionAttributes(types={Person.class}, value={"person"})
public class PersonController {
private final static String PERSON_VIEW_NAME = "person-form";
private ResumeManager resumeManager;
#Autowired()
public PersonController(ResumeManager resume) {
this.resumeManager = resume;
}
#InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
#RequestMapping(value="/person/edit/save")
public String save(#ModelAttribute(value="person") Person p, BindingResult result, SessionStatus status) {
new PersonValidator().validate(p, result);
Collections.sort(p.getEmails()); //this collection still contains client-side dropped objects
this.resumeManager.savePerson(p);
return PERSON_VIEW_NAME;
}
}
Explanation
When you load a page with <form:form modelAttribute="person" ...>, there are two cases :
case 1 : if person doesn't exist, it creates an empty Person
case 2 : if person already exists, it uses it
In all cases, when a page is loaded, there is an existing person.
When you submit a form, Spring MVC updates this existing person only with the submitted information.
So in case 1, if you submit email 1, 2, 3 and 4, Spring MVC will add 4 emails to the empty person. No problem for you in this case.
But in case 2 (for example when you edit an existing person in session), if you submit email 1 and 2, but person has already 4 emails, then Spring MVC will just replace email 1 and 2. Email 3 and 4 still exist.
A possible solution
Probably not the best one, but it should work.
Add a remove boolean to the Email class :
...
public class Email {
...
private boolean remove; // Set this flag to true to indicate that
// you want to remove the person.
...
}
In the save method of your controller, remove the emails that have remove set to true.
Finally, in your JSP, add this hidden field :
<form:hidden path="emails[${status.index}].remove" />
And tell your Javascript to set the input value to true when the user clicks to delete the email.
Alternate solution to Jerome Dalbert one
Jerome's solution should work (thanks again for clear answer and solution), but I didn't want to modify business model.
So here is the way I found out: mark HTML elements to remove using java-script and actually remove it using ajax calls at form submit (I initially avoided ajax to keep model unchanged until user submits, but this solutions preserves that requirement).
JSP:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%# taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta>
<link rel="stylesheet" href="<c:url value="/styles/resume.css"/>" type="text/css"></link>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"></link>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script src="/resume/js/jquery.editable-1.0.1.js"></script>
<title>Resumes manager</title>
<script>
$('.sortable').sortable({
update: function(event,ui) {
var liElements = this.getElementsByTagName('li');
$(liElements).each(function(i, liElement) {
var orderElements = liElement.getElementsByClassName('order');
$(orderElements).each(function (j, orderElement) {
orderElement.value = i;
});
});
}
});
$('.trashable').click(function() {
$(this.parentNode.childNodes).each(function(index, element) {
if(element.src.match(/trash.png/) != null) {
element.src = '/resume/images/back.png';
this.parentNode.className = 'trashed';
} else if(element.src.match(/back.png/) != null) {
element.src = '/resume/images/trash.png';
this.parentNode.className = '';
} else {
element.disabled = !element.disabled;
}
});
});
function trash(element) {
var sfx = element.alt;
var lnk = ('/resume/person/edit/').concat(sfx);
$.ajax({
url: lnk
});
}
$('#personForm').submit(function() {
var trashed = $(this).find('.trashed');
$(trashed).each(function(index, element) {
var img = $(element).find('.trashable');
var tmp = $(img)[0];
trash(tmp);
});
});
});
</script>
</head>
<body>
<h1>Personal data</h1>
<form:form modelAttribute="person" action="/resume/person/edit/save" id="personForm" method="post" >
<table>
<tr>
<td>Email addresses:</td>
<td colspan="4">
<ol class="sortable">
<c:forEach items="${person.emails}" varStatus="status">
<li><form:hidden path="emails[${status.index}].order" class="order"></form:hidden><form:input path="emails[${status.index}].label"></form:input><form:input type="email" path="emails[${status.index}].value"></form:input><img src="/resume/images/trash.png" class="trashable" alt="dropEmail/${person.emails[status.index].id}"></img></li>
</c:forEach>
</ol>
</td>
</tr>
<tr><td colspan="5"><form:button name="save" value="${person.id}">${person.id == 0 ? 'save' : 'update'}</form:button></td></tr>
</table>
</form:form>
</body>
</html>
Controller:
#Controller
#SessionAttributes(types={Person.class}, value={"person"})
public class PersonController {
private final static String PERSON_VIEW_NAME = "person-form";
private ResumeManager resumeManager;
#Autowired()
public PersonController(ResumeManager resume) {
this.resumeManager = resume;
}
#InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
#RequestMapping(value="/person/edit/{id}")
public String edit(#PathVariable("id") long personId, Model model) {
Person p = this.resumeManager.getPersonById(personId);
if(p != null) {
model.addAttribute("person", p);
return PERSON_VIEW_NAME;
} else {
return "redirect:/";
}
}
#RequestMapping(value="/person/edit/save")
public String save(#ModelAttribute(value="person") Person p, BindingResult result, SessionStatus status) {
new PersonValidator().validate(p, result);
Collections.sort(p.getEmails());
this.resumeManager.savePerson(p);
return PERSON_VIEW_NAME;
}
#RequestMapping(value="/person/edit/dropEmail/{id}")
#ResponseBody
public void dropEmail(#ModelAttribute(value="person") Person p, #PathVariable("id") long id) {
int i = 0;
for(Email e : p.getEmails()) {
if(e.getId() == id) {
p.getEmails().remove(i);
break;
}
i++;
}
}
}

Categories