登录界面
- 说明
登录界面可以利用springboot框架实现,也可以用网络编程(客户端——服务器 C——S模式)的形式实现,下面我将逐一说明
springboot框架图模型:


网络编程架构图模型

人为用户,GUI是界面,NC为NetClient,Command为命令,NS为NetServlet,ST为ServerThread线程类,M为Model,DB是DBtool工具,最后圆柱体是数据库
- 利用springboot实现
第一步 建库建表

不需要什么复杂的属性,有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;
}
}
}
实现判断账号密码的方式有很多,我这个仅供参考,例如下面

第五步 创建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中跳转界面

js函数模型大概就这样,其中$.getJSON也可以通过$.ajax实现
- 利用网络编程实现登陆界面
第一步 建库建表

第二步 准备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);
}
}

浙公网安备 33010602011771号