2016-12-23 3 views
0

Я вернулся в Java недавно после значительного количества времени с Python, и я снова пытаюсь с ним поправиться. Мой первый желаемый проект состоял в том, чтобы создать небольшое приложение, в котором вы можете (во-первых) войти. Я использую mySQL для хранения базы данных имен пользователей и паролей.Как «извлечь» переменную из других классов или методов?

До сих пор я использовал графический интерфейс Swing от Java, чтобы создать всплывающее окно с запросом на вход в систему. Введенное имя пользователя и пароль проверяются на те, которые указаны в таблице SQL.

Проблема в том, что я использую цикл while для проверки входов в таблицу SQL. Таким образом, введенная информация проверяется на каждый ключ и значение в Hashmap, созданном из таблицы SQL.

Я не уверен, как «извлечь» мою переменную g (Hashmap) из цикла while и инструкции try SQL, чтобы я мог использовать ее после того, как она была заполнена данными mySQL.

Я использую Eclipse (Java Neon).

Я не знаю, как «извлечь» хэш-карту, и когда я пытаюсь заставить цикл while или try возвращать hashmap, Eclipse сообщает мне, что методы void не могут вернуть значение (ясно). Тем не менее, я не могу изменить тип возврата из void в HashMap) String, String> потому что «Тип возврата несовместим с ActionListener.actionPerformed (ActionEvent e)» и «реализует java.awt.event.ActionListener.actionPerformed».

Вот мой код:

import javax.swing.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.util.HashMap; 
import java.util.Map; 

public class Hello0 extends JFrame { 
    private static final long serialVersionUID = 1487932324102279819L; 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("Frame Demo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(350, 200); 

     JPanel panel = new JPanel(); 
     frame.add(panel); 
     placeComponents(panel); 

     frame.setVisible(true); 
    } 


    private static void placeComponents(JPanel panel) { 

     panel.setLayout(null); 
     JLabel userLabel = new JLabel("Username"); 
     userLabel.setBounds(10, 20, 80, 25); 
     panel.add(userLabel); 

     JTextField userText = new JTextField(20); 
     userText.setBounds(100, 20, 165, 25); 
     panel.add(userText); 

     JLabel passwordLabel = new JLabel("Password"); 
     passwordLabel.setBounds(10, 50, 80, 25); 
     panel.add(passwordLabel); 

     JPasswordField passwordText = new JPasswordField(20); 
     passwordText.setBounds(100, 50, 165, 25); 
     panel.add(passwordText); 

     JButton loginB = new JButton("Login"); 
     loginB.setBounds(10, 80, 80, 25); 
     panel.add(loginB); 

     loginB.addActionListener(new ActionListener() { 

      public HashMap<String, String> actionPerformed(ActionEvent e) { 
       String username0 = "root"; 
       String password = "javaSQLmy98"; 
       try { 

        String url = "jdbc:mysql://localhost:3306/javabase?useSSL=false"; 
        Connection connection = DriverManager.getConnection(url, username0, password); 
        PreparedStatement stmt0 = connection.prepareStatement("SELECT * from userids"); 

        String pass0 = null; 
        String user1 = userText.getText().toString(); 
        char[] pass1 = passwordText.getPassword(); 
        pass0 = String.valueOf(pass1); 
        System.out.println(user1); 
        System.out.println(pass1); 

        ResultSet rs = stmt0.executeQuery(); 
        rs = stmt0.executeQuery("SELECT * from userids "); 
        while (rs.next()) { 

         String user = rs.getString("username"); 
         String pass = rs.getString("paswrd"); 

         Map<String, String> g = new HashMap<>(); 
         g.put(user, pass); 
         return g; 
         // This was the alternative: if(g.keySet().contains("Jacob") && g.values().contains("root")) { 


         /*This code below was originally outside the while loop but I could not 
         figure out how to make it work without it being inside, and accessible 
         to the hashmap g. Now it is being checked each time the while loop 
         is ran, with a new pair of usernames and passwords on each loop. */ 

         if (user1.equals(user) && pass0.equals(pass)) { 
          System.out.println("Good!"); 
         } 

         /*The problem here is that the checker IS inside the loop, so it 
         tests the input against each of the entries in the SQL table. */ 
         else { 
          System.err.println("The username or password is incorrect."); 
         } 
        } 

        connection.close(); 
       } catch (Exception e1) { 
        System.err.println(e1.getMessage()); 
       } 

      } 
     }); 

    } 

} 

Ура!

+0

Почему вы загружаете все в HashMap вместо того, чтобы просто включать предложение WHERE в ваш SQL-запрос? –

+0

Вы понимаете, как написать запрос в SQL, чтобы получить одну строку для идентификатора пользователя, вместо того, чтобы перебирать все строки в таблице? –

+0

@RiaanNel Я не уверен, как это поможет. Разве слово WHERE просто не действует как фильтр? –

ответ

0

Если вы добавите предложение WHERE к вашему запросу, оно вернет только данные, соответствующие критериям. Другими словами, запрос ниже (очевидно, с правильными значениями) вернет указанную запись userid, если она существует, иначе она вернет пустой набор результатов.

SELECT * from userids 
WHERE userName = 'user1' 
AND passwrd = 'pass1' 

Вы можете сделать прочь со всей в то время как петли и HashMap, а код можно упростить следующим образом:

if (rs.next()) { 
    System.out.println("Good!"); 
} else { 
    System.err.println("The username or password is incorrect."); 
} 

Кроме того, как было предложено ранее, если это нечто большее, чем программирование, пароли должны быть хэшированы вместо того, чтобы храниться в текстовом формате.

+0

Это полезно для определенных значений «user1» и «pass1», но как использовать вход для имени пользователя и пароля? –

+0

Любая хорошая старая конкатенация строк по линиям «SELECT ...» + пользователь + «AND ...» + pass (что плохо, потому что оно оставляет вас уязвимым для SQL-инъекции), или вы можете использовать PreparedStatement (предпочтительный вариант). http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html –

+0

Вышлите решение своей проблемы? Если да, пожалуйста, отметьте ответ как принятый. http://stackoverflow.com/help/someone-answers –

1

Чтобы получить доступ к g за пределами while, вы должны объявить его вне while, так как каждый {} в Java прицелы переменные внутри него. Таким образом,

Map<String, String> g = new HashMap<>(); 
while (condition) { 
    // do something 
    g.put(key, value); 
} 
// do something with g 

Но в этом случае вы можете выполнить проверку непосредственно в SQL, что должно быть намного более эффективным.


Примечание стороны:

Не храните пароли. Don't store passwords.Hash+Salt passwords (or better, use a library).

+0

Спасибо за хороший ответ и предложения. Объявление его за пределами цикла while создаст пустой Hashmap? И затем я заполняю его внутри цикла while, но могу использовать его снаружи из-за того, где он был объявлен? –

+0

@JacobAdamczyk точно – CAD97

0

Попробуйте это:

Map<String, String> g = new HashMap<String, String>(); 
while(rs.next()) { 
    String user = rs.getString("username"); 
    String pass = rs.getString("paswrd"); 
    g.put(user, pass); 

    ..... 
} 

Примечание: Принимая имя пользователя в качестве ключа в HasmMap не является хорошим программирования, потому что может быть несколько пользователей с таким же именем.

+0

Какую же структуру данных вы бы рекомендовали? –

+0

Это зависит от ваших текущих требований. вы можете установить Set или если вы хотите пойти с Картой, то вы можете пойти с Картой . Где ключ будет вашим идентификатором пользователя типа long, а значение будет POJO-классом. – SujitKumar

+0

Над классом POJO будут обладать такими свойствами, как userId, имя пользователя, пароль и т. Д. – SujitKumar

Смежные вопросы