[学生信息管理系统第三篇]具体业务功能实现--登录及代码解说_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > [学生信息管理系统第三篇]具体业务功能实现--登录及代码解说

[学生信息管理系统第三篇]具体业务功能实现--登录及代码解说

 2011/10/28 8:18:16  yping061  http://yping061.iteye.com  我要评论(0)
  • 摘要:大家好!在第一篇里已经提到该迷你系统的四个业务功能:A.登录;B.查询;C.更新;D.删除,这里先讲第一个业务功能--登录.首先对登录业务进行分析.教员可通过用户名跟密码登陆系统,具体业务流程:教员在登录界面输入用户名跟密码->调用客户业务类的登录方法,向服务发送请求->服务器接收用户发送的登录请求,调用服务器的登录服务,返回结果->服务器向客户端发送响应->客户端接收服务器的响应并进行处理.我们已经明确地知道要实现登录要做些什么:A
  • 标签:功能 实现 代码
     大家好!在第一篇里已经提到该迷你系统的四个业务功能:A.登录;B.查询;C.更新;D.删除,这里先讲第一个业务功能--登录.
    首先对登录业务进行分析.教员可通过用户名跟密码登陆系统,具体业务流程:教员在登录界面输入用户名跟密码->调用客户业务类的登录方法,向服务发送请求->服务器接收用户发送的登录请求,调用服务器的登录服务,返回结果->服务器向客户端发送响应->客户端接收服务器的响应并进行处理.
    我们已经明确地知道要实现登录要做些什么:
    A.创建服务器端ServerSocket,处理客户端登录请求,返回处理结果.
      A.1 在第二篇中,介绍过ServerContextListener类主要用于创建服务端的ServerSocket,接收客户端的请求,加载服务器提供的服务.所以,在接下来的ServerContextListener.java文件中,我们首先要完成服务器端的初始化工作,代码如下
package com.yping.server;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

import com.yping.entity.Student;
import com.yping.entity.Teacher;
import com.yping.util.Datas;
import com.yping.util.SysConstants;
import com.yping.util.Tools;

public class ServerContextListener extends Thread {

	public static void main(String[] args) {
		//启动服务线程
		new ServerContextListener().start();

	}
	public void run(){
		
	//创建服务器Socket对象
	ServerSocket serverSocket=null;
		
	//要接收的客户端Socket对象
          Socket clientIncoming=null;
		
        //创建服务端和客户端两个socket间用于数据通信的输入输出流,因为采用对象序列化,所以用ObjectInputStream
        //和ObjectOutputStream
	ObjectInputStream objInputStream=null;
	ObjectOutputStream objOutputStream=null;
		
	//实例化
	try{
	    serverSocket=new ServerSocket(Integer.parseInt(
						Tools.getValue(SysConstants.SYS_LISTENERPORT)));

	//处理客户端发送的请求方法
	//while循环使服务器始终处于监听状态
	while(true){
	clientIncoming=serverSocket.accept();
	objInputStream=new ObjectInputStream(clientIncoming.getInputStream());
	objOutputStream=new ObjectOutputStream(clientIncoming.getOutputStream());
}
    }catch (NumberFormatException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }finally{
     try{
	 objOutputStream.close();
	 objInputStream.close();
	 clientIncoming.close();
    } catch (IOException e) {
	 // TODO Auto-generated catch block
	 e.printStackTrace();
    }	
  }	
 }
}

      A.2 在上面的代码片断中,服务器创建ServerSocket与客户端进行响应,在传递端口参数实例化ServerSocket时,我们用Tools类读取配置文件sys.properties里的端口号,而配置文件中端口的字串(PORT=8189)由SysConstants类里的一个常量SYS_LISTENERPORT来代表,SysConstants类存放了系统中用于判断或选择的常量:
//创建服务器ServerSocket对象
ServerSocket serverSocket=null;
//因为实例化ServerSocket对象可能会抛出异常,所以放在try块里
serverSocket=new ServerSocket(Integer.parseInt(
						Tools.getValue(SysConstants.SYS_LISTENERPORT)));
//要接收的客户端Socket对象
Socket clientIncoming=null;

      A.2 Tools类的代码也不复杂:
package com.yping.util;

import java.io.IOException;
import java.util.Properties;

public class Tools {
	
    private static Properties p=new Properties();
    static{
    	try{
    		p.load(Tools.class.getClassLoader().getResourceAsStream(SysConstants.SYS_PROPERTYNAME));
    	}catch(IOException e){
    		e.printStackTrace();
    	}
    }
    public static String getValue(String key)
    {
    	return p.getProperty(key);
    }
}
  
      A.3 SysConstants类的代码:
package com.yping.util;

public class SysConstants {
	public static final String SYS_PROPERTYNAME="sys.properties";
	public static final String SYS_LISTENERPORT="PORT";
	public static final String SYS_HOSTNAME="HOST";
	public static final String SYS_SUCCESS="SUCCESS";
	public static final String SYS_ERROR="ERROR";
	public static final String SYS_LOGIN="LOGIN";
	public static final String SYS_FIND="FIND";
	public static final String SYS_UPDATE="UPDATE";
	public static final String SYS_DELETE="DELETE";
}

      A.3 服务器端的初始化工作完成后,就要想办法跟客户端进行"交流",怎么样交流呢?我们在while循环里对客户端保持监听:
while(true){
	clientIncoming=serverSocket.accept();
}

      当客户端连接上服务器的后,服务器端会获得客户端的InputStream和OutputStream,服务器端用这个InputStream读取客户端的消息,例如登录请求,最后再把结果用OutputStream写回客户端:
objInputStream=new ObjectInputStream(clientIncoming.getInputStream());
objOutputStream=new ObjectOutputStream(clientIncoming.getOutputStream());

      A.3 好了,现在万事俱备,只欠东风,服务器与客户端的"沟通桥梁"已经搭好了,只要教员在客户端进行User和Password的输入,服务器就能接收到它的登录请求.那么服务器是怎样知道客户端需要的是一个登录请求服务呢?
if(datas.getFlag().equals(SysConstants.SYS_LOGIN)){
     System.out.println("收到客户端的Login Request");
}

     一个简单的if判断即可让服务器决定客户端需要哪种业务,但这个判断语句里,datas又是怎样的一个对象?就如第一篇我们所提到的,Datas就是在服务器与客户端之间传递的数据,里面封装了教员和学生对象,还有一个判断标志:
package com.yping.util;

import java.io.Serializable;
import java.util.List;

import com.yping.entity.Student;
import com.yping.entity.Teacher;

public class Datas implements Serializable {

	public void setFlag(String flag) {
		this.flag = flag;
	}
	public String getFlag() {
		return flag;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setStudent(Student student) {
		this.student = student;
	}
	public Student getStudent() {
		return student;
	}
	public void setStudentList(List<Student> studentList) {
		this.studentList = studentList;
	}
	public List<Student> getStudentList() {
		return studentList;
	}
	private String flag;	//传递的标识
	private Teacher teacher;	//教员对象
	private Student student;	//学员对象
	private List<Student> studentList;	//学员集合
}

      A.3 现在开始服务器的响应,当教员在客户端进行user和password的输入后,我们用Data类对教员的登录请求和输入的教员信息进行封装,通过Socket传输来到服务器,服务器读取客户端发送过来的Data对象,并根据这个Data对象判断服务请求标志是SYS_LOGIN,调用服务器业务类里的doLogin方法完成登录验证:
//登录服务
if(datas.getFlag().equals(SysConstants.SYS_LOGIN)){
	System.out.println("收到客户端的Login Request");
	String userName=datas.getTeacher().getUserName();
	String passWord=datas.getTeacher().getPassWord();
	//调用业务方法						Teacher teacher=serverService.doLogin(userName, passWord);
	if(teacher==null){
	  datas.setFlag(SysConstants.SYS_ERROR);
	}else{
	      System.out.println("客户端的登录验证成功");
	      datas.setFlag(SysConstants.SYS_SUCCESS);
	      datas.setTeacher(teacher);	
							}
	}else if(datas.getFlag().equals(SysConstants.SYS_FIND)){
	//查询学员信息
	System.out.println("收到客户端的Query Request");
}

     服务器业务类里的登录方法是这样对user和password进行验证的(ServerService.java):
package com.yping.server;

import com.yping.entity.Teacher;
import com.yping.entity.Student;
import java.util.*;

public class ServerService {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	private static Teacher teacher=null; //教员对象
	private static List<Student> studentList=null; //学员集合
	
	static{
		//初始化教员对象和学员集合
		teacher=new Teacher();
		teacher.setId(1);
		teacher.setUserName("admin");
		teacher.setPassWord("admin");
		teacher.setNickName("yping061");
		
		studentList=new ArrayList<Student>();
		studentList.add(new Student(1,"卡斯柯",1,22,1,"麻麻地"));
		studentList.add(new Student(2,"北羊",1,25,0,"我勒了个去的"));
		studentList.add(new Student(3,"通号院",1,25,1,"不错不错,沟通到位"));
		studentList.add(new Student(4,"铁科",2,23,1,"稳定"));
		studentList.add(new Student(5,"信达环宇",2,23,1,"防火墙厂家"));
		
	}
	public Teacher doLogin(String userName,String passWord)
	{
	  //服务器端的登录方法
	  if(userName.equals(teacher.getUserName())&& passWord.equals(teacher.getPassWord()))
	  return teacher;
	  else	return null;
	}
}

      A.4 至此,服务器的工作基本完成,现在做些手尾工作,把响应返回给客户端,也就是用OutputStream将Data对象写回客户端:
objOutputStream.writeObject(datas);
objOutputStream.flush();
clientIncoming.shutdownOutput();
System.out.println("向客户端返回请求数据成功");

    B.创建客户端Socket,发送登录请求,处理返回的响应.
      B.1 前面服务器的工作就是对客户端传输过来的数据(Data对象)判断,判断业务请求标志,是SYS_LOGIN,还是SYS_FIND,抑或是SYS_DELETE等,然后对教员输入的userName和passWord调用方法进行登录验证,然后把结果数据(Data对象)返回客户端,现在,客户端要完成一系列工作了:
package com.yping.client;
import java.util.*;

import com.yping.entity.Student;
import com.yping.entity.Teacher;
import com.yping.util.Datas;
import com.yping.util.SysConstants;

public class Client {

public static void main(String[] args) {	
   Client.createLoginView();
}
   /**
    * 登录视图
    */
   public static void createLoginView(){
   System.out.println("**********Student Information Manager System ************");
   System.out.println("1.Login \n2.Exit");
   System.out.println("**********Please select the operation********************");
   int num=scanner.nextInt();	
   if(num==1){
     while(true){
     System.out.println("User: ");
     String userName=scanner.next();
     System.out.println("Password: ");
     String passWord=scanner.next();
     //调用登录业务,如登录成功显示学员管理界面 
     System.out.println("调用客户端业务--登录(Client.java)");
    Datas data=clientBusiness.doLogin(userName,passWord);
    if(data.getFlag().equals(SysConstants.SYS_SUCCESS)){
	System.out.println("Login Successfully.");
	createStudentManagerView(data.getTeacher());
    }else{
      System.out.println("User name or password error,login failure...");
     }
    }
   }else if(num==2){
      System.out.println("System exit");
      System.exit(0);
   }	
 }
   //控制台输入对象
    private static Scanner scanner=new Scanner(System.in);
   //客户端业务对象
    private static ClientBusiness clientBusiness=new ClientBusiness();
   private static Teacher teacher;
}

      B.2 客户端业务类(ClientBusiness.java)中的doLogin向服务器发送登录请求,而doLogin里的工作就是在客户端也建立对服务器的Socket连接,然后获取服务器Socket通信的InputStream和OutputStream,教员在客户端进行userName和passWord输入后,Datas类实例化将它们进行封装,封装的还有业务标志SYS_LOGIN,最后通过OutputStream的writeObject将Datas类的实例化对象datas发送到服务器端进行验证:
 //调用登录业务,如登录成功显示学员管理界面 
 System.out.println("调用客户端业务--登录(Client.java)");
 Datas data=clientBusiness.doLogin(userName,passWord);

      每个业务功能(登录,查询,更新,删除)里都会调用到的初始化socket和关闭socket方法:
public void initSocket(){
  //实例化Socket对象
   String hostName=Tools.getValue(SysConstants.SYS_HOSTNAME);
   int port=Integer.parseInt(Tools.getValue(SysConstants.SYS_LISTENERPORT));
   try {
         incoming=new Socket(hostName,port);
	//incoming.setSoTimeout(10000);
	System.out.println("与服务器连接成功");
	objOutputStream=new ObjectOutputStream(incoming.getOutputStream());
	System.out.println("获得服务器输出流");
	objInputStream=new ObjectInputStream(incoming.getInputStream());
	System.out.println("获得服务器输入流");
    } catch (UnknownHostException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
    } catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
    }
}

public void closeSocket(){
  try{
         objInputStream.close();
	objOutputStream.close();
	incoming.close();
  }catch(IOException e){
	e.printStackTrace();
  }
}

    C.根据服务器返回的响应对登录视图进行更新,如果成功登录,则显示管理功能菜单.
      C.1 到目前为止,我们在服务器端与客户端之间的"交互"工作已经完成,只需在客户端判断服务器的响应,也就是传回来的数据--Data类的datas对象,判断该对象里面的标志是否为SYS_SUCCESS,如果是,就显示出学生信息管理的功能菜单:
if(data.getFlag().equals(SysConstants.SYS_SUCCESS)){
  System.out.println("Login Successfully.");
  createStudentManagerView(data.getTeacher());
}else{
  System.out.println("User name or password error,login failure...");
}

    呼~~登录业务的功能讲解到这里就算完成了,另外三个业务:查询,更新跟删除,代码实现步骤都是一样,各个类的作用如果还有不清楚的地方可以参考第一篇,这里我会附上完整源代码,有兴趣有好的建议请发邮件到944278277@qq.com,谢谢~~
  • StuInfo.rar (21.8 KB)
  • 下载次数: 6
发表评论
用户名: 匿名