How I can resolve java user class and JDBC user class? The problem is when i run out put is ther is data in sql.For example
public User authenctication(String eMail, String password) {
try {
con = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "root");
stm = con.createStatement();
rs = stm.executeQuery("select * from User,Role where user.id=role.id");
while(rs.next()) {
user = new User();
user.setAddress(rs.getString(""));
user.setCountry(rs.getString(""));
user.setCreatedBy(rs.getString(""));
user.setEMail(rs.getString(""));
user.setId(rs.getInt(""));
}
} catch (Exception sqlEx) {
System.out.println("sqlexecuteException: " + sqlEx.toString());
}
return user;
}
user = new User();
Everytime you assign a new Object to user, you loose the old. A better possibility would be the usage of a LinkedList:
List<User> users = new LinkedList<User>();
while (rs.next()) {
User user = new User();
user.setAddress(rs.getString(""));
user.setCountry(rs.getString(""));
user.setCreatedBy(rs.getString(""));
user.setEMail(rs.getString(""));
user.setId(rs.getInt(""));
users.add(user);
}
The code above seems to be wrong. You are trying to create and initialize the same object
user = new User();
again and again all over the result set. Instead use an Array List
public User authentication(String eMail, String password) {
try {
ArrayList<User> user_set = new ArrayList<User>();
con = DriverManager.getConnection("jdbc:mysql://localhost/mydb", "root", "root");
stm = con.createStatement();
rs = stm.executeQuery("select * from User,Role where user.id=role.id");
while(rs.next()) {
user = new User();
user.setAddress(rs.getString(""));
user.setCountry(rs.getString(""));
user.setCreatedBy(rs.getString(""));
user.setEMail(rs.getString(""));
user.setId(rs.getInt(""));
user_set.add(user);
}
} catch (Exception sqlEx) {
System.out.println("sqlexecuteException: " + sqlEx.toString());
}
return user_set;
}
Give the Fully-Qualified Name of a class to avoid Naming Conflicts.
For Ex :
com.me.package.User objUser = new com.me.package.User();
Where User is the class which resides in the package com.me.package
Try to look at more closely to your query ,it seems wrong to me .
Also use Prepared Statement to avoid Sql Injection
I think you want only one user to be logged in. For that, your query is wrong.
You should make it like this:
"SELECT * FROM User,Role WHERE (user.id=role.id) AND (user.email='" + eMail + "')"
This will give you only the user with the email address you passed.
But there is another way to achive your goal without risking a SQL injection. You could leave your program as it is. You only add one simple line in your loop, just before the closing brace:
if (user.getEMail().equals(eMail))
break;
This line will make it possible to exit the loop after the right user was found. So you will return the right one.
Related
Attempting to push this object that I'm building my while loop into a list array. I can't exactly figure out what I'm doing wrong. Can some one please explain first, what the best syntax is and the best way to pull out this information to push it to a list array. so later I can access the list array by getting the information out of it.
public void getTableConnection() throws ClassNotFoundException,
SQLException {
List<Car>cars = new ArrayList<Car>();
Car car = new Car();
try {
Table table = new Table();
table.getTableConnection();
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/carrentalsystem";
String username = "root";
String password = "javatest";
String query = "select * from cardetails";
Connection conn = DriverManager.getConnection(url, username,
password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
car.setId(rs.getInt("id"));
car.setYear(rs.getString("Year"));
car.setMake(rs.getString("Make"));
car.setModel(rs.getString("Model"));
car.setColor(rs.getString("Color"));
car.setAvailable(rs.getString("Availability"));
String renting;
car.add()
}
return cars;
}catch(Exception e) {
}finally{
}
}
I had to change that line to cars.add(car)
At the first place you didn't add car to cars.You can't change the value of the returned ArrayList (cars) in the finally block if it is already returned. So don't return from try.
String email = email_register_txt.getText();
String username = username_register_txt.getText();
Statement stmt = db_connection.connect().createStatement();
String sql = "SELECT * FROM user_profile WHERE username=' "+username+" ' OR user_email=' "+email+" ' ";
res = stmt.executeQuery(sql);
if(res.next()) {
if(res.getString("username").equalsIgnoreCase(username)) {
JOptionPane.showMessageDialog(registerPanel, "The username has already been already registered!");
} else if (res.getString("user_email").equalsIgnoreCase(email)) {
JOptionPane.showMessageDialog(registerPanel, "This email address has already been already registered!");
}
} else { ...
Either of those error message appear when i enter the username/email who has already been inserted into the database.
My register work but I think the verify part may be missing something?
You are obviously not showing all the pertinent code or you simply have neglected to place the needed code into your method that should make this work.
A ResultSet is basically a collection of results from your query which you need to iterate through to access all results from that query. A while loop is widely used as the means to iterate through all the results contained within a result set object. I see nowhere in your code where you have declared a ResultSet Object but yet you are trying to utilize one. Perhaps try something like this:
String email = email_register_txt.getText();
String username = username_register_txt.getText();
try {
Connection conn = DriverManager.getConnection("...your jdbc connection string...");
conn.setAutoCommit(false);
String sql = "SELECT * FROM user_profile WHERE username = ? OR user_email = ?";
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, username);
stmt.setString(2, email);
ResultSet res = stmt.executeQuery();
// Utilize a boolean Flag to indicate whether
// or not the User is registered.
boolean registered = false;
while (res.next()) {
if(res.getString("username").equalsIgnoreCase(username)) {
JOptionPane.showMessageDialog(registerPanel,
"The username has already been already registered!");
registered = true;
break; // Get out of the loop. No more need for it.
}
else if(res.getString("user_email").equalsIgnoreCase(email)) {
JOptionPane.showMessageDialog(registerPanel,
"This email address has already been already registered!");
registered = true;
break; // Get out of the loop. No more need for it.
}
}
// Do what needs to be done if User is NOT registered.
if (!registered) {
...............................
...............................
}
res.close();
stmt.close();
conn.close(); //Close the DB connection
}
catch (SQLException ex) {
ex.printStackTrace();
}
You will notice the use of the PreparedStatement Class. There are a number of benefits for using this class:
1) PreparedStatement allows you to write dynamic and parametric queries.
2) PreparedStatement is faster than Statement in Java.
3) PreparedStatement prevents SQL Injection Attacks in Java
Read more about Why to use Prepared Statements in Java here.
I have created a login form using java servlets and jsp's. The login information such as username and password is saved in Database.
My question is that when a user enters the information that my java class fails to find in database I dont get the exception. How could I create an exception if the login data isnt available in Db?
public boolean loginValidator(String e, String p) throws SQLException {
String userName = e;
String password = p;
boolean validate = false;
try{
PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE email = ? and password = ?");
ps.setString(1, userName);
ps.setString(2, password);
ResultSet rst = ps.executeQuery();
while (rst.next()) {
validate = (rst.getString("email").equals(userName)) && ((rst.getString("password").equals(password)));
}}
catch(SQLException ex){
System.out.println(ex.getMessage());
validate = false;
}
return validate;
}
This is actually a method in my java class that validates and send boolean type to a servlet and later servlet decides to direct or restrict the access to application subject to the boolean type returned.
PS: A new learner of javaWeb.
And a learner of SQL, right? Because there is NO exception, if there is no such line in the DB table. The query just returns empty ResultSet. So you have to check, whether the result set is empty or not (and then alternatively check the email and password - but that is IMHO superfluous).
public boolean loginValidator(String userName, String password) {
try{
PreparedStatement ps = connection.prepareStatement("SELECT * FROM user WHERE email = ? and password = ?");
ps.setString(1, userName);
ps.setString(2, password);
ResultSet rst = ps.executeQuery();
return rst.next(); // whether DB contains such record
} catch(SQLException ex){
ex.printStackTrace(); // TIP: use logging
}
return false;
}
Btw. I would strongly recommend you NOT to store plaintext passwords in the DB.
I am trying to ensure that when a user enters username & password, authentication is done by checking if input matches some row in the user table. Here is the code so far: It doesn't respond when the login button is click. Please suggest how I can set it right. Thanks
private void dbConnection()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
Statement stmt = conn.createStatement();
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
ResultSet rs = stmt.executeQuery(CHECK_USER);
while(rs.next())
{
String user = txtUser.getText();
String pass = txtPass.getText();
if(user.equals(rs.getString("username")))
{
if(pass.equals(rs.getString("password")))
{
this.dispose();
new AboutTo().setVisible(true);
}
else JOptionPane.showMessageDialog(null, "Invalid Password");
}
else JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
stmt.close();
rs.close();
conn.close();
}
catch(SQLException | ClassNotFoundException er)
{
JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
}
}
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
you have passed username & password in sql query so it go in while block only if username And password will match ...
you supposed to make sql querylike this
String CHECK_USER = "SELECT * FROM records";
or you can use if block like this
if(rs.next()
{
//login successfull code
}
else
{
//login fail
}
Basically, the logic is wrong.
What you are doing is approximately this.
Get a username and a password from the user.
Ask the database for all records for which the user name is matches the supplied username and the password matches the supplied password.
For each such record:
Test if the user name matches, and open a dialog if it doesn't match. That won't happen ... because you only selected records with that user name.
Test if the password matches, and open a dialog if it doesn't match. That won't happen ... because you only selected records with that password.
What you really ought to be doing is:
Get a username and a password from the user.
Select the records that match the user name and password.
Print a message if the number of records that you matched is zero.
I should also point out some other things:
Popping up a dialog box to tell the user his user name / password are wrong is beside the point. What you really need to do is tell something else in your server that the login failed.
When the user gets just the username or just the password incorrect, you should not offer him any clues that one was correct. Doing that makes it easier for "the bad guy" to work out the correct combination.
Storing passwords in clear in a database is Bad Practice. Best practice is to store seeded hashes of the passwords ... and use a cryptographically strong hashing function.
You forgot to call getText() on txtUser and txtPass.
This is how you could fix your query:
String CHECK_USER = "SELECT * FROM records WHERE username = '" + this.txtUser.getText() + "' AND password = '" + this.txtPass.getText() + "'";
You should note that concatenation of raw input text to queries will open vulnerability to SQL injection. You should use PreparedStatement instead so that the input text is properly escaped.
The following is a way to implement this properly, however lacks the following things that should be of concern to you:
You are storing passwords in clear text. You should use a hashing function such as SHA-1.
Every authentication will result in a new connection to the database. You should probably use a proper connection pool.
.
private boolean authenticate() throws SQLException {
String dbUrl = "jdbc:mysql://localhost:3306/maths_tutor";
// This query will simply count the matching rows, instead of actually selecting
// them. This will result in less bandwidth between your application and the server
String query = "SELECT count(*) AS num_records FROM records WHERE username = ? AND password = ?";
// Obtaining the username and password beforehand could perhaps make it more clear
// and prevent errors instead of pulling the data every time you need it
String username = txtUser.getText();
String password = txtPass.getText();
// The try-with-resources block will make sure the resources are closed once we are done with
// them. More information available at
// http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
try (
// Open database connection
Connection conn = DriverManager.getConnection(dbUrl, "root", "jesus");
// Prepare the statement
PreparedStatement stmt = conn.prepareStatement(query)
) {
// Set the username and password for the SQL statement
stmt.setString(1, username);
stmt.setString(2, password);
// Execute the query in a try block, to ensure that the resources
// will be released
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
// If we got 1 or more matches, this means we successfully
// authenticated. Otherwise, we failed authentication.
return rs.getInt("num_records") > 0;
}
}
}
// Failed authentication.
return false;
}
// Rename this to something meaningful according to your application
private void doAuthentication() {
try {
if (authenticate()) {
// Do successful authentication handling
this.dispose();
new AboutTo().setVisible(true);
} else {
// Do failed authentication handling
JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
} catch(SQLException er) {
// Do error handling
JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
}
}
The possible error would be near this line
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
first make sure you have set the classpath and added the mysql driver to the project
second I would the following instead of the above, in fact why do you make things to much complex?!
java.sql.Driver _dr=new com.mysql.jdbc.Driver();
java.util.Properties _pr=new java.util.Properties();
_pr.setProperty("user","root");
_pr.setProperty("password","jesus");
Connection conn = _dr.connect("jdbc:mysql://localhost:3306/maths_tutor", _pr);
and the last thing is beware about using this like of code
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
so here the system is ready for injection.
so the good way would be like this, using parameters.
String CHECK_USER = "SELECT * FROM records WHERE username = ? AND password = ?";//this will avoid sql injection
java.sql.PreparedStatement _st=conn.prepareStatement(CHECK_USER);
_st.setString(1, this.txtUser);
_st.setString(1, this.txtPass);
EDIT :by the way, there is no need to iterate over result set! simple just call the next() method, if it returns true, so it means user has entered correct user/pass, else otherwise.
ResultSet rs = stmt.executeQuery(CHECK_USER);
if(rs.next()){/*user exist*/
this.dispose();
new AboutTo().setVisible(true); }
else{
JOptionPane.showMessageDialog(null, "Invalid Username or Password");
}
string query = "SELECT count(*) FROM [dbo].[login1] WHERE username='" + username.Text + "' and password='" + password.Text + "'";
SqlDataAdapter sda = new SqlDataAdapter(query, con);
DataTable dt = new DataTable();
sda.Fill(dt);
if (dt.Rows[0][0].ToString() == "1")
{MessageBox.Show("YEAH");}
The title is the error I'm getting, when I click load my program freezes. I assume it's because I'm doing a statement inside a statement, but from what I see it's the only solution to my issue. By loading, I want to just repopulate the list of patients, but to do so I need to do their conditions also. The code works, the bottom method is what I'm trying to fix. I think the issue is that I have 2 statements open but I am not sure.
load:
public void DatabaseLoad()
{
try
{
String Name = "Wayne";
String Pass= "Wayne";
String Host = "jdbc:derby://localhost:1527/Patients";
Connection con = DriverManager.getConnection( Host,Name, Pass);
PatientList.clear();
Statement stmt8 = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String SQL8 = "SELECT * FROM PATIENTS";
ResultSet rs8 = stmt8.executeQuery( SQL8 );
ArrayList<PatientCondition> PatientConditions1 = new ArrayList();
while(rs8.next())
{
PatientConditions1 = LoadPatientConditions();
}
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String SQL = "SELECT * FROM PATIENTS";
ResultSet rs = stmt.executeQuery( SQL );
while(rs.next())
{
int id = (rs.getInt("ID"));
String name = (rs.getString("NAME"));
int age = (rs.getInt("AGE"));
String address = (rs.getString("ADDRESS"));
String sex = (rs.getString("SEX"));
String phone = (rs.getString("PHONE"));
Patient p = new Patient(id, name, age, address, sex, phone,
PatientConditions1);
PatientList.add(p);
}
UpdateTable();
UpdateAllViews();
DefaultListModel PatientListModel = new DefaultListModel();
for (Patient s : PatientList) {
PatientListModel.addElement(s.getAccountNumber() + "-" + s.getName());
}
PatientJList.setModel(PatientListModel);
}
catch(SQLException err)
{
System.out.println(err.getMessage());
}
}
This is the method that returns the ArrayList of patient conditions
public ArrayList LoadPatientConditions()
{
ArrayList<PatientCondition> PatientConditionsTemp = new ArrayList();
try
{
String Name = "Wayne";
String Pass= "Wayne";
String Host = "jdbc:derby://localhost:1527/Patients";
Connection con = DriverManager.getConnection( Host,Name, Pass);
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String SQL = "SELECT * FROM PATIENTCONDITIONS";
ResultSet rs5 = stmt.executeQuery( SQL );
int e = 0;
while(rs5.next())
{
e++;
String ConName = (rs5.getString("CONDITION"));
PatientCondition k = new PatientCondition(e,ConName);
PatientConditionsTemp.add(k);
}
}
catch(SQLException err)
{
System.out.println(err.getMessage());
}
return PatientConditionsTemp;
}
I had a similar problem.
I was connecting to derby db hosted on local server.
I created 2 simultaneous connections:
With squirrel
With ij tool
When a connection makes a modification on a table, it first gets a lock for the particular table.
This lock is released by the connection only after committing the transaction.
Thus if the second connection tries to read/write the same table, a msg prompts saying:
ERROR 40XL1: A lock could not be obtained within the time requested
To fix this, the connection which modified the table has to commit its transaction.
Hope this helps !
Here is a good place to start: http://wiki.apache.org/db-derby/LockDebugging
You need to close your statement and result set as well so that when you restart your program they won't be open. Add stmt.close(); and rs.close(); at the end of your lines of code within the try and catch statement.
Why could you not use the same connection object to do both the queries?
Like pass that connection object to the LoadPatientConditions() as a parameter and use it there.