-->

登录界面

- 说明

登录界面可以利用springboot框架实现,也可以用网络编程(客户端——服务器 C——S模式)的形式实现,下面我将逐一说明
springboot框架图模型:
image
image
网络编程架构图模型
image
人为用户,GUI是界面,NC为NetClient,Command为命令,NS为NetServlet,ST为ServerThread线程类,M为Model,DB是DBtool工具,最后圆柱体是数据库

- 利用springboot实现

第一步 建库建表

image
不需要什么复杂的属性,有id、name/username、pwd/password就够用了

第二步 创建实体类

@Data
public class User2 {
    private int id;
    private String username;
    private String password;
}

注意:实体类里面的属性必须和表里的对应,否则在Mapper里会报错

第三步 创建Mapper

@Mapper
public interface UserMapper {

    @Select("select * from register where username = #{username} and password = #{password}")
    List<User2> login(User2 user);
}

#{}里面的属性必须是传进来的User2实体类里的

第四步 创建Service

@Service
@Transactional
public class UserService {

    private UserMapper mapper;

    @Autowired
    public UserService(UserMapper mapper) {
        this.mapper = mapper;
    }

    public Boolean login(User2 user){
        if (mapper.login(user).isEmpty() || mapper.login(user).size() == 0){
            System.out.println(mapper.login(user));
            return false;
        }else {
            System.out.println(mapper.login(user));
            return true;
        }
    }
}

实现判断账号密码的方式有很多,我这个仅供参考,例如下面
image

第五步 创建Controller

@RestController
@RequestMapping("/user")
public class UserController {

    private UserService service;

    @Autowired
    public UserController(UserService service) {
        this.service = service;
    }

    @PostMapping("/login")
    public Boolean login(@RequestBody User2 user){
        return service.login(user);
    }
}

注意:如果Controller里包含增删改查一套,可以使用restful请求模式,当然,你也可以不用,只不过用了Controller接口比较简单明了
restful请求文档
其实就是动作增(post)删(delete)改(put)查(get) + 对象

第六步 前端代码

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <title>登陆界面</title>
    <link rel="stylesheet" href="layui/css/layui.css" media="all">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

</head>
<body>
<form style="text-align: center;margin: auto">
    <div class="layui-form-item layui-inline" style="text-align: center">
        <label class="layui-form-label">账号:</label>
        <div class="layui-input-inline" style="text-align: center">
            <input type="text" name="username" lay-verify="required" placeholder="请输入账号" autocomplete="off"
                   class="layui-input" style="text-align: center" id="name">
        </div>
    </div>
    </br>
    <div class="layui-form-item layui-inline" style="text-align: center">
        <label class="layui-form-label">密码:</label>
        <div class="layui-input-inline" style="text-align: center">
            <input type="password" name="password" placeholder="请输入密码" autocomplete="off" class="layui-input"
                   style="text-align: center" id="pwd">
        </div>

    </div>
    </br>
    <div class="layui-btn-container layui-inline" style="text-align: center">
        <button class="layui-btn layui-btn-primary layui-border-blue" type="button" onclick="login()">登录</button>
        <button class="layui-btn layui-btn-primary layui-border-blue">注册</button>
    </div>
</form>
<script>
    function login() {
        let User = {
            username:$("#name").val(),
            password:$("#pwd").val()
        };
        $.getJSON({
            type: "post",
            url:'/user/login',
            data: JSON.stringify(User),
            contentType: "application/json; charset=utf-8",
            // data:{name:'#{name}',pwd:'#{pwd}'},
            success:function (data) {
                if (data){
                    // alert(User);
                    window.location="index.html"
                }else {
                    // alert(User);
                    alert("账号密码有误");
                }
            }
        })
    }
</script>
</body>
</html>

username:$("#name").val()是HTML的js的根据id标签取值
$("#name").val("")是HTML的js的根据id标签赋空值

data: JSON.stringify(User),
contentType: "application/json; charset=utf-8",
这两句是用于post方法,将参数转为JSON形式

window.location="index.html"用于HTML中跳转界面
image
js函数模型大概就这样,其中$.getJSON也可以通过$.ajax实现

- 利用网络编程实现登陆界面

第一步 建库建表

image

第二步 准备DBtool工具类

public class DbTool {

    private static String url = "jdbc:mysql://43.142.87.68:3306/coffers";
    private static String username = "root";
    private static String password = "123456";

    public static int executeDML(String sql,Object...args) throws SQLException {
        try(Connection c = DriverManager.getConnection(url,username,password)){
            try(PreparedStatement ps = c.prepareStatement(sql)){
                for (int i = 0; i < args.length; i++) {
                    ps.setObject(i+1,args[i]);
                }
                return ps.executeUpdate();
            }
        }
    }

    public static List<Object []> executeDql(String sql,Object...args) throws SQLException {
        try(Connection c = DriverManager.getConnection(url,username,password)){
            try(PreparedStatement ps = c.prepareStatement(sql)){
                for (int i = 0; i < args.length; i++) {
                    ps.setObject(i+1,args[i]);
                }
                List<Object []> result = new ArrayList<>();
                var rs = ps.executeQuery();
                while (rs.next()){
                    Object [] row = new Object[rs.getMetaData().getColumnCount()];
                    for (int i = 0; i < row.length; i++) {
                        row[i] = rs.getObject(i+1);
                    }
                    result.add(row);
                }
                return result;
            }
        }
    }
}

executeDML用于处理增删改操作,executeDql用于处理查询操作

第三步 创建实体类(领域对象)

public class Login implements Serializable {

    private String username;
    private String password;

    public Login() {
    }

    public Login(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;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Login login = (Login) o;
        return Objects.equals(username, login.username) && Objects.equals(password, login.password);
    }

    @Override
    public int hashCode() {
        return Objects.hash(username, password);
    }

    @Override
    public String toString() {
        return "Register{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public Object [] toArray(){
        return new Object[]{
          username,password
        };
    }
}

最后一个toArray()方法用于输出实体类为数组,前面的方法都可以自动生成,构造方法一般有三种:空属性,实际需要属性,全部属性

第四步 Model

public class LoginModel {
    public List<Object []> register(Login login) throws SQLException {
        String sql = "select * from users where name = ? and password = ?";
        return DbTool.executeDql(sql, login.getUsername(), login.getPassword());
    }
}

Model里调用DBtool实现基本的增删改查

第五步 Client与Server

Client

public class NetClient {

    private Socket s;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;

    public void connect() throws IOException {
        s = new Socket("localhost", 22222);
    }

    public void close() throws IOException {
        s.close();
    }

    public void send(Command c) throws IOException {
        if (oos == null) {
            oos = new ObjectOutputStream(s.getOutputStream());
        }
        oos.writeObject(c);
    }

    public Object receive() throws Exception {
        if (ois == null) {
            ois = new ObjectInputStream(s.getInputStream());
        }
        return ois.readObject();
    }
}

Client包含基本的连接、关闭、发送、接收的功能

Server

public class NetServer {

    ExecutorService es = Executors.newCachedThreadPool();

    public void start() throws IOException {
        ServerSocket serverSocket = new ServerSocket(22222);
        System.out.println("服务器正在监听...");
        while (true) {
            Socket s = serverSocket.accept();
            es.execute(new ServerThread(s));
        }
    }


    public static void main(String[] args) throws IOException {
        new NetServer().start();
    }
}

只有一个处理请求的方法

第六步 ServerThread 线程类

点击查看代码
public class ServerThread extends Thread{

    private Socket s;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;

    public ServerThread(Socket s) {
        this.s = s;
    }

    @Override
    public void run() {
        try {
            oos = new ObjectOutputStream(s.getOutputStream());
            ois = new ObjectInputStream(s.getInputStream());
            while (true) {
                Command o = (Command) ois.readObject();
                o.execute();
                oos.writeObject(o);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

第七步 Command类

点击查看代码
public class LoginCommand extends Command {
    @Override
    public void execute() {
        try {
            Login c = (Login) o;
            r = new LoginModel().register(c);

            if (r != null) {
                final Log log = new Log(userName, "logs", c.getUsername() + "成功登录");
                new LogModel().add(log);
            }


        } catch (SQLException ex) {
            e = ex;
            throw new RuntimeException(ex);
        }
    }
}

他的父类Command如下

public abstract class Command implements Serializable {

    public Object o;
    public Exception e;
    public Object r;
    public String userName;

    public abstract void execute();
}

第八步 Controller与前端界面和到一起的(前后段不分离)

点击查看代码
public class 登陆界面 extends JFrame {

    public String user;

    NetClient rc = new NetClient();
    public 登陆界面() {
        initComponents();
        try {
            rc.connect();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void 登录(ActionEvent e) {
        Login r = new Login();
        r.setUsername(this.textField1.getText());
        r.setPassword(this.passwordField1.getText());
        Command ac = new LoginCommand();
        ac.o = r;
        ac.userName = this.textField1.getText();
        try {
            rc.send(ac);
            ac = (Command) rc.receive();
            if (ac.r != null){
                JOptionPane.showMessageDialog(null,"登陆成功");



                this.setVisible(false);
                整合界面 a = new 整合界面();
                a.user = r.getUsername();
                a.setVisible(true);
                a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }else {
                JOptionPane.showMessageDialog(null,"登陆失败");
            }
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }

    }


    private void 清空(ActionEvent e) {
        clear();
    }

    public void clear(){
        textField1.setText("");
        passwordField1.setText("");
    }

    private void initComponents() {
        // JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
        label1 = new JLabel();
        textField1 = new JTextField();
        label2 = new JLabel();
        passwordField1 = new JPasswordField();
        button1 = new JButton();
        button2 = new JButton();

        //======== this ========
        var contentPane = getContentPane();

        //---- label1 ----
        label1.setText("\u8d26\u53f7\uff1a");
        label1.setHorizontalAlignment(SwingConstants.CENTER);

        //---- label2 ----
        label2.setText("\u5bc6\u7801\uff1a");
        label2.setHorizontalAlignment(SwingConstants.CENTER);

        //---- button1 ----
        button1.setText("\u767b\u5f55");
        button1.addActionListener(e -> 登录(e));

        //---- button2 ----
        button2.setText("\u53d6\u6d88");
        button2.addActionListener(e -> 清空(e));

        GroupLayout contentPaneLayout = new GroupLayout(contentPane);
        contentPane.setLayout(contentPaneLayout);
        contentPaneLayout.setHorizontalGroup(
            contentPaneLayout.createParallelGroup()
                .addGroup(contentPaneLayout.createSequentialGroup()
                    .addGroup(contentPaneLayout.createParallelGroup()
                        .addGroup(contentPaneLayout.createSequentialGroup()
                            .addGap(19, 19, 19)
                            .addGroup(contentPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING, false)
                                .addGroup(contentPaneLayout.createSequentialGroup()
                                    .addComponent(label2)
                                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(passwordField1))
                                .addGroup(contentPaneLayout.createSequentialGroup()
                                    .addComponent(label1)
                                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                    .addComponent(textField1, GroupLayout.PREFERRED_SIZE, 126, GroupLayout.PREFERRED_SIZE))))
                        .addGroup(GroupLayout.Alignment.TRAILING, contentPaneLayout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(button1)
                            .addGap(18, 18, 18)
                            .addComponent(button2)))
                    .addContainerGap(41, Short.MAX_VALUE))
        );
        contentPaneLayout.linkSize(SwingConstants.HORIZONTAL, new Component[] {button1, button2});
        contentPaneLayout.setVerticalGroup(
            contentPaneLayout.createParallelGroup()
                .addGroup(contentPaneLayout.createSequentialGroup()
                    .addGap(21, 21, 21)
                    .addGroup(contentPaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(label1)
                        .addComponent(textField1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addGap(18, 18, 18)
                    .addGroup(contentPaneLayout.createParallelGroup()
                        .addComponent(label2)
                        .addComponent(passwordField1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 37, Short.MAX_VALUE)
                    .addGroup(contentPaneLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(button2)
                        .addComponent(button1))
                    .addGap(30, 30, 30))
        );
        contentPaneLayout.linkSize(SwingConstants.VERTICAL, new Component[] {button1, button2});
        pack();
        setLocationRelativeTo(getOwner());
        // JFormDesigner - End of component initialization  //GEN-END:initComponents
    }

    // JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
    private JLabel label1;
    private JTextField textField1;
    private JLabel label2;
    private JPasswordField passwordField1;
    private JButton button1;
    private JButton button2;
    // JFormDesigner - End of variables declaration  //GEN-END:variables

    public static void main(String[] args) {
        登陆界面 d = new 登陆界面();
        d.setVisible(true);
        d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
posted @ 2022-10-16 21:41  ꧁ʚ星月天空ɞ꧂  阅读(88)  评论(0)    收藏  举报