javaSE进阶第二周

day07

踩坑一:关于输入输出流的顺序问题

if("2".equals(strs[0])){
String returnmessage = null;
try {
    // 接收对象
    ObjectInputStream ois = new ObjectInputStream(
        socket.getInputStream());
    member = (Member) ois.readObject();
    System.out.println(member);
    memberService = new  MemberService();
    // 登录判断
    Member login =memberService.isLogin(member.getName(),member.getPassword());
    returnmessage ="2,ok";
    MessageUtils.sendMessage(socket, returnmessage);
    List<Member> friends = memberService.loadFriends(login.getId());
    System.out.println(friends.toString());
    friends.add(0, login);
    // 发送对象
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
    oos.writeObject(friends);
    oos.flush();
    // 成功则发送2,ok
} catch (Exception e) {
    // 有异常捕获异常并且发送 2,nook,e.getMessage()
    returnmessage = "2,nook,"+e.getMessage();
    MessageUtils.sendMessage(socket, returnmessage);
}
}

对于输入输出流来说,一定要按照顺序进行读写,例如:在Server中先写发送了一个int类型的值,然后紧接着又发送了一个String类型的值,所以在接收的时候,也必须先接收int值,在接收String值,否则会有接收错误,出现乱码。其实就是文件接收头的地方出现了错误。

1.自定义异常

1)首先建一个异常类:继承RunrtimeException

package com.lxb.dao.exception;

public class ChatException extends RuntimeException{

	public ChatException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public ChatException(String message, Throwable cause,
			boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public ChatException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public ChatException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public ChatException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
	
}

2)在需要的时候捕获异常,并且输出异常的信息

public Member isLogin(String name, String password) {
		Member member = memberDao.isLogin(name);
		if(member == null){
			throw new ChatException("该用户名不存在");
		}
		if(!password.equals(member.getPassword())){
			throw new ChatException("密码错误");
		}
		return member;
	}

3)在使用上述方法的地方的catch异常

} catch (Exception e) {
    // 有异常捕获异常并且发送 2,nook,e.getMessage()
    returnmessage = "2,nook,"+e.getMessage();
    MessageUtils.sendMessage(socket, returnmessage);
}

day08

好友界面的双向更新

// 添加好友 4,strs[1]= selfId,strs[2]=friendId
if ("4".equals(strs[0])) {
    memberService = new MemberService();
    Friend friend = new Friend();
    int selfId = Integer.parseInt(strs[1]);
    int friendId = Integer.parseInt(strs[2]);

    // 获取自己的ID
    friend.setSelfId(selfId);
    // 获取朋友的id
    friend.setFriendId(friendId);
    // 添加朋友
    boolean addFriend = memberService.addFriend(friend);
    // 返回的消息
    String addReturn = "4,ok";
    MessageUtils.sendMessage(socket,addReturn);
    // 获取登录的好友集合
    List<Member> friends = memberService.loadFriends(selfId);
    for (Member member2 : friends) {
        System.out.println("111"+member2);
    }
    // 发送对象
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
    oos.writeObject(friends);
    oos.flush();

    // 好友的界面更新

    // 获取朋友的姓名
    Member mems = memberService.loadByName(friendId);
    // 获取登录的好友集合
    List<Member> friends2 = memberService.loadFriends(friendId);
    for (Member member2 : friends2) {
        System.out.println("222"+member2);
    }
    Socket socket2 = Server.namesAndsockets.get(mems.getName());
    // 返回的消息
    String addReturn1 = "4,ok";
    MessageUtils.sendMessage(socket2,addReturn1);
    // 发送对象
    ObjectOutputStream oos1 = new ObjectOutputStream(socket2.getOutputStream());
    oos1.writeObject(friends2);
    oos1.flush();
}

day09

对于异常抛出的处理(一):在DBUtils中的异常抛出处理,由于他本身也是Dao层的直接使用,而且Dao层也是直接操作数据库的,所以将异常抛给Dao层是比较合适的。

public static Connection getConnection() throws SQLException
	{
		return DriverManager.getConnection(DBUrl,DBUser,DBPassword);
	}

对于异常抛出的处理(二):对于Dao的实现类的异常则不可以在向上抛出,因为实现层数是实现了接口的方法,接口的方法只有定义没有实现,无法处理异常。而且接口也无法判断实现方法抛出来的是何种异常。

try {
    conn = DBUtils.getConnection();
    String sql = "select * from t_member where name = ?";
    ps = conn.prepareStatement(sql);
    ps.setString(1, name);
    rs = ps.executeQuery();
    if (rs.next()) {
        flag = true;
    }
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    DBUtils.freeResource(conn, ps, rs);
}
return flag;

day10

DBUtils的建立:注意点,对于conn,ps,rs要先检查是否为空再进行关闭

public final class DBUtils {
	private static String DBDriver = "com.mysql.jdbc.Driver";
	private static String DBUrl = "jdbc:mysql://localhost:3306/db_comm";
	private static String DBUser = "root";
	private static String DBPass = "123456";
	static {
		try {
			Class.forName(DBDriver);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(DBUrl, DBUser, DBPass);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return conn;
	}

	public static void freeReource(Connection conn, PreparedStatement ps,
			ResultSet rs) {

		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (ps != null) {
					try {
						ps.close();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						try {
							conn.close();
						} catch (SQLException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}

	}

	public static void freeReource(Connection conn, PreparedStatement ps) {

		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

设置滚动条

// 设置界面滚动
jp3.setPreferredSize(new Dimension(250,1000));// 这一行必须添加
JScrollPane jsp = new JScrollPane(jp3);
jsp.setBounds(5, 115, 250, 380);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(jsp);

在鼠标点击事件中,要获取init()函数传回来的值,一直获取不到?

我犯的是一个错误是:变量的生命周期不够,每次在执行完init()方法以后,定义在init()方法中的变量的生命就结束了,所以再次点击时按钮时候,就出现了0的情况。

解决:定义一个类成员变量,然后在传回来参数的时候,赋值,点击按钮调用时,即可以获取到。

day11

1.群聊中的一个bug

在写群聊的过程中,发现一个很有意思的事情,如果这个群所有的成员都登录去,聊天就没有问题,可是只要有是部分成员,则会时不时的报空指针异常,而且这些成员只可以发一句话,就会报错。困扰了我很久,断点调试或者是打印调试,都没有问题,很是苦恼。后来一行一行的进行逻辑分析,最后找到了问题的所在。在Client中保存的一个来变量–里面有所有已经登录的用户的socket和name,群发消息主要是通过保存在这个HashMap来寻找所要接收消息的用户的。但是有的而用户并没有登录,而从数据库查出来的数据是这个群里所有的群成员。所以在执行这行代码时就会因为数据不匹配而报空指针。

Socket toSocket = Server.namesAndsockets.get(member2.getName());

修改以后:加一个非空的判断

for (Member member2 : members) {
Socket toSocket = Server.namesAndsockets.get(member2.getName());
    if(toSocket != null){
        System.out.println("["+toSocket+"]");
        MessageUtils.sendMessage(toSocket, line);
    }else{
        continue;
    }
}

day12

老师讲的文件传输,今天听的确实有点懵,所以自己在整理思路的时候,特意画了一幅图,帮助我来理解整个传输过程。

javaSE进阶第二周_第1张图片

你可能感兴趣的:(java,javaSE进阶)