JSF- i login and when i navigate it automathically logout the session [duplicate] - session

This question already has answers here:
Difference between h:button and h:commandButton
(5 answers)
Closed 6 years ago.
Hello i am working with JSF2 and i am having some trouble with the session.
My problem is that i login and the user name appears like its logged but when i navigate to other page the name does not appear anymore. This started happening when i make the logout option. I have the login and logout methods in the same controller. And the text where its shows the name of the user and logout button is a facelet template, because i wanted it to be shown in all the pages that have that template.
this is the code for the login and the logout:
public String login(){
try {
user = ejb.Autenticar(this.mail, this.pass);
if(user != null){
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> sessionMap = externalContext.getSessionMap();
sessionMap.put("USER", user);
return "LoginOK";
}
} catch (Exception e) {
return null;
}
return null;
}
public String logout(){
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return "LoginView";
}
This is the code of the facelet template (The user name and the logout button are in the divSessionUser):
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet name="./css/default.css"/>
<h:outputStylesheet name="./css/cssLayout.css"/>
<title>Facelets Template</title>
</h:head>
<h:body>
<div id="divSessionUser">
<span>
<b>Session user: </b>
<p:outputLabel value="#{loginControlador.user.name}"/>
</span>
<p:button value="Logout" outcome="#{loginControlador.logout()}"/>
</div>
<div id="top" class="top">
<h:graphicImage library="images" name="header1.png" styleClass="topImage"></h:graphicImage>
</div>
<div>
<div id="left">
<ul>
<li> <h:link outcome="indexView" value="Home" /></li>
<li> <h:link outcome="registroCView" value="Register Comunity" /></li>
<li> <h:link outcome="LoginView" value="Login" /></li>
<li> <h:link outcome="registroUserView" value="Register User" /></li>
</ul>
</div>
<div id="content" class="left_content">
<ui:insert name="content">Content</ui:insert>
</div>
</div>
</h:body>

I dont know if this is the correct way of doing this, but it got solved by inserting the div=divSessionUser of the facelet template inside a form and change the button for commandButton.
Hope it helps anyone, and if someone have a better answer please tell us!!!
Thanks!

Related

Search page in spring mvc doesn't work

I Have created simple mvc CRUD. All works fine except search page.
Im getting errorr as follows:
HTTP Status 500 - Request processing failed; nested exception is org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0
Controller page is:
#RequestMapping(value="/search")
public ModelAndView search(){
return new ModelAndView("search","command", new Emp());
}
#RequestMapping(value="/jsp/searchemp",method = RequestMethod.POST)
public ModelAndView search1(#ModelAttribute("name") Emp emp){
String name = null;
name = dao.searchname(name);
return new ModelAndView("searchemp","name",name);
}
Search.jsp:
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>z
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
label {
text-align: right;
clear: both;
float:left;
margin-right:15px;
}
.box{background-color: #e1e8f0;}
body{background:#f0eceb;}
</style>
</head>
<body>
<div style=" left: 30%; top: 25%; position: absolute;">
<div class="col-sm-12 col-sm-offset-3 box " >
<center> <h1>Add New Employee</h1> </center>
<form method="post" action="jsp/searchemp/" >
<div class="form-group"> <div class="col-xs-7">
<label ><h5>Name :</h5></label>
<input name="name" class="form-control" placeholder="Enter Name of the employee" />
<button type="submit" value="Save" class="btn btn-primary btn-lg">Search</button>
</div></div>
</form>
</div>
</div>
</body>
</head>
Searchemp.jsp:
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h1>Employees List</h1>
<table class="table table-hover" border="1" width="70%" cellpadding="2">
<thead>
<tr><th>Id</th><th>Name</th><th>Salary</th><th>Designation</th><th>Edit</th><th>Delete</th></tr></thead>
<tbody><tr>
<td>${String.id}</td>
<td>${String.name}</td>
<td>${emp.salary}</td>
<td>${emp.designation}</td>
<td>Edit</td>
<td>Delete</td>
</tr> </tbody>
</table>
<br/>
Add New Employee
jdbctemplate query:
public String searchname(String name) {
String query = "select * from Emp99 where name=?";
Object[] inputs = new Object[] {name};
String empName = template.queryForObject(query, inputs, String.class);
return empName;
}
Dont know what goes wrong.
help me.
in order for jsp to consume an bean , your controller method should return data,in your jsp you are trying to utilize
{String.id} and {emp.id} which is never passed from the controller method search1.so you need to add your beans to a model and
return the page like this.
#RequestMapping(value="/jsp/searchemp",method = RequestMethod.POST)
public String search1(#ModelAttribute("name") Emp emp,Model model){
model.addAttribute("emp",emp); //passing the model name and the bean ,
//model.addAttribute("name",anotherBean); //you can add many attributes as you wish.
return "searchemp";
}
now inside the searchemp.jsp you can utilize the emp bean like this.
{emp.id}
remove the {String.id} part. inside the searchemp.jsp which will not work.

Thymeleaf + spring dynamic replace

Is it possible to create a dynamic replace in Thymeleaf?
I have the following controller:
#Controller
public class LoginController {
#RequestMapping("/login")
public String getLogin(Model model){
model.addAttribute("template","login");
return "index";
}
}
And the following view:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head></head>
<body>
<div th:replace="fragments/${template} :: ${template}"></div>
</body>
</html>
And i'm getting the following error:
Error resolving template "fragments/${template}", template might not exist or might not be accessible by any of the configured Template Resolvers
UPDATE
I tried to preprocess my variables like this:
<div th:replace="fragments/${__#{${template}}__} :: ${__#{${template}}__}"></div>
How ever now ${template} is getting replaced with login i have the following error now:
Exception evaluating SpringEL expression: "??login_en_US??"
Although Joe Essey's solution is working as well i solved with following code:
<div th:replace="#{'fragments/' + ${template}} :: ${template}"></div>
I believe the appropriate method to manage this behavior in thymeleaf is to use layout:fragment tags. Please correct me if I'm wrong. Here is a simple example of my layout page, and the login page which is 'dynamically' loaded:
layout.html
<html xmlns:layout="http://www.w3.org/1999/xhtml" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<title layout:title-pattern="$DECORATOR_TITLE - $CONTENT_TITLE">Layout</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
</head>
<body>
<div>
<div class="app-container">
<div th:fragment="content">
</div>
</div>
</div>
<div th:fragment="script"></div>
</body>
</html>
Then, when login gets loaded, it replaces the th:fragment div with the associated div in the html view which matches the string returned by the controller method, in this case login.html:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.w3.org/1999/xhtml"
layout:decorator="layout">
<head>
<title>Login</title>
</head>
<body>
<div th:fragment="content">
<form th:action="#{/login}" method="post">
<div><label> User Name : <input type="text" name="username"/> </label></div>
<div><label> Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</div>
</body>
</html>
Now, if you want to load another fragment conditionally, the approach I take is to add replace tags with th:if cases. Here's an example of a Form that displays different questions based on an attribute of the current user:
<div th:if="${foo.type)} == 'type_1'">
<div th:replace="fragments/custom-questions :: type-1-checkboxes"></div>
</div>
<div th:if="${foo.type} == 'type_2'">
<div th:replace="fragments/custom-questions :: type-2-checkboxes"></div>
</div>
Then the associated div gets loaded from the file custom-questions.html:
<div th:fragment="type-1-checkboxes">
//stuff
</div>
<div th:fragment="type-2-checkboxes">
//stuff
</div>
I am just encountering this issue (this is my first time with thymeleaf/spring). This is what solved it for me:
<div class="col-md-12" th:include="__${template}__ :: body" ...
In Thymeleaf 3.0, the following solution has worked for me:
<div th:replace="('fragments/' + ${template}) :: (${template})">
(Note however, that I use it with fixed name of the fragment and dynamic name of the template, so the parantheses around :: (${template}) might be optional.)
The solution is inspired by documentation for Thymeleaf in https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#fragment-specification-syntax
Both templatename and selector in the above examples can be fully-featured expressions (even conditionals!) like:
<div th:insert="footer :: (${user.isAdmin}? #{footer.admin} : #{footer.normaluser})"></div>
Note again how the surrounding ~{...} envelope is optional in th:insert/th:replace
<div th:insert=“${subpage}::fragementName”>
Just change subpage names and you will dynamic behaviour in thymleaf

spring MVC two forms with one controller

Here is the Jsp file. I want a controller that handles both the forms in just one page. is there a way to handle this form? I create a controller but it cannot bind the forms.
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<!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=UTF-8">
<title>Welcome to Spring Web MVC project</title>
</head>
<body>
<form:form method="POST" modelAttribute="logindetails" name ="LoginForm" autocomplete="off" >
Dept_Code :
<form:input path="departmentcode"/>
Dept_name
<form:input path="departmentname" placeholder="name" />
<button type="submit" >Save</button>
</form:form><br/>
<form:form method="POST" modelAttribute="emp_details" name = "emp_Form" autocomplete="off" >
Emp_Code :
<form:input path="emp_code"/>
Emp_Coded
<form:input path="Emp_coded" placeholder="coded" />
DDO_Desc
<form:input path="ddo_desc" placeholder="DDO_DESC" />
<button type="submit" >Save</button>
</form:form>
</body>
</html>
Here is my controller Class if you need in case. but I only bind for one form.
#Controller
public class DepartmentController {
#Autowired
Deptservices deptservices;
#RequestMapping(value="index", method= RequestMethod.GET)
public ModelAndView insert(#ModelAttribute("logindetails") Department insert)
{
ModelAndView mav=new ModelAndView("index");
return mav;
}
#RequestMapping(value="index", method= RequestMethod.POST)
public ModelAndView insertPost(#ModelAttribute("logindetails") Department insert)
{
ModelAndView mav=new ModelAndView("index");
deptservices.insert(insert);
return mav;
}
}
You have bind the model with name logindetails.
So, change modelAttribute="emp_details" to modelAttribute="logindetails" in second form.
take a view model like
EmployeeViewMOdel{
logindetails
emp_details
}
model.addAttribute("EmployeeViewMOdelObj",EmployeeViewMOdel);
<form:form method="POST" modelAttribute="*EmployeeViewMOdelObj*" name ="LoginForm" autocomplete="off" >
<form:form method="POST" modelAttribute="EmployeeViewMOdelObj" name = "emp_Form" autocomplete="off" >
bind this object to both the forms and then single controller may handle your request.

The request sent by the client was syntactically incorrect +spring

I searched for this problem and as I got it has some problems with naming conflicts, but again I could not find the reason. I would appreciate the helps. following is the line in the .jsp which calls the controller:
<td>
<a href="message/createMessage">
Reply
</a>
<input type="hidden" name="receiver" value="${message.fromUser}">
</td>
${message.fromUser} gets the required property from the model. I am sure it is not the reason for the problem because of other link in this page which works and uses the same model. The controller is as follow:
#Controller
#RequestMapping("/message")
public class MessageController
{
#RequestMapping("createMessage")
public String createMessage(
#RequestParam("receiver") String receiver,
HttpSession session,
Model model)
{
try
{
MessageDAO mDao = new MessageDAO();
Message message = new Message();
String fromUser = (String) session.getAttribute("userName");
message.setFromUser(fromUser);
message.setUserName(receiver);
Message message2 = mDao.create(message);
model.addAttribute(message);
return "newMessage";
}
catch (Exception e)
{
model.addAttribute("message", "Can't create message!");
return "redirect:/"; // ?? should add a dialog box for error
}
}
}
Thank you for your help!
as an attempt to solve the problem and based on the first answer I tried to use url-rewriting. used #PathVariable("receiver") in my controller. still the same problem. I have added the full revised jsp here: error happens when I click reply link for a message.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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>Insert title here</title>
</head>
<body>
<h1>welcome ${sessionScope.user.userName}</h1>
<form:form method="POST" action="message/deleteMessage">
<table border="1">
<tr>
<th>Message ID</th>
<th>From User</th>
<th>Message</th>
<th>Date</th>
<th>Reply to User</th>
<th>Delete</th>
</tr>
<c:forEach items="${messages}" var="message" >
<tr>
<td>${message.messageID}</td>
<td>${message.fromUser}</td>
<td>${message.message}</td>
<td>${message.messageDate}</td>
<td>Reply</td>
<td><input type="checkbox" name="delete" value="${message.messageID}"> </td>
</tr>
</c:forEach>
<tr><td colspan="6"><input type="submit" value="Delete selected messages"></td></tr>
</table>
</form:form>
In your "form" you have a plain html hyperlink that doesn't do any form submit(so the value of the hidden field is never being sent.
So you need to declare a <FORM action= 'message/createMessage' > element.
Then you need to either submit the form with AJAX or create a submit button. Another way is to pass receiver value manually by appending the value of the form createMessage?receiver=someValue(I added this as example I don't think it's a recommended way, everything has its pros n' cons anyway).
So there are many ways to pass the parameter.
See http://www.w3.org/TR/html401/interact/forms.html

Unable to add events after AJAX load using jQuery

I have a web page on which I use jQuery's AJAX to load new elements into a div. This part of my page works fine.
I now want to add a similar event to these newly-added elements. To do this I planned to use jQuery's .live() method but nothing appears to happen.
So I initially start with this
<div id="change-agent-list" class="tooltip">
<div class="top"></div>
<div class="middle"></div>
<div class="bottom"></div>
</div>
Into .middle I asynchronously load markup that looks like this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title></title>
</head>
<body>
<form name="main" method="post" action="/ils/agent-selector/" id="main">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTQ1MTc3ODM4NGRkg9mLyLiGNVcP/ppO9C/IbwpxdwI=" />
</div>
<ul id="content_0_agentsUL">
<li>
Agent 1
</li>
<li>
Agent 2
</li>
<li>
Agent 3
</li>
</ul>
<div id="agent-details"></div>
</form>
</body>
</html>
When the page initially loads I use this script - my intention is to add a click handler for each of the .agent-name elements that are asynchronously added later.
$j(document).ready(function () {
$j(".agent-name").live("click", function() {
var agentDetails = $j(".agent-details");
var loadingContent = '<div id="ajax-load"><img src="/sitecore/__/_images/global/ajax-load.gif" alt="AJAX content loading" /></div>';
agentDetails.show();
agentDetails.empty().html(loadingContent);
var modalURL = $j(".agent-name").attr("href");
agentDetails.load(modalURL);*/
return false;
});
});
The problem is that no events are being bound to the .agent-name elements. I've tried replacing all the inner script with a simple alert() so that I can see if any events are being bound to the .agent-name elements, and I can't get this alert() to display.
So in other words, no events are being bound to my .agent-name elements.
Even if I move the agent-name class to the list elements and change the jQuery to simply
$j(".agent-name").live("click", function() {
alert('1');
});
I still get nothing when I click on the elements.
Can anyone explain why, or how I fix this so that I can late-bind events to elements created in an AJAX callback?
I eventually solved this by using jQuery's on instead of "live".
You can only have one #agent-name because IDs are unique. You can just use $('#agents .link') since you already have a class on each anchor.
Not sure if this is helpful, but this works for me:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$(".agent-name").live("click", function() {
alert("click");
return false;
});
});
</script>
</head>
<body>
<form name="main" method="post" action="/ils/agent-selector/" id="main">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTQ1MTc3ODM4NGRkg9mLyLiGNVcP/ppO9C/IbwpxdwI=" />
</div>
<ul id="content_0_agentsUL">
<li>
Agent 1
</li>
<li>
Agent 2
</li>
<li>
Agent 3
</li>
</ul>
<div id="agent-details"></div>
</form>
</body>
</html>

Resources