I'm trying to create a basic password reset system. I'm creating an unique token for each user, storing in database and retrieving that token value in url like: http://localhost:8080/login/reset-password.jsp?token=0d1eaa1a-869c-4f40-8437-a3cdaeddf497
The problem here is that I'm trying to update the password in the database but the value isn't updated. It displays that the password is changed, but nothing happens in database. Please help.
Here's my servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String password = request.getParameter("password");
String token = request.getParameter("token");
ForgotPasswordHandler.UpdatePassword(password, token);
String message = "Password changed!";
request.setAttribute("message", message);
request.getRequestDispatcher("reset-password.jsp?token=" + token).forward(request, response);
}
Here's my method in class ForgotPasswordHandler.java:
public static void UpdatePassword(String password, String token) {
try
{
if (con == null){
System.out.println("Failed connection");
}else{
PreparedStatement ps = con.prepareStatement(
"UPDATE user SET password = ? WHERE reset_token = ?");
ps.setString(1,password);
ps.setString(2,token);
ps.executeUpdate();
ps.close();
}}
catch (Exception e) {
e.printStackTrace(System.out);
}
}
Your connection may have autoCommit turned off. If that is the problem you can fix it with code like this:
if (!con.getAutoCommit()) {
con.commit();
}
One other thing to note is that if the call to ps.executeUpdate() fails, the prepared statement will not be cleaned up. To avoid that problem move the close to the finally block. Here is what the full code would look like:
PreparedStatement ps = null;
try
{
if (con == null){
System.out.println("Failed connection");
} else {
ps = con.prepareStatement(
"UPDATE user SET password = ? WHERE reset_token = ?");
ps.setString(1,password);
ps.setString(2,token);
ps.executeUpdate();
if (!con.getAutoCommit()) {
con.commit();
}
}
}
catch (Exception e) {
e.printStackTrace(System.out);
}
finally {
if (ps != null) {
ps.close();
}
}
Related
So i got this form that I'm using but I get that error whenever i submit, it says CONNECTION SUCCESSFUL but then it returns the error and never insert nor retrieves anything from the db. I checked the version of the sqlite and everything, can't figure it out.
public class databaseConnection {
public static Connection connection = null;
public static Connection getConnection() throws ClassNotFoundException {
try {
System.out.println("CONNECTING");
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:SoftwareDB.db");
System.out.println("CONNECTION SUCCESSFUL");
} catch (SQLException e) {
System.out.println("ERROR: Connection Failed!");
}
return connection;
}
public static void login(String username, String password, String login) throws ClassNotFoundException {
try {
System.out.println("INSERTING");
try (Statement stmt = getConnection().createStatement()) {
String sql = "INSERT INTO login (username, password) VALUES ('" + username + "', '" + password + "', '" + login + "');";
stmt.execute(sql);
}
getConnection().close();
System.out.println("INSERT SUCCESSFUL");
} catch (SQLException ex) {
Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static ResultSet getLoginDetails(String query) throws SQLException, ClassNotFoundException {
ResultSet rs;
try (PreparedStatement ps = getConnection().prepareStatement(query)) {
rs = ps.executeQuery();
ps.close();
getConnection().close();
}
return rs;
}
public static ResultSet getExistentDetails(String query) throws SQLException, ClassNotFoundException {
ResultSet rs;
try (PreparedStatement ps = getConnection().prepareStatement(query)) {
rs = ps.executeQuery();
getConnection().close();
}
return rs;
}
}
private void loginBtnMouseClicked(java.awt.event.MouseEvent evt) {
if (username.getText().isEmpty() || password.getText().isEmpty()) {
infoLabel.setVisible(true);
username.setText("");
password.setText("");
} else {
try {
databaseConnection.getLoginDetails("SELECT * FROM register WHERE email = '?' AND password = '?'");
String ts = new SimpleDateFormat("dd.MM.yyyy - HH.mm.ss").format(System.currentTimeMillis());
databaseConnection.login(username.getText(), password.getText(), ts);
JOptionPane.showMessageDialog(null, "Login succesful!");
new login().setVisible(true);
infoLabel.setVisible(true);
username.setText("");
password.setText("");
} catch (HeadlessException ex) {
JOptionPane.showMessageDialog(null, "Failed!");
} catch (SQLException | ClassNotFoundException ex) {
Logger.getLogger(login.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Output
I believe you have forgotten an important thing: properly preparing your PreparedStatement and opening/closing connections correctly.
Would you try the following rewritten getLoginDetails() method and take inspiration from it for the other methods?
public static ResultSet getLoginDetails(String query, String email, String password) throws SQLException, ClassNotFoundException {
ResultSet rs;
try (Connection conn = getConnection()) {
try (PreparedStatement ps = conn.prepareStatement(query)) {
ps.setString(1,email);
ps.SetString(2,password);
rs = ps.executeQuery();
// Do something with the ResultSet here or do not close the statement!
}
}
return rs; // should be something else! (as it could be already closed)
}
Then you certainly need to do something with the ResultSet! For example: check that the email/password combination exists in order to validate the login request.
Also, some important remarks and tips:
better check that the connection is valid after initialization using isValid(timeout)
think about a connection pool or at least some ways to reuse your connection(s)
eventually use existing tools (libraries like Apache) for your ORM (Object-Relation Mapping) and DAO (Database Access Object) layers. Actually, that's highly recommended.
closing a PreparedStatement will automatically close the associated ResultSet. Your code does not take that into account. Cf. https://docs.oracle.com/javase/8/docs/api/java/sql/ResultSet.html
Keep me posted!
I have to connect a database to my codes to check a pin code. I have managed to make it but I'm having some problem to make the else part of the if statement to work. I think its the query part which is causing the problem as when I change the if..else statement it works perfectly.
If there is any other way to write this query to get the same result please let me know
thank you
public void getOperation() {
{
Connection conn = null;
String query = "SELECT pin FROM customerdetails WHERE pin='"+Pin+"'";
Statement stmt = null;
try {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/customerdb", "user","#1234#");
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
String password = rs.getString("pin");
if (Pin.equals(password)) {
PinCheck = "Pin OK";
} else
{
PinCheck = "Invalid Pin";
}
}
} catch (SQLException e) {
System.err.println(e);
} finally {
if (stmt != null) {
}
if (conn != null ) {
//conn.close();
}
}
}
Having this
String query = "SELECT pin FROM customerdetails WHERE pin='"+Pin+"'";
while (rs.next()) {
String password = rs.getString("pin");
if (Pin.equals(password)) {
PinCheck = "Pin OK";
} else
{
PinCheck = "Invalid Pin";
}
}
makes little sense, as you will always have equal Pin - because you are querying for it. Check for results count. 1== Pin matches, 0== pin invalid.
i am learning CRUD and login.i am having problems login part. i can not get it to working on the servlet side, i have interface userDao :
public interface UsersDao {
public boolean validate(String UserName, String Password);
}
UsersDaoImplementation class:
#Override
public boolean validate(String UserName, String Password) {
boolean status = false;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
String query = "SELECT * FROM Users WHERE UserName=? and Password=?";
preparedStatement = conn.prepareStatement( query );
preparedStatement.setString(1, UserName);
preparedStatement.setString(2, Password);
resultSet = preparedStatement.executeQuery();
status=resultSet.next();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return status;
}
for the servlet this what i have
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String UserName=request.getParameter("UserName");
String Password=request.getParameter("Password");
HttpSession session = request.getSession(false);
if(session!=null)
session.setAttribute("UserName", UserName);
if (UsersDaoImplementation.validate(UserName, Password))
{
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/views/jupiter/jupiter.jsp");
rd.forward(request,response);
}
else
{
out.print("<p style=\"color:red\">Sorry username or password error</p>");
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/views/system/index.html");
rd.include(request,response);
}
out.close();
}
What is the right way do reslove this? and what am i not doing right?
First, here you take UserName and Password values from request, probably from a html page.
String UserName=request.getParameter("UserName");
String Password=request.getParameter("Password");
Then you compare these values you get with themselves
if (UserName.equals(UserName)
&& Password.equals(Password))
So it will always return true.
Second, inside your if statement you call your validate function, but you don't use its return, you just call it.
dao.validate(UserName,Password);
So, you most likely want to do something like this
if (dao.validate(UserName, Password) {
// user found
}
These line:
if (UserName.equals(UserName) && Password.equals(Password))
make no sense because the comparisons doesn't have function. You compared the variable Username with himself.
1 - RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/views/jupiter/jupiter.jsp");
2 - rd.forward(request,response);
3 - dao.validate(UserName,Password);
At first step you redirect, (line 2), after, in next step, you validate (line 3).
I think that you should change the lines 2 and 3.
1 - RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/views/jupiter/jupiter.jsp");
2 - dao.validate(UserName,Password);
3 - rd.forward(request,response);
I am trying to make a form where sellers can insert new items, new category and delete items. Now I have problem with DELETE.
This is my code and if somebody know how to fix it please help.
String id = "42";
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/projekat","root","");
PreparedStatement prepared_statement = connection.prepareStatement("DELETE FROM artikli WHERE id= ? ;");
prepared_statement.setString(1, id);
int result_set = prepared_statement.executeUpdate();
if (result_set > 0)
{
System.out.println("Deleted");
}
else
{
System.out.println("Can't delete");
}
} catch (Exception ex) {
System.out.println(ex);
}
Try this:
String id = request.getParameter("id");
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/projekat","root","");
PreparedStatement prepared_statement = null;
String strQuery = "DELETE FROM artikli WHERE id= ?";
prepared_statement = connection.prepareStatement(strQuery);
prepared_statement.setString(1, id);
int result_set = prepared_statement.executeUpdate();
if (result_set > 0)
{
// System.out.println(result_set);
response.sendRedirect("Prodaja2.jsp");
}
else
{
// System.out.println(result_set);
response.sendRedirect("Prodaja2.jsp?error=Can'tDelete");
}
} catch (Exception ex) {
out.print(ex);
} finally {
try {
stmtProd.close();
connection.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
In your code the semicolon after the query may be conflicting. And also don't forget to close the connections in the finally block created because it may lead to resource leak and connection will remain active even if the user logs out.
One error is here, that is in your syntax
Change the code
PreparedStatement prepared_statement = connection.prepareStatement("DELETE FROM artikli WHERE id= ? ;");
to
PreparedStatement prepared_statement = connection.prepareStatement("DELETE FROM artikli WHERE id= ?");
If there is no other errors, Check value in id, there is a chance of null value.
I wrote a servlet whose purpose is to login into the application only if the query executes...now what is the condition to be used for invalid username and id...I'm unable to write the condition..pls help me out...the servlet is...
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:orcl ","scott","tiger");
System.out.println("cnnection est");
int Id = Integer.parseInt(request.getParameter("id"));
String Name=request.getParameter("firstname");
boolean b=true;
//Connection con =JdbcConnectionUtil.getConnection();
PreparedStatement pst = con.prepareStatement("select * from login where id=? and firstname=?");
pst.setInt(1, Id);
pst.setString(2, Name);
ResultSet rs = pst.executeQuery();
if(rs!=null && rs.next())
{
//while(rs.next()){
PrintWriter pw = response.getWriter();
System.out.println("here");
pw.println("hello");
pw.println(rs.getInt(1));
pw.println(rs.getString(2));
pw.println(rs.getString(3));
}
//}
else
{
RequestDispatcher rd = request.getRequestDispatcher("/LoginFailed.html");
}
//
}
catch(Exception ex){
ex.printStackTrace();
}
}
Using rd.forward will solve the problem I think.
How to forward requests from Servlet to JSP
First you check for the correct parameters and then you do the logic. Also do not forget to close statements and connections to avoid memory leaks.
Here is refactored code:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//get parameters from request
try {
String idParam = request.getParameter("id");
String name = request.getParameter("firstname");
//check if request contains such parameters
if (idParam == null || name == null) {
throw new IllegalArgumentException(
"Id and Name parameters must not be null.");
}
//try casting idParam to int
Integer id = null;
try {
id = Integer.parseInt(idParam);
} catch (NumberFormatException nfe) {
throw nfe;
}
PreparedStatement pst = null;
Connection con = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:orcl ", "scott", "tiger");
pst = con.prepareStatement(
"select * from login where id=? and firstname=?");
pst.setInt(1, id);
pst.setString(2, name);
//check if result returned any data
ResultSet rs = pst.executeQuery();
if (!rs.next()) {
throw new Exception(
"No such user for id: " + id + " and name: " + name);
}
PrintWriter pw = response.getWriter();
pw.println("hello");
pw.println(rs.getInt(1));
pw.println(rs.getString(2));
pw.println(rs.getString(3));
} catch (Exception ex) {
throw ex;
} finally {
try {
if (pst != null) {
pst.close();
}
if (con != null) {
con.close();
}
} catch (SQLException sqle) {
throw sqle;
}
}
} catch (Exception ex) {
ex.printStackTrace();
RequestDispatcher rd = request.getRequestDispatcher("/LoginFailed.html");
rd.forward(request, response);
}
}
Something like that would be appropriate I think.