【Betty】聊天室 —— 服务器端
首先,本人来编写 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)