java-课程设计-聊天室(团队博客)
一、个人负责模块
工具包,实现了服务器和客户端的请求和回应,文件和信息的传输,和对用户信息的储存和传输
二、功能框架图
三、个人任务简述
我的主要任务是为客户端和服务器的交互提供方法
1.客户端向服务器发出请求
Request.java
package common.model.entity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class Request implements Serializable {
private static final long serialVersionUID = -1237018286305074249L;
/** 请求传送的数据类型 */
private ResponseType type;
/** 请求动作 */
private String action;
/** 请求域中的数据,name-value */
private Map<String, Object> attributesMap;
/**
* 构造函数,初始化Request实例
*/
public Request(){
this.attributesMap = new HashMap<String, Object>();
}
/**
* 获取请求的数据类型
* @return 请求的数据类型
*/
public ResponseType getType() {
return type;
}
/**
* 设置请求的数据类型
* @param type 请求的数据类型
*/
public void setType(ResponseType type) {
this.type = type;
}
/**
* 获取请求的动作
* @return 请求的动作
*/
public String getAction() {
return action;
}
/**
* 设置请求的动作
* @param action 请求的动作
*/
public void setAction(String action) {
this.action = action;
}
/**
* 获取请求域中的所有数据
* @return 请求域中的所有数据(name-value)
*/
public Map<String, Object> getAttributesMap() {
return attributesMap;
}
/**
* 根据name获取请求域中的value数据
* @param name 请求域中的name值
* @return 请求域中对应的value数据
*/
public Object getAttribute(String name){
return this.attributesMap.get(name);
}
/**
* 向请求域中添加数据(name-value)
* @param name 请求域中的name值
* @param value 请求域中的value值
*/
public void setAttribute(String name, Object value){
this.attributesMap.put(name, value);
}
/**
* 根据name删除请求域中的数据
* @param name 请求域中的name值
*/
public void removeAttribute(String name){
this.attributesMap.remove(name);
}
/**
* 清空请求域中的所有数据
*/
public void clearAttribute(){
this.attributesMap.clear();
}
}
Response.java
package common.model.entity;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 〈响应对象〉<br>
* 〈〉
*
*/
public class Response implements Serializable {
private static final long serialVersionUID = 1689541820872288991L;
/** 响应状态 */
private ResponseStatus status;
/** 响应数据的类型 */
private ResponseType type;
private Map<String, Object> dataMap;
/** 响应输出流 */
private OutputStream outputStream;
/**
* 构造函数,初始化Response实例
*/
public Response(){
this.status = ResponseStatus.OK;
this.dataMap = new HashMap<String, Object>();
}
/**
* 获取响应状态
* @return 响应状态
*/
public ResponseStatus getStatus() {
return status;
}
/**
* 设置响应状态
* @param status 响应状态
*/
public void setStatus(ResponseStatus status) {
this.status = status;
}
/**
* 获取响应数据的类型
* @return 响应数据的类型
*/
public ResponseType getType() {
return type;
}
/**
* 设置响应数据的类型
* @param type 响应数据的类型
*/
public void setType(ResponseType type) {
this.type = type;
}
/**
* 获取响应域中的所有数据
* @return 响应域中的所有数据(name-value)
*/
public Map<String, Object> getDataMap() {
return dataMap;
}
/**
* 设置响应域中的所有数据(name-value)
* @param dataMap 响应域中的所有数据(name-value)
*/
public void setDataMap(Map<String, Object> dataMap) {
this.dataMap = dataMap;
}
/**
* 获取响应输出流
* @return 响应输出流
*/
public OutputStream getOutputStream() {
return outputStream;
}
/**
* 设置响应输出流
* @param outputStream 响应输出流
*/
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
/**
* 向响应域中添加数据(name-value)
* @param name 响应域中的name值
* @param value 响应域中的value值
*/
public void setData(String name, Object value){
this.dataMap.put(name, value);
}
/**
* 根据name获取响应域中的value数据
* @param name 响应域中的name值
* @return 响应域中对应的value数据
*/
public Object getData(String name){
return this.dataMap.get(name);
}
/**
* 根据name删除响应域中的数据
* @param name 响应域中的name值
*/
public void removeData(String name){
this.dataMap.remove(name);
}
/**
* 清空响应域中的所有数据
*/
public void clearData(){
this.dataMap.clear();
}
}
然后是对文件和信息的传输功能的实现
FileInfo.java
package common.model.entity;
import java.io.Serializable;
import java.util.Date;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
*/
public class FileInfo implements Serializable {
private static final long serialVersionUID = -5394575332459969403L;
/** 消息接收者 */
private User toUser;
/** 消息发送者 */
private User fromUser;
/** 源文件名 */
private String srcName;
/** 发送时间 */
private Date sendTime;
/** 目标地IP */
private String destIp;
/** 目标地端口 */
private int destPort;
/** 目标文件名 */
private String destName;
/**
* 获取消息接收者
* @return 消息接收者对象
*/
public User getToUser() {
return toUser;
}
/**
* 设置消息接收者
* @param toUser 消息接收者对象
*/
public void setToUser(User toUser) {
this.toUser = toUser;
}
/**
* 获取消息发送者
* @return 消息发送者对象
*/
public User getFromUser() {
return fromUser;
}
/**
* 设置消息发送者
* @param fromUser 消息发送者对象
*/
public void setFromUser(User fromUser) {
this.fromUser = fromUser;
}
/**
* 获取源文件名
* @return 源文件名字符串
*/
public String getSrcName() {
return srcName;
}
/**
* 设置源文件名
* @param srcName 源文件名字符串
*/
public void setSrcName(String srcName) {
this.srcName = srcName;
}
/**
* 获取发送时间
* @return 发送时间对象
*/
public Date getSendTime() {
return sendTime;
}
/**
* 设置发送时间
* @param sendTime 发送时间对象
*/
public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
}
/**
* 获取目标地址IP
* @return 目标地址IP字符串
*/
public String getDestIp() {
return destIp;
}
//这个方法为destIp属性设置值。通过传入一个字符串类型的destIp参数,用于更新对象的destIp属性。
public void setDestIp(String destIp) {
this.destIp = destIp;
}
//这个方法用于返回对象的destPort属性的当前值。
public int getDestPort() {
return destPort;
}
//这个方法为destPort属性设置值。通过传入一个整型destPort参数,用于更新对象的destPort属性。
public void setDestPort(int destPort) {
this.destPort = destPort;
}
//这个方法用于返回对象的destName属性的当前值。
public String getDestName() {
return destName;
}
//这个方法为destName属性设置值。通过传入一个字符串类型的destName参数,用于更新对象的destName属性。
public void setDestName(String destName) {
this.destName = destName;
}
}
Message.java
package common.model.entity;
import java.io.Serializable;
import java.util.Date;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
*/
/**
* 该类表示一条聊天消息。
*/
public class Message implements Serializable {
private static final long serialVersionUID = 1820192075144114657L;
/** 消息接收者 */
private User toUser;
/** 消息发送者 */
private User fromUser;
/** 消息内容 */
private String message;
/** 发送时间 */
private Date sendTime;
/**
* 获取消息的接收者
*
* @return 接收者的User对象
*/
public User getToUser() {
return toUser;
}
/**
* 设置消息的接收者
*
* @param toUser 接收者的User对象
*/
public void setToUser(User toUser) {
this.toUser = toUser;
}
/**
* 获取消息的发送者
*
* @return 发送者的User对象
*/
public User getFromUser() {
return fromUser;
}
/**
* 设置消息的发送者
*
* @param fromUser 发送者的User对象
*/
public void setFromUser(User fromUser) {
this.fromUser = fromUser;
}
/**
* 获取消息的文本内容
*
* @return 字符串格式的消息内容
*/
public String getMessage() {
return message;
}
/**
* 设置消息的文本内容
*
* @param message 字符串格式的消息内容
*/
public void setMessage(String message) {
this.message = message;
}
/**
* 获取消息的发送时间
*
* @return Date对象表示的发送时间
*/
public Date getSendTime() {
return sendTime;
}
/**
* 设置消息的发送时间
*
* @param sendTime 发送时间对应的Date对象
*/
public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
}
}
3.对用户信息的储存与传输
User.java
package common.model.entity;
import javax.jws.soap.SOAPBinding;
import javax.swing.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
*/
/**
* 该类表示一个用户。
*/
public class User implements Serializable {
private static final long serialVersionUID = 5942011574971970871L;
/** 用户的唯一ID */
private long id;
/** 用户登录用密码 */
private String password;
/** 用户自定义的昵称 */
private String nickname;
/** 用户选择的头像编号 */
private int head;
/** 用户性别,'M'表示男性,'F'表示女性 */
private char sex;
/** 用户好友列表 */
private List<User> mateList;
/** 用户聊天记录 */
private List<String> chatRecords;
/**
* 通过构造函数初始化User实例,如果nickname为空则将其赋为默认值"未命名",并添加上线消息到聊天记录。
*
* @param password 用户密码
* @param nickname 用户昵称
* @param sex 用户性别
* @param head 用户头像编号
*/
public User(String password, String nickname, char sex, int head){
this.password = password;
this.sex = sex;
this.head = head;
this.mateList = new ArrayList<User>(100);
this.chatRecords = new ArrayList<String>(300);
if(nickname.equals(""))
{
this.nickname = "未命名";
}else{
this.nickname = nickname;
}
//非常重要的一步。因为如果只对chatRecords分配空间,而没有分配实际值时,对其进行readObject操作时会报错!
String sb = "【系统消息】用户"+ nickname + "上线了!\n";
this.chatRecords.add(sb);
}
/**
* 通过构造函数初始化User实例。
*
* @param id 用户唯一ID
* @param password 用户密码
*/
public User(long id, String password){
this.id = id;
this.password = password;
}
//通过传入id和好友列表mateList初始化用户信息。
public User(long id, List<User> mateList) {
this.id = id;
this.mateList = mateList;
}
//获取用户id。
public long getId(){
return id;
}
//设置用户id。
public void setId(long id){
this.id = id;
}
//设置用户密码。
public void setPassword(String password){
this.password = password;
}
//获取用户密码。
public String getPassword(){
return password;
}
//设置用户性别。
public void setSex(char sex){
this.sex=sex;
}
//获取用户性别。
public char getSex(){
return this.sex;
}
//设置用户昵称。
public void setNickname(String nickname){
this.nickname = nickname;
}
//获取用户昵称。
public String getNickname(){
return this.nickname;
}
//设置用户头像。
public void setHead(int head){
this.head = head;
}
//获取用户头像。
public int getHead(){
return this.head;
}
//设置用户好友列表mateList。
public void setMateList(List<User> mateList) {this.mateList=mateList; };
//向用户好友列表mateList中添加好友,如果该用户已经是好友,则不会重复添加。
public void addMate(User user) {
if(this.mateList == null) {
this.mateList = new ArrayList<User>(100);
}
if(this.mateList.contains(user)) {
return;
}
this.mateList.add(user);
}
//从用户好友列表mateList中删除特定好友。
public void delMate(User user) {
this.mateList.remove(user);
}
//获取用户好友列表mateList。
public List<User> getMateList() { return this.mateList;}
// 查看要检验的用户是否已存在自身的好友列表中
public boolean testMateId(User testUser) {
for(User mate: this.mateList) {
if(mate.getId()== testUser.getId()) {
return true;
}
}
return false;
}
//向用户聊天记录chatRecords中添加一个字符串str。
public void addRecord(String str) {
if(this.chatRecords == null) {
this.chatRecords = new ArrayList<String>(300);
String sb = "【系统消息】用户"+this.nickname + "上线了!\n";
this.chatRecords.add(sb);
}
this.chatRecords.add(str);
}
//获取用户聊天记录chatRecords列表,如果此前没有任何聊天记录,则会给chatRecords预先加入一条“上线”系统消息记录。
public List<String> getChatRecords() {
if(this.chatRecords == null) {
this.chatRecords = new ArrayList<String>(300);
String sb = "【系统消息】用户"+this.nickname + "上线了!\n";
this.chatRecords.add(sb);
}
return this.chatRecords;
}
//清除用户聊天记录chatRecords。
public void clearChatRecords() {
this.chatRecords = null;
}
//根据用户设定的头像名称生成头像图标Icon并返回该Icon对象。
public ImageIcon getHeadIcon(){
ImageIcon image = new ImageIcon("images/"+head+".png");
return image;
}
//重载hashCode()方法,使用默认的哈希值计算公式,通过对id、nickname、password、sex和head等私有属性进行异或后相乘再加1来生成该对象的哈希码。
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + head;
result = prime * result + (int)(id ^ (id >> 32));
result = prime * result + ((nickname == null) ? 0 : nickname.hashCode());
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + sex;
return result;
}
//重载equals()方法,如果传入参数为非"User"类或者为空,返回false;否则判断当前对象的id、nickname、sex、password和head是否与传入对象所有对应成员变量完全一致,若完全一致则返回true,否则返回false。
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
User other = (User) obj;
if(head != other.head || id != other.id || sex != other.sex)
return false;
if(nickname == null){
if(other.nickname != null)
return false;
}else if(!nickname.equals(other.nickname))
return false;
if(password == null){
if(other.password != null)
return false;
}else if(!password.equals(other.password))
return false;
return true;
}
//重载toString()方法,返回包含当前对象id、password、nickname、head和sex等基本信息的字符串。
@Override
public String toString() {
return this.getClass().getName()
+ "[id=" + this.id
+ ",pwd=" + this.password
+ ",nickname=" + this.nickname
+ ",head=" + this.head
+ ",sex=" + this.sex
+ "]";
}
}
四、课程设计感想
通过团队十几天的努力,感觉收获颇丰,加强了对所学知识的巩固。学习了Java 网络编程、Java l0 流,Java 类和对象的定义,Jav封装、继承、多态,Java 中的序列化和异常处理,Java 中的集合类和流处理,技术又上了一层楼。