I have a user Sign in Html form where I get the user's email and password and check them against a database. So far I have the following code but when I submit the form it does not go to the specified JSP page. What can I do to improve my code and how can I just generate an error message when the user presses submit but still stay on the same page?
Thank you in advance.
//SERVLET doPost Method
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userinp = request.getParameter("userinp"); //hidden type in html sign up form
HttpSession s = request.getSession();
User u = new User();
if(userinp.equals("signup")) {
u.setName(request.getParameter("name"));
u.setLname(request.getParameter("lname"));
u.setEmail(request.getParameter("email"));
u.setPassword(request.getParameter("password"));
s.setAttribute("User", u);
//Save to DB
u = (User)s.getAttribute("User");
s.invalidate();
UserM ud = new UserM(); //class which contains CRUD methods
ud.createTable();
ud.insert(u);
ServletContext ctx = request.getSession().getServletContext();
forwardTo(ctx, request, response, "/Somepage.jsp");
} else if(userinp.equals("login")) {
String pass1 = request.getParameter("pass");
String email = request.getParameter("useremail");
Connection conn = null;
PreparedStatement stm = null;
try {
conn = ConnectionConfiguration.getConnection();
stm = conn.prepareStatement("SELECT password FROM users WHERE email = ?");
stm.setString(4, email);
ResultSet resultSet = stm.executeQuery();
while(resultSet.next()) {
String pass2 = resultSet.getString("password");
if(pass1.equals(pass2)) {
ServletContext ctx = request.getSession().getServletContext();
forwardTo(ctx, request, response, "/Somepage.jsp");
} else {
//code to generate "Wrong Password" message
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(stm != null) {
try {
stm.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
//ForwardTo Method
public static void forwardTo(ServletContext ctx, HttpServletRequest req, HttpServletResponse resp, String dest) throws ServletException
{
RequestDispatcher rd = ctx.getRequestDispatcher(dest);
try
{
rd.forward(req, resp);
}
catch(Throwable t)
{
t.printStackTrace();
throw new ServletException(t);
}
}
//HTML FORM
<html>
<head>
<meta charset="ISO-8859-1">
</head>
<body>
<form action = "UserServ" method="POST">
<h3>Enter the details below to Sign In</h3><br>
Email: <input type="text" name="useremail" required><br>
Password: <input type="password" name="pass" required><br>
<input type="submit" value="Sign In">
</form>
</body>
</html>
You have an error in your database preparedStatement:
stm.setString(4, email);
What is 4 supposed to be here? The first parameter of setString corresponds to the '?' in your prepared statement.
stm = conn.prepareStatement("SELECT password FROM users WHERE email = ?");
You only have 1 question mark, so it should be:
stm.setString(1, email);
What can I do to improve my code
Seperate the database logic from your servlet. Use the MVC pattern, it will make your life easier.
and how can I just generate an error
You can easily achieve this with JSTL/EL in your JSP. Set an attribute in your servlet and forward that to the jsp page. JSTL will check if the attribute exists and show the appropriate message.
You could also just forward the user to a specific page if the details are wrong, like i have shown in the example below.
A more advanced way would be to implement AJAX, this is basically using javascript to make asynchronous calls to your servlet so that you don't have to refresh the page. You could use this to check see if the details are correct.
message when the user presses submit but still stay on the same page?
You mean if they haven't typed in any details? You could use javascript/jquery to do this. Maybe disable the submit btn/form from submitting when the text fields are empty.
Below is your servlet code, i condensed your database logic. Much easier to manage this way:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userinp = request.getParameter("userinp"); //hidden type in html sign up form
HttpSession s = request.getSession();
User u = new User();
ServletContext ctx = s.getServletContext();
//check for null first, because if userinp is empty, then you will get a NPE
if(userinp != null && userinp.equals("signup")) {
u.setName(request.getParameter("name"));
u.setLname(request.getParameter("lname"));
u.setEmail(request.getParameter("email"));
u.setPassword(request.getParameter("password"));
s.setAttribute("User", u);
//Save to DB
u = (User)s.getAttribute("User");
s.invalidate();
UserM ud = new UserM(); //class which contains CRUD methods
ud.createTable(); //why are you creating a table for each user? (you need to create a table called 'users' and just insert the new user there.
ud.insert(u);
forwardTo(ctx, request, response, "/Somepage.jsp");
} else if( userinp != null && userinp.equals("login")) { //you should separate the register and login logic (easier to maintain in two different servlets
String pass1 = request.getParameter("pass");
String email = request.getParameter("useremail");
//so instead of getting the password from the database, you can check to see if the details exist instead and return a boolean.
if(validate(email,pass1)){
forwardTo(ctx, request, response, "/Welcome.jsp"); //user is logged in
}else{
forwardTo(ctx, request, response, "/Error.jsp"); //user is not logged in, details do not match
}
}
}
validate method:
//this should be in a different class. So it's easier to maintain and can be used elsewhere. It's bad practice to have database logic in your servlet. Because what if you want to use this in a different servlet or another part of your application? (you don't want to copy and pasta it everywhere do you?)
public static boolean validate(String email, String password){
boolean status = false;
PreparedStatement pst = null;
ResultSet rs = null;
//if you put your getConnection method as a try condition, it will automagically close the connection for you.
try(Connection conn= ConnectionConfiguration.getConnection()){
pst = conn.prepareStatement("select * from users where email=? and password=?;");
pst.setString(1, email); //1 here corresponds to the first '?' in preparedStatement
pst.setString(2, password); //2 corresponds to the second '?'
rs = pst.executeQuery();
status = rs.next(); //if there are any results, then status is true.
} catch (SQLException e) {
e.printStackTrace();
}
return status;
}
Let me know if you have problems anywhere or other questions, happy to help.
Related
I have created a login page using HTML page and Java Servlet class. However I am wondering if it is possible to have a JSP instead of the Java file? So essential use this code in the Java class into a JSP page and still have the same functionality?
<form action="Lognn" method="post">
<input type="text" name="name"/>
<input type="text"name="pass"/>
Java class
Public class Login extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
try (PrintWriter out = response.getWriter()) {
String name = request.getParameter("name");
String pass = request.getParameter("pass");
MyDb1 db = new MyDb1();
Connection con = db.getCon();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select uid,name,pass from register where email = '"+name+"' and pass = '"+pass+"'");
while ((rs.next())) {
String uid = rs.getString("uid");
//out.println("User id"+uid);
HttpSession session=request.getSession();
session.setAttribute("name",uid);
response.sendRedirect("http://localhost:8080/Final/userprofile.jsp");
}
} catch (SQLException ex) {
Logger.getLogger(Login.class.getName()).log(Level.SEVERE, null, ex);
}
Generally, each JSP is translated and compiled to a servlet, and a lot of things you can do with servlets you can do with JSP.
You can change your form action="Lognn" method="post" to form action="Lognn.jsp" method="post", then
in Lognn.jsp you can read your input parameters from html like <%= request.getParameter("name")%>, then
in Lognn.jsp you can connect to a database directly or you can use EJB
and finally you can give html output back from the same JSP.
It formally will work without servlet, but in CATALINA_HOME/WORk directory a servlet will be internally created and compiled from your JSP.
I've searched for username availability in google. There was no any good solution to this problem. Here I'm trying to check username availability in database table user. I have following code
<input type="text" name="username" id="usernamee" tabindex="1"class="form-control" placeholder="Username"><span class="status">
this is my script code
<script>
$(function(){
$("#usernamee").blur(function(){
var uname = $('#usernamee').val();
if(uname.length >= 3){
$(".status").html("<font> Checking availability...</font>");
$.ajax({
type: "GET",
url: "/exist/"+uname,
success: function(msg){
$(".status").html(msg);
}
});
}
else{
$(".status").html("<font color=red>Username should be <b>3</b> character long.</font>");
}
});
});
</script>
this is my controller code
#RequestMapping(value = { "/exist/{name}" }, method = RequestMethod.POST)
public void checkUsername(#PathVariable("name") String username, HttpServletResponse response , HttpServletRequest request) throws IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
String connectionURL = "jdbc:mysql://localhost:81/name"; // students is my database name
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = (Connection) DriverManager.getConnection(connectionURL, "root", "root");
PreparedStatement ps = (PreparedStatement) connection.prepareStatement("select username from users where username=?");
ps.setString(1,username);
ResultSet rs = ps.executeQuery();
if (!rs.next()) {
out.println("<font color=green><b>"+username+"</b> is avaliable");
}
else{
out.println("<font color=red><b>"+username+"</b> is already in use</font>");
}
out.println();
} catch (Exception ex) {
out.println("Error ->" + ex.getMessage());
} finally {
out.close();
}
}
When I run these code the statusspan tag only shows checking availability..... only. My controller haven't been invoked.
Above code is copied from internet. Any suggestions are welcomed.
Thank you in advance
You send GET request
$.ajax({
type: "GET"
But your controller expect POST
#RequestMapping(value = { "/exist/{name}" }, method = RequestMethod.POST)
Either change ajax to POST or controller to GET
I haven't get you question from what you said above, but you should add #ResponseBody for ajax request.
I recall what I said above, PrintWriter is used and #ResponseBody is not needed, but use #ResponseBody will be better
I have read the similar topics like this, and that one but it did not help with my problem.
I created a simple JavaEE mvc web app. The jsp page contains a form with two text fields and two buttons. The first text field to enter an Id, the second to enter a name. Depending on which button is clicked a Servlet routes to the appropriate method (Search by ID or Search by Name).
Search by id method works correctly. And I see the following path in the address bar: http://localhost:8080/employees_war_exploded/ControllerServlet?textEmployeeId=1&command=Search_ID&employeeName=
However there is a problem with a Search by name method. It does not show any results. Here is what I see in the address bar: http://localhost:8080/employees_war_exploded/ControllerServlet?textEmployeeId=&employeeName=ann&command=Search_Name
I guess the problem is that in both cases it gets the parameters of both text fields ("textEmployeeId" and "employeeName"). How can I make it process both inputs separately in the same form? Maybe there is some other reason for the problem that I do not see?
<form class="form-style" name="form1">
<label>ID:
<input type="text" name="textEmployeeId" value="${tempEmployee.id}" />
</label>
<input type="submit" name="command" value="Search_ID">
<br>
<br>
<label>Name:
<input type="text" name="employeeName" value="${tempEmployee.name}" />
</label>
<input type="submit" name="command" value="Search_Name">
<br>
<br>
</form>
ControllerServlet.java
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String theCommand = request.getParameter("command");
if (theCommand == null) {
theCommand = "EMPLOYEE_LIST";
}
// route to the appropriate method
switch (theCommand) {
case "EMPLOYEE_LIST":
listEmployees(request, response);
break;
case "Search_ID":
searchById(request, response);
break;
case "Search_Name":
searchByName(request, response);
break;
default:
listEmployees(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void searchByName(HttpServletRequest request, HttpServletResponse response) throws Exception {
String nameString = request.getParameter("employeeName");
List<Employee> namedEmployees = employeeDbUtil.searchEmployees(nameString);
request.setAttribute("EMPLOYEES", namedEmployees);
RequestDispatcher dispatcher = request.getRequestDispatcher("/search-by-name.jsp");
dispatcher.forward(request, response);
}
private void searchById(HttpServletRequest request, HttpServletResponse response) throws Exception {
String textString = request.getParameter("textEmployeeId");
Employee theEmployee = employeeDbUtil.getEmployeeById(textString);
request.setAttribute("THE_EMPLOYEE", theEmployee);
RequestDispatcher dispatcher = request.getRequestDispatcher("/show-employee.jsp");
dispatcher.forward(request, response);
}
}
Update: I'm getting a NullPointerException for the searchByName method. Could there be a problem with this method from a DAO class that is called from ControllerServlet?
public List<Employee> searchEmployees(String employeeName) throws Exception {
List<Employee> employeeList = new ArrayList();
Connection myConnection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
employeeName += "%";
preparedStatement = myConnection.prepareStatement("SELECT * FROM employees WHERE LOWER(name) like LOWER(?)");
preparedStatement.setString(1, employeeName);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Employee tempEmployee = resultSetToEmployee(resultSet);
employeeList.add(tempEmployee);
}
return employeeList;
}
finally {
DbExceptions.close(resultSet);
DbExceptions.close(preparedStatement);
DbExceptions.close(myConnection);
}
}
I have a servlet where I get data from Sql Server using ResultSet. I use
request.setAttribute("list", list);
request.getRequestDispatcher("Display.jsp").forward(request, response); to display as a table in the jsp.
But in the omnibox of chrome I see /ServletName instead of /JSPName.jsp. The table is displayed in the jsp using foreach based on the list received from servlet.
This is the servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Connection connection = null;
Statement stmt = null;
try {
StringBuffer data = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException ex) {
Logger.getLogger(NewServlet.class.getName()).log(Level.SEVERE, null, ex);
}
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;databaseName=DesktopScreen","sa","sa123");
stmt = connection.createStatement();
ArrayList list = new ArrayList();
String query = "select * from ClientLogin";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String UniqueId,ClientId,RequestedDateTime,ConnectionStatus;
UniqueId = rs.getString("UniqueID");
ClientId = rs.getString("ClientId");
RequestedDateTime = rs.getString("RequestDateTime");
ConnectionStatus = rs.getString("ConnectionStatus");
BeanClass beanClass = new BeanClass();
beanClass.setUniqueId(UniqueId);
beanClass.setClientId(ClientId);
beanClass.setConnectionStatus(ConnectionStatus);
beanClass.setRequestDateTime(RequestedDateTime);
list.add(beanClass);
}
request.setAttribute("list", list);
request.getRequestDispatcher("Display.jsp").forward(request, response);
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
connection.close();
} catch (SQLException ex) {
Logger.getLogger(NewServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This is Display.jsp:
<table border ="1" style="border: border-collapse">
<tr><td>UniqueId</td><td>ClientId</td><td>Request Date and Time</td><td>Connection Status</td></tr>
<c:forEach items="${list}" var="item">
<tr>
<td>${item.getUniqueId()}</td>
<td>${item.getClientId()}</td>
<td>${item.getRequestDateTime()}</td>
<td>${item.getConnectionStatus()}</td>
</tr>
</c:forEach>
</table>
Your browser has requested for the servlet url and the servlet has forwared it to jsp. Your browswer does not know that. This is because you are using [requestDispatcher.forward()][1] method. Check the image from thejavageek.com
This is what happens
Browser requests the servlet.
Servlet forwards the task to jsp.(Browser doesn't know that)
Broswer still thinks the response has come from servlet and not jsp.
If you want the url to be shown in browser, then you need to user response.sendRedirect() which is explained in image below
If you use response.sendRedirect(), below steps will happen.
Your browser requests servlet.
Servlet calls response.sendredirect();
Browser will make another request to another resource and url will be changed in the address bar.
When you use requestDispatcher.forward(); the resources are forwarded within the server from where the call is made. This is done by container internally and client or browser is not involved in it.
i have the following pice of code 'anmelden.java':
#WebServlet("/anmelden")
public class anmelden extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String benutzer = request.getParameter("benutzer");
String passwort = request.getParameter("passwort");
try {
PrintWriter out = response.getWriter();
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/test","admin","*****");
PreparedStatement stmt = con.prepareStatement("SELECT benutzer,passwort,rolle FROM login WHERE benutzer = ? AND passwort = ?");
stmt.setString(1, benutzer);
stmt.setString(2, passwort);
ResultSet rs = stmt.executeQuery();
if(rs.next())
{
HttpSession session = request.getSession();
session.setAttribute("benutzer", rs.getString("benutzer"));
RequestDispatcher dis = request.getRequestDispatcher("mandant.jsp");
dis.forward(request, response);
out.print("1");
}
else
{
out.print("Benutzername und/oder Passwort falsch");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
This is my jsp file 'login.jsp':
$("#anmelden").click(function(){
var benutzer = $("#benutzer").val();
var passwort = $("#passwort").val();
if(benutzer == "" || passwort == "")
{
return;
}
$.ajax({
url:"anmelden",
type:"POST",
data:"benutzer="+benutzer+"&passwort="+passwort
}).success(function(data){
var erfolg = data;
if(erfolg == "1")
{
window.location.href="http://localhost:8080/PSD/mandant.jsp";
}
else
{
$("#ok").text(erfolg);
}
});
});
As u can see i tries to set the name coming from my DB into my session Attribute.
I want to use the Attribute in my 'mandant.jsp' file.
But it dosen't work - all what happens is, that my 'login.jsp' file which makes the ajax call, print the code from 'mandant.jsp' into my div as text.
So it dosen't opend the next page as i want -.-
But if i comment out the HttpSession block then it works fine but then i can't use ,of course,the session Attribute.
So what's wrong or what must i change so that this code works?
Many thanks
This is because this part of the code:
RequestDispatcher dis = request.getRequestDispatcher("mandant.jsp");
dis.forward(request, response);
is generating the HTML from mandant.jsp file using the request object (along with HttpSession and ServletContext) to fulfill any Expression Language and writing this HTML into the response. Just remove these lines and you'll be ok.
You are mixing two types of communication here, from the JSP page you are making an ajax call but from the Servlet you are making a Dispatch redirect.
If you want the login page to be redirected after a a successful login then don't call the Servlet with an ajax call and better do a form submit.
If you rather want to only check credentials on the servlet and redirect from the client then keep the ajax call but avoid the request dispatcher in the servlet and return a success/error code instead. Then capture that code from the ajax response and redirect to a successful page if you want.