【Betty】聊天室 —— 服务器端

shadowLogo

首先,本人来编写 pojo层

pojo层:

本人先来编写 存储用户信息UserInfo类

用户信息的封装 —— UserInfo类:

package edu.youzg.chat_room.server.pojo;

public class UserInfo {
	private String id;
	private String nick;
	private String password;

	public UserInfo() {
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getNick() {
		return nick;
	}

	public void setNick(String nick) {
		this.nick = nick;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return nick;
	}

}

接下来,本人现在来编写下 用于查询用户登陆信息dao层

dao层:

用户信息的CRUD —— UserDao类:

实现思路:

为了简化操作,本人就将用户信息存储在 xml文件
那么,校验用户登陆信息的逻辑,就可以直接遍历xml的信息,来对比了

实现代码:

package edu.youzg.chat_room.server.dao;

import edu.youzg.util.XMLParser;
import edu.youzg.util.exceptions.XMLIsInexistentException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import edu.youzg.chat_room.server.pojo.UserInfo;

public class UserDao {
	private Document document;

	public UserDao() throws XMLIsInexistentException {
		this.document = XMLParser.getDocument("/userInfo.xml");
	}

	public UserInfo getUser(String id) {
		UserInfo user = new UserInfo();
		new XMLParser() {
			@Override
			public void dealElement(Element element, int index) {
				String strId = element.getAttribute("id");
				if (!strId.equals(id)) {
					return;
				}

				String nick = element.getAttribute("nick");
				String password = element.getAttribute("password");
				user.setId(strId);
				user.setNick(nick);
				user.setPassword(password);
			}
		}.parseTag(this.document, "user");
		
		if (user.getId() == null) {
			return null;
		}
		
		return user;
	}
	
}

接下来,本人来编写下 处理客户端请求service层

service层:

首先,本人来实现一个 用于 校验用户信息UserService类

用户信息校验 —— UserService类:

package edu.youzg.chat_room.server.service;

import edu.youzg.chat_room.server.dao.UserDao;
import edu.youzg.chat_room.server.pojo.UserInfo;
import edu.youzg.util.exceptions.XMLIsInexistentException;

public class UserService {
	private UserDao userDao;
	
	public UserService() throws XMLIsInexistentException {
		this.userDao = new UserDao();
	}

	public UserInfo getUserById(String id, String password) {
		UserInfo user = userDao.getUser(id);
		
		if (user == null || !password.equals(user.getPassword())) {
			return null;
		}
		
		return user;
	}
	
}

接下来,本人来实现下用于 处理对端逻辑controller层

controller层:

在本篇博文中,本人只设计了一个 处理用户登陆逻辑 的功能:

用户请求处理 —— UserAction类:

对于客户端请求,我们只需新增一个 登陆处理逻辑

package edu.youzg.chat_room.server.controller;

import edu.youzg.betty.action.Actioner;
import edu.youzg.betty.action.Argument;
import edu.youzg.betty.action.Mapping;
import edu.youzg.chat_room.server.pojo.UserInfo;
import edu.youzg.chat_room.server.service.UserService;
import edu.youzg.util.exceptions.XMLIsInexistentException;

@Actioner
public class UserAction {
	private UserService userService;

	public UserAction() throws XMLIsInexistentException {
		this.userService = new UserService();
	}
	
	@Mapping("userLogin")
	public UserInfo getUserById(
			@Argument("id") String id,
			@Argument("password") String password) {
		UserInfo user = userService.getUserById(id, password);
		
		if (user == null) {
			user = new UserInfo();
			user.setId("ERROR");
		} else {
			user.setPassword(null);
		}
		
		return user;
	}

}

那么,现在,本人就来编写下 服务器界面view层

view层:

本人现在来编写下 服务器页面 —— ChatRoomServerView类

服务器页面 —— ChatRoomServerView类:

package edu.youzg.chat_room.server.view;

import edu.youzg.betty.core.Server;
import edu.youzg.betty.event.IListener;
import edu.youzg.util.ISwingHelper;
import edu.youzg.util.PromptBoxTool;
import edu.youzg.util.PropertiesParser;
import edu.youzg.util.exceptions.FrameIsNullException;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;

public class ChatRoomServerView implements ISwingHelper, IListener {
	private Server server;

	private JFrame jfrmServerView;
	private JTextField jtxtCommand;
	private JTextArea jtatMessage;

	public ChatRoomServerView() {
		this.server = new Server();
		this.server.addListener(this);
	}

	public ChatRoomServerView initServer() {
		this.server.initServer("/server.cfg.properties");
		initView();
		return this;
	}

	@Override
	public void init() {
		jfrmServerView = new JFrame("右转聊天室");
		jfrmServerView.setLayout(new BorderLayout());
		jfrmServerView.setMinimumSize(new Dimension(800, 600));
		jfrmServerView.setExtendedState(JFrame.MAXIMIZED_BOTH);
		jfrmServerView.setLocationRelativeTo(null);
		jfrmServerView.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		JLabel jlblTopic = new JLabel("右转哥粉丝聊天室", JLabel.CENTER);
		jlblTopic.setFont(topicFont);
		jlblTopic.setForeground(topicColor);
		jfrmServerView.add(jlblTopic, BorderLayout.NORTH);
		
		JPanel jpnlFooter = new JPanel(new FlowLayout());
		jfrmServerView.add(jpnlFooter, BorderLayout.SOUTH);
		
		JLabel jlblCommand = new JLabel("命令:");
		jlblCommand.setFont(normalFont);
		jpnlFooter.add(jlblCommand);
		
		jtxtCommand = new JTextField(40);
		jtxtCommand.setFont(normalFont);
		jpnlFooter.add(jtxtCommand);
		
		JPanel jpnlLeftBlank = new JPanel();
		JLabel jlblLeftBlank = new JLabel(" ");
		jlblLeftBlank.setFont(normalFont);
		jpnlLeftBlank.add(jlblLeftBlank);
		jfrmServerView.add(jpnlLeftBlank, BorderLayout.WEST);
		
		JPanel jpnlRightBlank = new JPanel();
		JLabel jlblRightBlank = new JLabel(" ");
		jlblRightBlank.setFont(normalFont);
		jpnlRightBlank.add(jlblRightBlank);
		jfrmServerView.add(jpnlRightBlank, BorderLayout.EAST);
		
		jtatMessage = new JTextArea();
		jtatMessage.setFont(normalFont);
		jtatMessage.setEditable(false);
		jtatMessage.setFocusable(false);
		JScrollPane jscpMessage = new JScrollPane(jtatMessage);
		TitledBorder ttbdMessage = new TitledBorder("系统消息");
		ttbdMessage.setTitleFont(normalFont);
		ttbdMessage.setTitleColor(Color.red);
		ttbdMessage.setTitlePosition(TitledBorder.ABOVE_TOP);
		ttbdMessage.setTitleJustification(TitledBorder.CENTER);
		jscpMessage.setBorder(ttbdMessage);
		
		jfrmServerView.add(jscpMessage, BorderLayout.CENTER);
	}

	@Override
	public void reinit() {
	}

	private void closeServer() {
		if (server.isStartup()) {
			PromptBoxTool.showWarnning(jfrmServerView, "服务器尚未宕机!");
			return;
		}
		try {
			exitView();
		} catch (FrameIsNullException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void dealEvent() {
		jfrmServerView.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				closeServer();
			}

			@Override
			public void windowOpened(WindowEvent e) {
				PropertiesParser property = new PropertiesParser();
				String strAutoStartup = property.value("autoStartup");
				if (strAutoStartup.equalsIgnoreCase("true")) {
					try {
						server.startup();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}

		});
		
		jtxtCommand.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String command = jtxtCommand.getText().trim();
				if (command.length() <= 0) {
					return;
				}
				dealCommand(command);
				jtxtCommand.setText("");
			}
		});
	}
	
	private void dealCommand(String command) {
		if (command.equalsIgnoreCase("startup")
				|| command.equalsIgnoreCase("st")) {
			try {
				server.startup();
			} catch (IOException e) {
				PromptBoxTool.showError(jfrmServerView, e.getMessage());
			}
		} else if (command.equalsIgnoreCase("shutdown")
				|| command.equalsIgnoreCase("sd")) {
			server.shutdown();
		} else if (command.equalsIgnoreCase("exit")
				|| command.equalsIgnoreCase("x")) {
			closeServer();
		} else if (command.equalsIgnoreCase("forcedown")
				|| command.equalsIgnoreCase("fd")) {
			server.forcedown();
		}
	}

	@Override
	public JFrame getFrame() {
		return jfrmServerView;
	}
	
	@Override
	public void processMessage(String message) {
		jtatMessage.append(message);
		jtatMessage.append("\n");
		jtatMessage.setCaretPosition(jtatMessage.getText().length());
	}

}

在文末,本人来给出两个服务器端运行必须的配置文件

配置文件

首先,是 用于初始化Server连接参数server.cfg.properties文件

服务端连接参数 —— server.cfg.properties文件:

port=6666
maxClientCount=10
autoStartup=true

最后,是 用于存储用户信息student.xml文件

用户登陆信息 —— userInfo.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<user>
    <user id="xiyou-1" nick="师匠" password="1450575459"></user>
    <user id="xiyou-2" nick="齐天" password="1450575459"></user>
    <user id="xiyou-3" nick="天蓬" password="1450575459"></user>
    <user id="xiyou-4" nick="卷帘" password="1450575459"></user>
</user>

本人在这里说明一下:

中的 password 数值都是 1450575459
并不是乱设置的数字,这个数字是 数字123456 经过 hashcode加密 后的结果
我们在开发中,哪怕是服务端的数据库中,都 不能明文存储用户隐私数据
而且为了保证 用户隐私数据安全,使用的 加密算法,一般都是 非对称加密


启动层:

服务器 启动类 —— ChatRoomServerMain类:

package edu.youzg.chat_room.server.Main;

import edu.youzg.betty.action.ActionBeanFactory;
import edu.youzg.chat_room.server.view.ChatRoomServerView;
import edu.youzg.util.exceptions.FrameIsNullException;

public class ChatRoomServerMain {

	public static void main(String[] args) {
		try {
			ActionBeanFactory.scanPackage("edu.youzg.chat_room.server.controller");
			ChatRoomServerView serverView = new ChatRoomServerView()
					.initServer();
			serverView.showView();
		} catch (FrameIsNullException e) {
			e.printStackTrace();
		}
	}

}

至此,聊天室 服务端 的代码,就编写完毕了!

至于运行结果,本人将放在总集篇为同学们展示

(本人 聊天室总集篇 博文 ——《Betty 聊天室》链接:
https://www.cnblogs.com/codderYouzg/p/12749222.html)

posted @ 2020-04-22 00:41  在下右转,有何贵干  阅读(189)  评论(0编辑  收藏  举报