I I have a form in my "login.html" and after I click the "login" button, this form will be submitted to my java back-end code. However, I don't know how to redirect my login page to the new page.
In the following code:
<script>
$(function() {
$('#ff').form({
url: "LoginServlet",
success:function(data){
$.messager.alert(data);
}
});
});
</script>
In the success part, my redirected page will show in this message window. But I want it jump to the page returned by the servlet.
This is my login.html code:
<!DOCTYPE html>
<html lang="en">
<head>
<script>
$(function() {
$('#ff').form({
url: "LoginServlet",
success:function(data){
$.messager.alert(data);
}
});
});
</script>
</head>
<body>
<form id="ff" role="form" method="post">
<div>
<h1>User Login</h1>
</div>
<div>
<input id="username" name="username" class="easyui-textbox" data-options="iconCls:'icon-man',iconWidth:30,iconAlign:'left',prompt:'Username'" style="width:100%;height:35px;" />
</div>
<div>
<input id="password" name="password" class="easyui-passwordbox" data-options="iconWidth:30,iconAlign:'left',prompt:'Password'" style="width:100%;height:35px;" />
</div>
<div>
Submit
</div>
<div>
<div style="display:inline;">
Register
</div>
</div>
</form>
</body>
</html>
This is my java servlet code:
#WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
String username = request.getParameter("username");
String password = request.getParameter("password");
IUserService userService = new UserServiceImpl();
User user = userService.login(username, password).get(0);
if (user != null) {
response.sendRedirect(request.getContextPath() + "/index.jsp");
} else {
}
}
}
You could try removing the Javascript function and calling directly the jsp using the form action.
So I would remove the following part
<script>
$(function() {
$('#ff').form({
url: "LoginServlet",
success:function(data){
$.messager.alert(data);
}
});
});
</script>
This part here needs to be removed because of the structure that you have. Most projects with JSP have this structure that you have.
You want in first step to take all the form parameters and to visit the url .../LoginServlet.
Then as you have structured your servlet it makes the authentication and if successful it sends a message to your browser and says: Please browser keep these headers in the http message but please visit another URL (index.jsp) to see what you wait for.
As you can see it's up to the client (aka browser) to move between different URL in order to be served.
That is why that simple Javascript function does not work as expected.
So a simple solution would be to make the call directly in the form action
<body>
<form id="ff" role="form" method="post" action="/LoginServlet">
....
If the authentication was not successful then I would serve an error page from my servlet.
if (user != null) {
response.sendRedirect(request.getContextPath() + "/index.jsp");
} else {
response.sendRedirect(request.getContextPath() + "/error.html");
}
Related
I have an HTML form for user login on a JSP document and I send the input of the user to a Servlet, check the password against a database then redirect the user to a new page if it's correct or show an error message on the page "Incorrect Password" of incorrect.
I want the error message to appear on the same page as the form just below the Password input field. I have tried the code below but it still redirects me to a new page where it displays only the "Incorrect Password" message.
Is there any other way on how to do it?
Thank you in advance.
//SERVLET CODE
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Some code to check if the password matches the one in the DB and redirects to another page.
} else {
String text = "Incorrect Password!";
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(text);
}
}
}
//JSP PAGE
<!DOCTYPE html>
<html>
<head>
<script>
$('#sButton').click(function() {
$.post('UserServlet', function(responseText) {
$('#msg').text(responseText);
});
});
</script>
<title>User Log in</title>
<%# include file="PageHeader.html" %>
</head>
<body>
<form action = "SomeServlet" method="POST">
<h3 >Enter detailsto Sign In</h3><br>
Email: <input type="text" name="email" required><br>
Password: <input type="password" name="password" required><br>
<input type="submit" name="submit" value="Sign in">
<div style="color:red" id="msg"></div>
</form>
</body>
</html>
The error message should appear on this same page as I understand but it just opens a new page showing only the message and not the html form.
I have a simple servlet like this:
#WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String userID = "root";
private final String password = "root";
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html");
rd.include(request, response);
}
}
Also I have login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="US-ASCII">
<title>Login Page</title>
</head>
<body>
<form action="LoginServlet" method="post">
Username: <input type="text" name="user">
<br>
Password: <input type="password" name="pwd">
<br>
<input type="submit" value="Login">
</form>
</body>
</html>
In browser I start my app http://localhost:8080/LoginCookie/ and browser shows login.html. Then I click "Login" button and URL is changing to http://localhost:8080/LoginCookie/LoginServlet.
How do I disable it?
Instead of including your HTML, you could instead redirect to your login.html
Consider using
response.sendRedirect("login.html");
instead of rd.include()
Redirecting has the nice side-effect that reloading the page will reload login.html instead of triggering your servlet again.
If you want to stay on the same page, leave the action attribute empty into your form tag
<form action="" method="post">
But then, you have to make sure that your Servlet will receive your form. LoginServlet will not receive the form request anymore, it will be sent to Servlet mappend with the URL of your current position. So you'll have to make a Servlet receiving this info.
I have a jsp that calls a servlet. This servlet does some tasks and then I want to return to the page I was just at and reload it. This would be simple if I knew the exact url it would be each time using the redirectUrl. However, I can't hard code a value in this as it is dynamically created. Is there a way to do this when the previous url is Not known to me?
I am not sure if I understood you correctly, do you need move from jsp to servlet, and return to the same jsp? If this is what you need, I would put some hidden input in jsp form with path
<input type="hidden" name="jspPath" value="${pageContext.request.requestURI}"/>
So full solution is below:
page1.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
${requestScope.dataFromServlet }
<form action="${pageContext.request.contextPath}/HelloWorldServlet " method="POST">
<input type="hidden" name="jspPath" value="${pageContext.request.requestURI}"/>
<input type="hidden" name="param1" value="value1"/>
<input type="submit" value="Submit">
</form>
</body>
</html>
HelloWorldServlet.java
public class HelloWorldServlet extends HttpServlet {
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String jspPath = request.getParameter("jspPath");
if(jspPath == null || "".equals(jspPath))
jspPath = "errorPage.jsp";
request.setAttribute("dataFromServlet", "Hello World");
RequestDispatcher rd = request.getRequestDispatcher(jspPath);
rd.forward(request, response);
}
}
I have the following problem. First of all, I'm send request from jsp to servlet, then I'm doing some operation, and put some data to request, and forward to the same page for rendering new data. But after forwarding, my jsp page doesn't update. Can anyone say me, what I'm doing wrong?
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>File Viewer</title>
<link href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
<script src="${pageContext.request.contextPath}/resources/js/bootstrap.min.js"> </script>
<script src="${pageContext.request.contextPath}/resources/js/jquery-1.8.0.min.js"> </script>
<script type="text/javascript">
function showFolderRequest(fileName) {
$.post( "ftp?fileName="+fileName, function( data ) {
});
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="col-md-9 list-group" style="float: none; margin: 20px auto;">
<div class="list-group-item active" style="background-color: darkcyan;">
Ftp server: /
</div>
<c:forEach items="${requestScope.files}" var="fileEntity">
<p class="list-group-item" onclick="showFolderRequest('${fileEntity.name}')">
${fileEntity.name}
</p>
</c:forEach>
</div>
</div>
</body>
</html>
This is my servlet
#WebServlet("/ftp")
public class FileServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
FileManager fileManager = FileManager.getInstance();
String requestedFileName = req.getParameter("fileName");
req.setAttribute("files", fileManager.getAllFilesByPath(requestedFileName));
getServletContext().getRequestDispatcher("/test.jsp").forward(req, resp);
}
}
The problem is that you're firing an ajax request. When handling ajax requests, you need to be aware of some things:
You cannot forward not redirect from your servlet. This is an asynchronous request from the browser and it won't get any content from a forwarding or redirection from the server.
Expression Language (those things inside ${}) and JSP tags like JSTL run on server side when processing the JSP and rendering the HTML. Any ajax request wont update any EL nor any JSP tag content since this code it is not run on server. So, any new attribute you set here won't matter until you fire a non-ajax request.
The only way you can get any data from the server is by writing a response that contains the desired data. Usually, you would write a JSON response, but you can even write an XML or a plain text response, it will depend on your design. Then, in the browser side (Javascript), you handle the data from the response and display some text, update values in your current HTML, and on.
From this case, you can write a list of the desired files into a JSON string and write that string in the server response, then manage it accordingly in client side. This is just a bare example of how to achieve it using Jackson library to convert Java code into JSON string.
In servlet:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
FileManager fileManager = FileManager.getInstance();
String requestedFileName = req.getParameter("fileName");
//not really sure what retrieves, I'm assuming it is a Lis<FileEntity>
//edit this accordingly to your case
List<FileEntity> files = fileManager.getAllFilesByPath(requestedFileName);
String json = new ObjectMapper().writeValueAsString(files);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
In JavaScript:
<script type="text/javascript">
function showFolderRequest(fileName) {
$.post( "ftp?fileName="+fileName, function( data ) {
//logs the whole JSON string response into browser console
//supported in Chrome and Firefox+Firebug
console.log(data);
//parsing the JSON response
var files = JSON && JSON.parse(data) || $.parseJSON(data);
//since it is an array, you need to traverse the values
for (var fileEntity in files) {
//just logging the files names
console.log(fileEntity.name);
}
});
}
</script>
I am using play framework 2.1.5.. As this version of play does not support in built session timeout, I started implementing it functionally... Here is my code..
// Global.java file
#Override
public Action onRequest(Http.Request request, Method method) {
System.out.println(" Request .... " + request.toString());
return new Action.Simple() {
public Result call(Http.Context ctx) throws Throwable {
String lastActionTime = ctx.session().get("lastActionTime");
if (lastActionTime != null && sessionExpired(Long.valueOf(lastActionTime))) {
ctx.session().clear();
flash("success", "Session expired");
return redirect("/login");
}
return delegate.call(ctx);
}
};
}
private boolean sessionExpired(Long lastActionTime) {
maxSessionTime = Integer.parseInt(Play.application().configuration().getString("maxSessionTime"));
return ((System.currentTimeMillis() - lastActionTime) / MILLISECONDS_IN_A_MINUTE) >= maxSessionTime;
}
I am overriding the on request Method...
Session_ timed_ out contains logic where I fetch the session's last inactive time and subtract it from the current time to see if the difference has exceeded the maximum session time.
The problem now is that on session expire, a request fires to /login and it gives a html page as response.
The response is as follows..
<html xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<link rel="shortcut icon" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/stylesheets/dashboard.css" type="text/css" media="screen" charset="utf-8">
</head>
<body>
<header class="clearfix">
<h1>Login</h1>
</header>
<form action="/login" method="POST" >
<div id=login_form>
<h1>Sign in</h1>
<p class="success">
Session expired
</p>
<p>
<input type="email" name="email" placeholder="Email" value="">
</p>
<p>
<input type="password" name="password" placeholder="Password" >
</p>
<p>
<button type="submit">Login</button>
</p>
</div>
</form>
</body>
</html>
The method that handles /login request is:
public Result login(){
return ok(login.render(form(Login.class)));
}
My login class:
public static class Login{
public String email;
public String password;
public String validate(){
if (User.authenticate(email, password) == null){
return "Invalid username or password";
}
return null;
}
}
How can I render this html page to the view?
A few observations...
When a page request is captured by on request method, redirect to login is also considered as a page request and the page is rendered properly....
When an ajax request is intercepted by on request redirect to login is also made as ajax call (X-Requested-With is present in header)....
Now how can I convert this ajax call to page request??
You need two different strategies depending on the nature of the request. For AJAX requests, you could reply with some relevant http error code and implement some client-side code to redirect to your login page. For normal page requests, your current strategy will work fine.
Here's another way to achieve this.
Remove the static keyword from your anonymous inner class:
public Result call (final Context ctx) {
...
}
Finally figured out the answer...
When an incoming request is a page request, redirect to login is also considered as a page request.. Hence the response is rendered on the screen...
But, when the incoming request is an ajax request, redirect to login is treated as an ajax request...
So, to render this response...
//Global.java
#Override
public Action onRequest(Http.Request request, Method method) {
System.out.println(request.path());
return new Action.Simple() {
public Result call(Http.Context ctx) throws Throwable {
String lastActionTime = ctx.session().get("lastActionTime");
if (lastActionTime != null && sessionExpired(Long.valueOf(lastActionTime))) {
ctx.session().clear();
flash("success", "Session expired");
return temporaryRedirect("/login");
}
return delegate.call(ctx);
}
};
}
private boolean sessionExpired(Long lastActionTime) {
maxSessionTime = Integer.parseInt(Play.application().configuration().getString("maxSessionTime"));
return ((System.currentTimeMillis() - lastActionTime) / MILLISECONDS_IN_A_MINUTE) >= maxSessionTime;
}
In the client side,
$.ajaxSetup({
error: function (XMLHttpRequest, textStatus, errorThrown) {
document.open();
document.write(XMLHttpRequest.responseText);
document.close();
}
});
Thanks Avik & Mantithetical... But is there any other better way to achieve the same?