尝试检查json文件中的用户名和密码,看看学生是否可以登录



这是我迄今为止的代码。我已经创建了整个登录屏幕和登录按钮。现在我有了它,这样按钮在按下时就会消失,但我希望能够检查JSON文件以确认用户名和密码,然后转到下一个屏幕。

登录屏幕:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
public class LoginPage extends JPanel implements ActionListener {
private static final long serialVersionUID = -337449186297669567L;
private JLabel user_label = new JLabel("Username: ");
private JLabel password_label = new JLabel("Password: ");
private JLabel screenName = new JLabel("Login",SwingConstants.CENTER);
private JTextField username = new JTextField(10);
private JTextField password = new JTextField(10);
private JButton login, cancel;
private JPanel panel = new JPanel();
private String hidden = "login";

public LoginPage() {
System.out.println("Creating the label panel");
setBorder(BorderFactory.createEtchedBorder());
setLayout(new GridLayout(0, 1));
add(screenName);
add(user_label);
add(username);
add(password_label);
add(password);
login = new JButton("LOGIN");
setVisible(true);
addToggleListener();
initialize();
//setVisible(true);
}
public void initialize(){
JPanel buttonPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
add(buttonPanel);
c.weightx = 0.6;
c.weighty = 0.6;
c.gridx = 1;
c.gridy = 1;

c.fill = GridBagConstraints.NONE;
c.insets = new Insets(10, 50, 10, 20);
login.setPreferredSize(new Dimension(100,50));
c.anchor = GridBagConstraints.SOUTHEAST;
buttonPanel.add(login,c);
}
public void setText(String s) {
screenName.setText(s);
}
public boolean isLabelVisible() {
return screenName.isVisible();
}
public void setLabelVisibility(boolean value) {
screenName.setVisible(value);
}


public void addToggleListener(ActionListener al){
login.addActionListener(al);
}
public void addToggleListener() {
login.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
if(hidden.equals("login")){
login.setVisible(false);
} else {
login.setVisible(true);
}
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

Main,其中包含json文件的代码:

import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.enterprise.util.TypeLiteral;
import javax.json.bind.Jsonb;
import javax.json.bind.JsonbBuilder;
public class Main {
public static void main(String[] args) {
AppFrame frame = new AppFrame();
LoginPage lp = new LoginPage();
ToggleListener tl = new ToggleListener(lp);
lp.addToggleListener(tl);
frame.setLayout(new BorderLayout());
frame.add(lp, BorderLayout.CENTER);
frame.setVisible(true);
List<Student> studentList = new ArrayList<>();
addAnisa(studentList);
Jsonb jsonb = JsonbBuilder.create();
String jsonStudent = jsonb.toJson(studentList);
java.lang.reflect.Type t = new TypeLiteral<List<Student>>(){}.getType();
List<Student> l2 = jsonb.fromJson(jsonStudent, t);
String homeDirectory = System.getProperty("user.home");
Path p = Paths.get(homeDirectory + "/NetBeansProjects");
if(!Files.exists(p)){
File f = new File(homeDirectory + "/NetBeansProjects");
if(!f.mkdir()){
System.out.println("Nope");
}
}   
String s = homeDirectory + "/NetBeansProjects/studentInfo.json";
p = Paths.get(s);
File f2 = new File(s); 
try{
System.out.println("writing out file");
System.out.println(f2.getAbsoluteFile());
FileWriter fw = new FileWriter(f2.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw); 
bw.write(jsonStudent);
bw.close();
}
catch(IOException e){
e.printStackTrace();
System.exit(-1);
}


}
private static void addAnisa(List<Student> list){
Student s = new Student();

s.setFirstName("Anisa");
s.setLastName("Callis");
List<LoginInfo> loginInfo = new ArrayList<>();
LoginInfo LI = new LoginInfo();
LI.setUsername("amc123");
LI.setPassword("demo2021");
loginInfo.add(LI);
s.setLoginInfo(loginInfo);
list.add(s);

}
}

框架:

import javax.swing.*;
public class AppFrame extends JFrame {
private static final long serialVersionUID = -337449186297669567L;
public AppFrame(){
setTitle("Plan & Earn");
setSize(400, 400);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

学生登录信息:

public class LoginInfo {
String username;
String password;
public LoginInfo(){

}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}

}

json文件的学生信息:

import java.util.ArrayList;
import java.util.List;
public class Student {
String firstName; 
String lastName; 
private List<LoginInfo> loginInfo;



public Student(){

}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<LoginInfo> getLoginInfo() {
return loginInfo;
}
public void setLoginInfo(List<LoginInfo> loginInfo) {
this.loginInfo = loginInfo;
}
@Override
public String toString(){
return "Student{" + "firstName=" + firstName + ", lastName=" + lastName + ", Login Info=" + loginInfo + '}';
}

}

好吧,你正朝着正确的方向前进。你要考虑的一些事情是:

  1. 提供一个独立的管理者/服务来管理学生。这将负责加载、更新和一般管理学生,最好以某种方式将物理";如何";远离应用程序的其他部分(没有人关心它是否有JSON文件支持,他们只关心"做事")
  2. 提供某种独立于UI的身份验证工作流。LoginPage的职责是收集用户的信息。它不负责";如何";用户已通过身份验证
  3. LoginPage提供某种回调,以通知相关方学生已登录

主要目标是减少系统的耦合(系统的任何一个部分依赖于另一个部分的量)。在设计解决方案时,您希望始终考虑修改解决方案的任何一个部分有多难,以及这可能对系统的其他部分产生多大影响。

例如,如果您决定将学生管理转移到SQL数据库或web服务,这会对解决方案的其他部分产生什么影响。如果你发现自己不得不对解决方案的其他部分进行重大修改,那么它是紧密耦合的,这不是一件好事。

有很多方法可以解决这些问题,但以下是一些你应该记住的基本设计原则:

  • 委派模式
  • 依赖项注入
  • 观察员

还有关于系统任何部分真正需要多少信息的讨论,例如,LoginPage并不真正需要访问学生数据库,这不是它的责任,所以我们应该"隐藏";从中提取细节,只为其提供工作真正需要的细节。

这就是你会发现";代码到接口";强大的

  • 更智能的Java开发
  • OOP良好实践:接口编码
  • 还有更多,只是谷歌

好吧,但这有什么帮助?其实很多。

让我们从LoginPage开始。它想。。。

  • 从用户处获取用户的登录凭据
  • 根据系统验证凭据
  • 身份验证成功时通知相关方

首先,我们需要一些与物理实现解耦的方式来验证用户(即"委托")。。。

public interface Authenticator {
public Student authenticate(String userName, char[] password);
}

我知道,你很失望,但这真的很强大。这为LoginPage提供了将凭证传递到某个系统的能力,并使其根据自己的内部需求返回StudentnullLoginPage不在乎。因此,我们可以实现一系列不同的工作流程,LoginPage永远不会改变,赢得

接下来,我们需要LoginPage在身份验证成功时通知相关方(即"观察者")。。。

public class LoginPage extends JPanel {
public static interface LoginListener {
public void loginWasSucessful(LoginPage source, Student student);
}

现在,我已经将其定义为内部interfaceLoginPage,这主要是通过这种方式完成的,因为LoginListener只会在LoginPage的上下文中使用,但如果您愿意,您可以在它自己的文件中将其声明为单独的interface,这无关紧要。重点是,这定义了一个合同,利益相关方可以被告知";成功登录";

现在,我们需要开始把它组合起来。

首先,我更新了您的LoginPage。我已经修改了构造函数以接受AuthenticatorLoginListener的实例。。。

public class LoginPage extends JPanel {
public static interface LoginListener {
public void loginWasSucessful(LoginPage source, Student student);
}
private static final long serialVersionUID = -337449186297669567L;
private JLabel user_label = new JLabel("Username: ");
private JLabel password_label = new JLabel("Password: ");
private JLabel screenName = new JLabel("Login", SwingConstants.CENTER);
private JTextField username = new JTextField(10);
private JPasswordField password = new JPasswordField(10);
private JButton login, cancel;
private JPanel panel = new JPanel();
private String hidden = "login";
private Authenticator authenticator;
private LoginListener loginListener;
public LoginPage(Authenticator authenticator, LoginListener loginListener) {
this.authenticator = authenticator;
this.loginListener = loginListener;

setBorder(new CompoundBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16), BorderFactory.createEtchedBorder()));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(screenName, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.LINE_END;
add(user_label, gbc);
gbc.gridy++;
add(password_label, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.LINE_START;
add(username, gbc);
gbc.gridy++;
add(password, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
login = new JButton("LOGIN");
add(login, gbc);
login.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
login.setEnabled(false);
Student student = authenticator.authenticate(username.getText(), password.getPassword());
if (student != null) {
loginListener.loginWasSucessful(LoginPage.this, student);
} else {
JOptionPane.showMessageDialog(LoginPage.this, "Authentication failed", "Error", JOptionPane.ERROR_MESSAGE);
}
login.setEnabled(true);
}
});
}
}

有趣的部分在最后,我们处理loginActionEvent

接下来,我们需要一些方法来实际验证用户,为此,我写了一个超级简单的";认证器";

public class DefaultAuthenticator implements Authenticator {
private List<Student> students;
public DefaultAuthenticator(List<Student> students) {
this.students = students;
}
@Override
public Student authenticate(String userName, char[] password) {
for (Student student : students) {
for (LoginInfo loginInfo : student.loginInfo) {
if (userName.equals(loginInfo.getUsername()) && Arrays.equals(loginInfo.getPassword().toCharArray(), password)) {
return student;
}
}
}
return null;
}
}

这是为了测试目的。当你建立你的";学生经理";,我很想直接使用implementAuthenticator,或者将其传递(注入)到上面的实现中,这在当时对您来说是最合适的。

下一部分是测试它!为此,我构建了一个简单的StudentLoginInfo,它们被传递到DefaultAuthenticator中。然后,它被传递到我的主面板,负责设置主UI。。。

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// Load student information, maybe through some kind
// of student service
LoginInfo loginInfo = new LoginInfo("test", "1234");
List<LoginInfo> loginList = new ArrayList<>();
loginList.add(loginInfo);
Student student = new Student();
student.setLoginInfo(loginList);
List<Student> students = new ArrayList<>();
students.add(student);
Authenticator authenticator = new DefaultAuthenticator(students);
JFrame frame = new JFrame();
frame.add(new TestPane(authenticator));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private CardLayout cardLayout;
public TestPane(Authenticator authenticator) {
cardLayout = new CardLayout();
setLayout(cardLayout);
LoginPage login = new LoginPage(authenticator, new LoginPage.LoginListener() {
@Override
public void loginWasSucessful(LoginPage source, Student student) {
cardLayout.show(TestPane.this, "welcome");
}
});
add(login, "login");
add(new JLabel("Welcome", JLabel.CENTER), "welcome");
}
}

这里有趣的部分是成功登录的处理。当我在这里所做的一切将UI翻转过来以显示";欢迎";标签,你可以看到,这一切都是脱钩和脱离彼此。

我不在乎身份验证是如何工作的,也不在乎我是如何/何时收到成功登录的通知的,只在乎它可能发生

可运行的示例

import java.awt.CardLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.CompoundBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// Load student information, maybe through some kind
// of student service
LoginInfo loginInfo = new LoginInfo("test", "1234");
List<LoginInfo> loginList = new ArrayList<>();
loginList.add(loginInfo);
Student student = new Student();
student.setLoginInfo(loginList);
List<Student> students = new ArrayList<>();
students.add(student);
Authenticator authenticator = new DefaultAuthenticator(students);
JFrame frame = new JFrame();
frame.add(new TestPane(authenticator));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private CardLayout cardLayout;
public TestPane(Authenticator authenticator) {
cardLayout = new CardLayout();
setLayout(cardLayout);
LoginPage login = new LoginPage(authenticator, new LoginPage.LoginListener() {
@Override
public void loginWasSucessful(LoginPage source, Student student) {
cardLayout.show(TestPane.this, "welcome");
}
});
add(login, "login");
add(new JLabel("Welcome", JLabel.CENTER), "welcome");
}
}
public interface Authenticator {
public Student authenticate(String userName, char[] password);
}
public class DefaultAuthenticator implements Authenticator {
private List<Student> students;
public DefaultAuthenticator(List<Student> students) {
this.students = students;
}
@Override
public Student authenticate(String userName, char[] password) {
for (Student student : students) {
for (LoginInfo loginInfo : student.loginInfo) {
if (userName.equals(loginInfo.getUsername()) && Arrays.equals(loginInfo.getPassword().toCharArray(), password)) {
return student;
}
}
}
return null;
}
}
public class LoginPage extends JPanel {
public static interface LoginListener {
public void loginWasSucessful(LoginPage source, Student student);
}
private static final long serialVersionUID = -337449186297669567L;
private JLabel user_label = new JLabel("Username: ");
private JLabel password_label = new JLabel("Password: ");
private JLabel screenName = new JLabel("Login", SwingConstants.CENTER);
private JTextField username = new JTextField(10);
private JPasswordField password = new JPasswordField(10);
private JButton login, cancel;
private JPanel panel = new JPanel();
private String hidden = "login";
private Authenticator authenticator;
private LoginListener loginListener;
public LoginPage(Authenticator authenticator, LoginListener loginListener) {
this.authenticator = authenticator;
this.loginListener = loginListener;
setBorder(new CompoundBorder(BorderFactory.createEmptyBorder(16, 16, 16, 16), BorderFactory.createEtchedBorder()));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(screenName, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.LINE_END;
add(user_label, gbc);
gbc.gridy++;
add(password_label, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.LINE_START;
add(username, gbc);
gbc.gridy++;
add(password, gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
login = new JButton("LOGIN");
add(login, gbc);
login.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
login.setEnabled(false);
Student student = authenticator.authenticate(username.getText(), password.getPassword());
if (student != null) {
loginListener.loginWasSucessful(LoginPage.this, student);
} else {
JOptionPane.showMessageDialog(LoginPage.this, "Authentication failed", "Error", JOptionPane.ERROR_MESSAGE);
}
login.setEnabled(true);
}
});
}
}
public class LoginInfo {
String username;
String password;
public LoginInfo(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
public class Student {
String firstName;
String lastName;
private List<LoginInfo> loginInfo;
public Student() {
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<LoginInfo> getLoginInfo() {
return loginInfo;
}
public void setLoginInfo(List<LoginInfo> loginInfo) {
this.loginInfo = loginInfo;
}
@Override
public String toString() {
return "Student{" + "firstName=" + firstName + ", lastName=" + lastName + ", Login Info=" + loginInfo + '}';
}
}
}

洞穴

我没有故意把你的";学生管理;工作流与我的例子。我在这里所做的只是提供一种方法,通过它可以构建一个工作流,将身份验证工作(委派)连接到";接下来会发生什么;(观察员)工作流程。

您需要围绕这些概念构建解决方案。

但为什么(你这么做)?!

因为,给你一个"复制粘贴";解决方案对您没有帮助。你需要能够看到你的问题,并使用这些设计原则围绕它设计解决方案(它们是软件工程的基础是有原因的)。

您有一个可运行的示例,它演示了基本思想,现在,您需要围绕它们构建解决方案,并尝试学习和理解它们。

相关内容

最新更新