Sybase Query with Java Prepared Statements Not Working - java

I have a web application using Java/JSP that was running off a MySQL database which I've now moved to Sybase.
I've changed what I believe are all the relevant connection parts (Sybase Connector and relevant code)
I've been using PreparedStatements for my queries. What was working in MySQL is now no longer returning anything (errors or results).
The first simple query I've been testing is a login form which should be matching the user values for name and password in the table "appuser".
The Prepared Statement in the code provided used to work but no longer does with Sybase.
Relevant code is below. Let me know if anything else is needed.
public void connectDB() throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException
{
/* String userName="****";
String password="******";
String url="jdbc:sybase:sybdev1dw/ETL_MON";
Class.forName("com.sybase.jdbc4.jdbc.SybDriver").newInstance();
conn=DriverManager.getConnection(url, userName, password); */
String driver = "com.sybase.jdbc2.jdbc.SybDriver";
String host = "********";
String dbName = "********";
String url = "jdbc:sybase:Tds:" + host + ":4110" +"?SERVICENAME=" + dbName;
String username = "*******";
String password = "*********";
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
System.out.println("Connection successful"+conn);
}
public Boolean loginAction(String name, String pass, String role,HttpServletRequest request) throws SQLException {
Boolean valid=false;
session=request.getSession();
PreparedStatement stmt=conn.prepareStatement("SELECT pass FROM appuser WHERE name=?");
stmt.setString(1, name);
results=stmt.executeQuery();
System.out.println("loginAction:"+results.getFetchSize());
while(results.next())
{
if(results.getString("pass").equals(pass))
{
valid=true;
session.setAttribute("name",name);
session.setAttribute("role",role);
}
else
{
valid=false;
}
}
System.out.println("loginAction:"+valid);
return valid;
}

String compare is failing possibly because of spaces being padded to the database column.
result.getString("pass").trim().equals(pass.trim())
One other suggestion. Instead of doing a while(results.next()) , do an if(results.next()) if you are confident it will always return exactly one row ( or zero ).

Related

Connecting web app on Glassfish to an Oracle database

I'm currently working on this dynamic web project. I have a database and table that I've created in Oracle.
What I need to do right now is have this table connected to my project so that I can retrieve the data from there.
I read that I will need a JDBC driver downloaded and I found it here
But, it's not clear which one is the right one to download and where should I place it after that? in connection pool through admin console?
all toturials I see are related to mySql even this one:
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// JDBC driver name and database URL
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL="jdbc:mysql://localhost/TEST";
// Database credentials
static final String USER = "root";
static final String PASS = "password";
How can I use the same thing for oracle?
It is a example, how to connect to DB and to retrieve data from DB. I hope it is useful for you. Don't forget about try catch finally.
Read this topic.
Closing Database Connections in Java
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:#127.0.0.1:1521:xe"; //127.0.0.1 = localhost, 1521 = standard port, xe - DB name
String user = "root";
String password = "password";
Connection con = DriverManager.getConnection(url, user, password);
//To create sql query
PreparedStatement preparedStatement = con.prepareStatement("SELECT * FROM person");
//Response of your sql query
ResultSet resultSet = preparedStatement.executeQuery();
//For example you have table (Int id, String firstName, String lastName )
while(resultSet.next()){
//Prepare your data with your program logic....
int id = resultSet.getInt(1);
String firstName = resultSet.getString(2);
String lastName = resultSet.getString(3);
Person p = new Person(id, firstName, lastName);
}
Can you check the JDK version and the JDBC driver version that you are using? Both should be compatible. Check out the FAQ for more information.

JDBC - authorization users via database

I've made a program which is getting data from database and then authorizing, but the problem is only the last record is correct - logging in is succesful.
public class Test {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/uzytkownicy";
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) throws SQLException, ClassNotFoundException {
System.out.print("login: ");
Scanner zm1= new Scanner(System.in);
String name = zm1.next();
System.out.print("pass: ");
Scanner zm2 = new Scanner(System.in);
String password = zm2.next();
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting...");
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
Statement stmt = conn.createStatement();
String sql = "SELECT logins, passwords FROM users";
ResultSet rs = stmt.executeQuery(sql);
String databasePassword = null;
String databaseUsername = null;
while (rs.next()) {
databaseUsername = rs.getString("logins");
databasePassword = rs.getString("passwords");
}
if (name.equals(databaseUsername) && password.equals(databasePassword)) {
System.out.println("Logged in!");
}
else {
System.out.println("Bad Pass/Login");
}
rs.close();
stmt.close();
conn.close();
}
catch(SQLException se){
se.printStackTrace();
}
}
}
If I'm understanding what you're trying to do (which I may not be), your problem is that the comparison of username and password is outside the while loop, so your:
while (rs.next())
just loops through the entire result set, so when the while loop ends, databaseUsername and databasePassword will be set to the values from the last row read.
Instead, move the comparison inside the loop and set a flag (defaulting to false) and break out of the loop if the correct username and password is found, then use that flag to determine what to print.
Also, you might want to read up on parameterized queries. You can actually have the database do all the work for you by using a PreparedStatement and making your query:
SELECT 1 from users where logins = ? and passwords = ?;
If the result set contains anything, then the user entered a valid username and password, otherwise they didn't. The question marks in the query would be set to name and password using the set* methods of PreparedStatement.
Another note--storing plaintext passwords is a horrible idea. If the table storing the passwords is exposed (through various attacks or just a disgruntled employee stealing it), then everyone has all your users' passwords. Eek! You might argue that you'll take steps to prevent that, but from a security perspective, it's best to assume someday the table will be compromised, and do everything you can to ensure that it's not too harmful.

Duplicate entry whilst using Insert in preparedStatment and retrieving previous data whilst matching results

public int addUsers(int USER_ID,String FIRST_NAME,String LAST_NAME,String PASSWORD,String USERNAME,String USER_PERMISSION) throws SQLException {
Connection conn = null;
conn = getConnectivity(conn) ;
getConnectivity(conn);
String sqlSelect = "SELECT * from USER_DETAILS";
PreparedStatement pres = conn.prepareStatement(sqlSelect);
ResultSet rs1 = pres.executeQuery();
if(rs1.next()){
String Username = rs1.getString(5);
System.out.println("username found "+Username);
System.out.println("username input " + USERNAME);
System.out.println("password input " + PASSWORD);
if (Username.equals(USERNAME)){
System.out.println("Username already exists");
conn.close();
}
else{
System.out.println("FOUND ELSE");
String sql = "INSERT INTO USER_DETAILS VALUES (?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, USER_ID);
ps.setString(2, FIRST_NAME);
ps.setString(3,LAST_NAME);
ps.setString(4,PASSWORD);
ps.setString(5,USERNAME);
ps.setString(6,USER_PERMISSION);
int result = ps.executeUpdate();
System.out.println(result);
}
}
conn.close();
return USER_ID;
}
and for login I am using
public boolean login(String USERNAME, String PASSWORD) throws SQLException
{
boolean result = false;
Connection conn = null;
conn = getConnectivity(conn) ;
String sqlSelect = "SELECT * from USER_DETAILS";
PreparedStatement pres = conn.prepareStatement(sqlSelect);
ResultSet rs1 = pres.executeQuery();
if(rs1.next()){
String Username = rs1.getString(5);
String Password = rs1.getString(4);
String UserPermission = rs1.getString(6);
System.out.println("username found "+Username);
System.out.println("username input " + USERNAME);
System.out.println("password input " + PASSWORD);
if (Username.equalsIgnoreCase(USERNAME) && Password.equalsIgnoreCase(PASSWORD) && UserPermission.equalsIgnoreCase("blocked")){
System.out.println("User Logged in");
conn.close();
}
System.out.println("gets out of the code");
}
conn.close();
return result;
}
first of all it is allowing to enter more than one entry, so duplicates occurring regardless of my if statement, and when i add fresh new data and try to see I can log in, it still compares with previously added data and does not work. Can someone see what am i doing wrong here. please thanks
below is the system print out i get ,
Connection Valid
username found kamran (don't know why he is still picking up this column)
username input macbook (these i have already in my database)
password input hello (these i have already in my database)
gets out of the code
Connection Valid
Connection Valid
username found kamran (don't know why he is still picking up this column)
username input macho (these i have already in my database)
password input hello (these i have already in my database)
FOUND ELSE (dont know why it adds data when they already exist in database)
1
Your code doesn't make sense: you are querying for all users and only checking the first returned user if it matches. Of course that is going to fail if the first returned user doesn't match: in addUsers you will try to add the user if the first user returned doesn't match, in login a user can only login if it is the first user.
You need to use a WHERE clause to only request the user you want to check:
// Note: this assumes a case insensitive collation
String sqlSelect = "SELECT * from USER_DETAILS WHERE username = ?";
try (PreparedStatement pres = conn.prepareStatement(sqlSelect)) {
pres.setString(1, USERNAME);
try (ResultSet rs1 = pres.executeQuery()) {
if (!rs1.next) {
// user doesn't exist yet, create...
}
}
}
You need to do something similar for login (but then with if (rs1.next()) instead).
There are more problems with your current code: you are storing plaintext passwords: you should really hash them with a strong password hash like PBKDF2. Also please follow the java naming conventions. Variables and parameters are camelcase so not USERNAME but username (or userName), not UserPermission, but userPermission. This improves the readability for people who are used to the java naming conventions.

Trouble inserting data into a MySQL database

I am developing a desktop application in Netbeans. I am trying to insert a record into database. The very strange problem I am having is that when I press the save button no error occurs, everything works perfect. But when I check my DB, there is no data in there. But when I try to insert data directly in phpmyadmin through query then it inserts the record after the ID (auto increment) that has been generated before when I try to save data through desktop app. I know It is difficult to explain. Let me give you all a bit more explanation
For example my database is all clear and I am trying to save my first record
Through desktop app I pressed the save button
when I checked the database there is no record there
Here above If data was saved successfully then the record ID has to be 1
But now I am inserting the record by going into phpmyadmin and manually typing the quering in sql tab
now the id of the record should be 1 but the id is 2.
So it means through desktop app data is saving but somewhere hidden which I can't see and also It is remembering the id. I hope you undertstand my question.
If I pressed save button 3 times after then I insert some data in phpmyadmin the id of that record is 4.
I don't know what the problem is?
Here is my code :
public class DBConnectionManager {
private static String DRIVER_NAME = "com.mysql.jdbc.Driver";
private static String HOST_NAME = "localhost";
private static String PORT_NUMBER = "3306";
private static String DB_NAME = "sales";
private static String USER_NAME = "root";
private static String PASSWORD = "";
public static Connection openConnection() throws Exception {
Class.forName(DRIVER_NAME);
String jdbcURL = "jdbc:mysql://"+HOST_NAME+":"+PORT_NUMBER+"/"+DB_NAME;
Connection connection = DriverManager.getConnection(jdbcURL,USER_NAME,PASSWORD);
connection.setAutoCommit(false);
return connection;
}
}
public void addSupplierDetail() {
String contact_name = txt_contactName.getText();
String shop_name = txt_shopName.getText();
String city = txt_city.getText();
int phone = Integer.parseInt(txt_phone.getText());
int mobileNo = Integer.parseInt(txt_mobile.getText());
String address = txt_address.getText();
Supplier supplier = new Supplier();
supplier.setContactName(contact_name);
supplier.setShopName(shop_name);
supplier.setCity(city);
supplier.setPhone(phone);
supplier.setMobileNo(mobileNo);
supplier.setAddress(address);
connection = DBConnectionManager.openConnection();
SupplierDAO dao = new SupplierDAO(connection);
try {
if (dao.addSupplier(supplier)) {
connection.close();
JOptionPane.showMessageDialog(null, "data save");
// Dashboard dashboard = new Dashboard();
//dashboard.setVisible(true);
} else {
JOptionPane.showMessageDialog(null, "not saved");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
public boolean addSupplier(Supplier supplier) throws Exception {
String sql = "INSERT INTO suppliers"
+ "(sup_name,sup_address,city,mobile_no,phone,shop_name)"
+ "VALUES (?,?,?,?,?,?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, supplier.getContactName());
ps.setString(2, supplier.getAddress());
ps.setString(3, supplier.getCity());
ps.setInt(4, supplier.getMobileNo());
ps.setInt(5, supplier.getPhone());
ps.setString(6, supplier.getShopName());
System.out.println(ps);
int rowscount = ps.executeUpdate();
System.out.println("no of rows updated: " + rowscount);
ps.close();
return rowscount > 0;
}
try the debugger, if everything is executed as expected, check the autoCommit property of your statement (or connection I forgot to which one it is bound)
Since the auto-increment seems to be happening, as you said. Looks like auto commit is set to false. You can try to set it at connection level, by calling connection.setAutoCommit(true) or you can do it only for that transaction by calling connection.commit().

Validate email address and password

How do I validate a certain email and password while an user logs in?
protected void doPost(HttpServletRequest request, HttpServletResponse res) throws IOException, ServletException {
String email=request.getParameter("email");
String pass=request.getParameter("pass");
OutputStream out = res.getOutputStream();
try{
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:8080/college", "root", "root");
Statement st=con.createStatement();
String strSQL = "SELECT email,password FROM student";
How do I continue after the SELECT statement? I would prefer using the if...else statement to do the validation.
First close all connection resources properly - use a Java 7 try-with-resources.
Here is an simple example:
final String email = request.getParameter("email");
final String pass = request.getParameter("pass");
try (final Connection con = DriverManager.getConnection("jdbc:mysql://localhost:8080/student", "root", "root");
final PreparedStatement statement = con.prepareStatement("SELECT COUNT(*) AS count FROM student WHERE email=? AND password=?");) {
statement.setString(1, email);
statement.setString(2, pass);
try (final ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
final int rows = resultSet.getInt("count");
if (rows > 1) {
throw new IllegalStateException("More than one row returned!");
}
boolean validUser = rows == 1;
}
}
}
But really you should hash passwords in the database. Use something like jBcrypt. Your code would then look like:
final String email = request.getParameter("email");
final String pass = request.getParameter("pass");
try (final Connection con = DriverManager.getConnection("jdbc:mysql://localhost:8080/student", "root", "root");
final PreparedStatement statement = con.prepareStatement("SELECT pass FROM student WHERE email=?");) {
statement.setString(1, email);
statement.setString(2, pass);
try (final ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
final String hash = resultSet.getString("pass");
final boolean valid = BCrypt.checkpw(pass, hash);
}
}
}
Obviously you need to add error checking if there are no rows returned from the query. You also need to check that only one row is returned. But I leave that as an exercise.
you can use if, if you like. Use the input as your where statement and then check to see if there is a match, error or null, then execute whatever you want it to do.
You can use email and password in the SQL statement itself. like:
SELECT email, password from student where email = ? and password = ?
prepare above statement and bind the parameters.
This way validation will be done on the DB and you just need to check the result count (which has to be 1). You should have index on email column to have better SQL performance.
Do you relay need to fetch all students?
PreparedStatement st = con.prepareStatement("SELECT count(*) FROM student WHERE email=? AND password=?");
st.setString(1, email);
st.setString(2, pass);
ResultSet rs = st.executeQuery();
rs.next();
int count = rs.getInt(1);
if (count == 1) {
// password and email are correct
}
For this answer, I'll assume that by "validate email and password", what you mean is you want to authenticate the user based on their email address and a password. And not that you want to check whether the email address is a real email address.
So, the first thing you need to do is encrypt the passwords in your database, using a hash algorithm and a random salt. You record the salt alongside the hashed password.
Next thing is, when the user logs in, you look up the salt for that user, and you perform the same hash with the salt. Then you compare the result of that with the previously saved password hash, and if they're the same, then the passwords were the same.
It's important that the salt be random and different for every user.
Plenty of reading to be found on the above terms on the Internets.
Once you've done that, you should also apply the very sensible suggestions in other answers to only select the user you want, and handle your resources correctly.
WARNING I am not an expert on security, and neither are you. If you're implementing a log-in system for an exercise, fine. If it's for the real world, use something that's been written by someone who knows what they're doing.

Categories

Resources