利用java的可序列化IO流仿数据库原理进行CRUD操作。

1、序列化简介:

      Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。
使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,在未来,再将这些字节组装成对象。必须注意地是,对象序列化保存的是对象的"状态",即它的成员变量。由此可知,对象序列化不会关注类中的静态变量。
    除了在持久化对象时会用到对象序列化之外,当使用RMI(远程方法调用),或在网络中传递对象时,都会用到对象序列化。Java序列化API为处理对象序列化提供了一个标准机制,该API简单易用,而我今天只是把序列化运用到javaWeb中实现,将序列化文件当成一个小型数据库来进行CRUD操作。

2、整体项目:


1、User.java是实现序列的对象,java规定要对某个类进行序列化必须实现Serializable接口:

package cn.bjcx.bean;

import java.io.Serializable;

public class User implements Serializable{
	private static final long serialVersionUID = 1L;
	private Integer userId;
	private String password;
	public Integer getUserId() {
		return userId;
	}
	public void setUserId(Integer userId) {
		this.userId = userId;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	//重写equal方法,对文件进行查询的时候,利用id唯一,保证对每个对象的准确性
		@Override
		public boolean equals(Object obj) {
			boolean flag = false;
			if(obj instanceof User) {
				User user = (User)obj;
				if(this.userId.equals(user.getUserId())&&this.password.equals(user.getPassword()) ) {
					flag=true;
				}
			}
			return flag;
		}
		@Override
		public String toString() {
			return "User [userId=" + userId + ", password=" + password + "]";
		}

}

2、FileObjectManager.java封装了对序列对象的基本CRUD操作

package cn.bjcx.util;


import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import cn.bjcx.bean.User;

/**
 * 文件对象管理类
 * 
 * @author 林浩007
 * 
 */
public class FileObjectManager {

	private String filePath;

	private String fileName;

	private ObjectOutputStream oos;
	private ObjectInputStream ois;

	public FileObjectManager() {
	}

	public FileObjectManager(String filePath) {
		this.filePath = filePath;
		init(filePath);
	}

	public String getFileName() {
		return fileName;
	}

	private void init(String fileName) {
		this.fileName = fileName;
		// 对文件名分割,当分割长度为1时,则代表输入的是没有后缀的文件名,若输入的有后缀,则将后缀替换为txt
		String[] splitPath = fileName.split("\\.");
		if (splitPath.length == 1) {
			fileName += "User.txt";
		} else {
			fileName = splitPath[0] + ".txt";
		}
		try {
			open();
		} catch (IOException e) {
		}
	}
	
	/**
	 * 打开该流的输入输出
	 * 
	 * @throws IOException
	 */
	public static FileObjectManager open(String filePath) throws IOException {
		return new FileObjectManager(filePath);
	}

	/**
	 * 
	 * @param filePath
	 *            文件路径
	 * @param UserList
	 *            对象集合
	 * @param flag
	 *            是否追加添加
	 * @throws IOException
	 */
	public synchronized void save(List<User> UserList, boolean flag)
			throws IOException {
		// 改变输出文件的流的具体方式
		changeObjectOutputStream(flag);

		for (int i = 0; i < UserList.size(); i++) {
			save0(UserList.get(i));
		}
	}

	/**
	 * 将对象输出到对应的流中
	 * 
	 * @param User
	 */
	private synchronized void save0(User User) {
		try {
			oos.writeObject(User);
			oos.flush();
		} catch (IOException e1) {
		}
	}

	/**
	 * 保存单个User对象
	 * 
	 * @param filePath
	 * @param User
	 * @param flag
	 *            // 允许对象添加到之后而不是覆盖
	 * @throws IOException
	 */
	public synchronized void save(User user, boolean flag)
			throws IOException {
		// 改变输出文件的流的具体方式
		changeObjectOutputStream(flag);

		save0(user);
	}

	public synchronized User readAObject() throws IOException {
		User User = null;
		try {
			User = (User) ois.readObject();
		} catch (ClassNotFoundException e) {
			throw new IOException("读取对象出错");
		}
		return User;
	}

	/**
	 * 读出对应文件中的所有对象
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public synchronized List<User> read() throws IOException {
		List<User> objectList = new ArrayList<User>();
		User User = null;
		try {
			if (ois == null) {
				return objectList;
			}
			while ((User = (User) ois.readObject()) != null) {
				objectList.add(User);
			}
		} catch (EOFException e) {
		} catch (IOException e1) {
			// throw e1;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return objectList;
	}

	/**
	 * 查询此User对象是否存在
	 * 
	 * @param filePath
	 * @param User
	 * @return
	 * @throws IOException
	 */
	public synchronized User query(User User) throws IOException {
		List<User> list = this.read();
		int index = this.query0(list, User);
		if (index != -1) {
			return list.get(index);
		}
		return null;
	}

	public synchronized boolean contains(User User) throws IOException {
		List<User> list = this.read();
		int index = this.query0(list, User);
		if (index != -1) {
			return true;
		}
		return false;
	}

	/**
	 * 查询此对象在此集合中的下标
	 * 
	 * @param list
	 * @param User
	 * @return
	 */
	private synchronized int query0(List<User> list, User User) {
		for (int i = 0; i < list.size(); i++) {
			if (User.equals(list.get(i))) {
				// System.out.println(User.getVo().getUsername());
				return i;
			}
		}
		return -1;
	}

	/**
	 * 删除一个存放了User对象的list集合中的所有对象,并且返回对应数据库中的对象集合
	 * 
	 * @param filePath
	 * @param list
	 * @return
	 * @throws IOException
	 */
	public synchronized List<User> delete(List<User> list)
			throws IOException {
		// 获得此文件中所有的对象集合
		List<User> newList = new ArrayList<User>();
		List<User> objectList = this.read();
		int index = -1;
		boolean flag = false;
		// 删除对应的对象
		for (int i = 0; i < list.size(); i++) {
			if ((index = this.query0(objectList, list.get(i))) != -1) {
				flag = true;
				// 添加得到的数据
				newList.add(objectList.get(index));
				objectList.remove(index);
			}
		}
		// 再对对象进行重新保存在文件中
		if (flag) {
			try {
				this.save(objectList, false);
			} catch (IOException e) {
				throw e;
			}
		}
		return newList;
	}

//	修改某个对象
	public synchronized void  update(User User)
			throws IOException {
		// 获得此文件中所有的对象集合
		List<User> objectList = this.read();
		int index = -1;
		boolean flag = false;
		// 修改对应的对象
		if ((index = this.query0(objectList, User)) != -1) {//查找对应的对象的id
				flag = true;
				// 添加得到的数据
				objectList.remove(index);//查到相同的,将其删除
				objectList.add(User);
				this.save(objectList, false);
		}
		// 再对对象进行重新保存在文件中
	}
	/**
	 * 获取对象文件的输入流
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	private synchronized ObjectInputStream getObjectInputStream() {
		File file = new File(filePath);
		if (!file.exists()) {
			File directions = new File(file.getAbsolutePath().substring(0,
					file.getAbsolutePath().lastIndexOf("\\")));
			directions.mkdirs();
			try {
				file.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		try {
			InputStream is = new FileInputStream(file);
			ois = new ObjectInputStream(is);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
		}
		return ois;
	}

	/**
	 * 获取对象文件的输出流
	 * 
	 * @param filePath
	 * @param flag
	 * @return
	 * @throws IOException
	 */
	private synchronized ObjectOutputStream getObjectOutputStream(boolean flag)
			throws IOException {
		File file = new File(filePath);
		OutputStream os = new FileOutputStream(file, flag);
		try {
			oos = FileObjectOutputStream.newInstance(file, os);
		} catch (IOException e) {
			throw new IOException("获取文件输出流错误!");
		}
		return oos;
	}

	/**
	 * 若flag传入为false时则认为需要改变文件的输出方式,为不追加的添加数据
	 * 
	 * @param flag
	 * @throws IOException
	 */
	private void changeObjectOutputStream(boolean flag) throws IOException {
		// flag不为true时,则需要的是不追加的流对象
		if (!flag) {
			if (oos != null) {
				oos.close();
			}
			oos = getObjectOutputStream(flag);
		}
	}

	public void close() throws IOException {
		if (ois != null) {
			ois.close();
			ois = null;
		}
		if (oos != null) {
			oos.close();
			oos = null;
		}
	}

	/**
	 * 打开该流的输入输出
	 * @throws IOException
	 */
	public void open() throws IOException {
		ois = getObjectInputStream();
		oos = getObjectOutputStream(true);
	}

	/**
	 * 判断流是否打开 
	 * @return
	 * @throws IOException
	 */
	public boolean isOpen() throws IOException{
		if(ois == null && oos == null) {
			return true;
		}
		return false;
	}
	
}

3、FileObjectOutputStream.java文件对象输出封装类:

package cn.bjcx.util;

import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

class FileObjectOutputStream extends ObjectOutputStream {
	// 定义成静态的好处
	private static File f;
	/**
	 * 初始化静态文件对象,并返回类对象
	 * 
	 * @param file
	 *            文件对象,用于初始化静态文件对象
	 * @param out
	 *            输出流
	 * @return MyObjectOutputStream
	 * @throws IOException
	 */
	public static FileObjectOutputStream newInstance(File file, OutputStream out)
			throws IOException {
		f = file;// 本方法最重要的地方:构建文件对象,是两个文件对象属于同一个
		return new FileObjectOutputStream(out, f);
	}

	@Override
	protected void writeStreamHeader() throws IOException {
		if (!f.exists() || (f.exists() && f.length() == 0)) {
			super.writeStreamHeader();
		} else {
			super.reset();
		}

	}

	public FileObjectOutputStream(OutputStream out, File f) throws IOException {
		super(out);
	}

}

3、LoginServlet.java对表单数据进行封装成对象User进行写入到user.csv中注册和验证登入

package cn.cxjy.web;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import cn.bjcx.bean.User;
import cn.bjcx.util.FileObjectManager;
public class LoginServlet extends HttpServlet {
	private static String filePath = "G:\\北京实训实例\\TrainingTest\\src\\user.csv";
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}
	FileObjectManager  fom = new FileObjectManager(filePath);
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String username = request.getParameter("username");
		String pasw = request.getParameter("pasw");
		HttpSession session = request.getSession();
		String method = request.getParameter("method");
		System.out.println("method" + method);
        //根据前台传入的method是否为空进行判断是登入还是注册		
		if (method != null) {
			if (method.equals("register")) {//method为register,那么进行注册,并将对象实现序列化
				 FileObjectManager  fom = new FileObjectManager(filePath);
				  List<User> studentList = new ArrayList<User>();
				  User user = new User();
				  user.setUserId(Integer.valueOf(request.getParameter("userId")));
				  user.setPassword(request.getParameter("pasw"));
				  studentList.add(user);
			      fom.save(studentList, true);//实现user对象的序列化,成功之后跳转到登入index.jsp页面
			      request.getRequestDispatcher("index.jsp").forward(
							request, response);
			} else {
				session.invalidate();
				response.sendRedirect("index.jsp");
			}
		} else {
			//反序列化创建对象,查询用户登入的用户名和密码是否正确,正确就登入成功
			if (judgeUser(username, pasw)) {
				session.setAttribute("username", username);
				request.getRequestDispatcher("demo1/successful.jsp").forward(
						request, response);
			} else {
				request.getRequestDispatcher("demo1/error.jsp").forward(
						request, response);
			}
		}

	}
//判断用户名和密码
	private boolean judgeUser(String username,String pasw) throws IOException{
		boolean flag = false;
		User user = new User();
		user.setUserId(Integer.valueOf(username));
		System.out.println(username);
		user.setPassword(pasw);
		List<User> list = fom.read();//查询
		   for(int i=0;i<list.size();i++){
			  if(list.get(i).equals(user)){
				  flag=true;
			  }
		   }
		return flag;
	}

}

4、登入与注册页面以及判断用户是否登入成功:

index.sp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>序列化操作</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<script language="javascript" src="demo1/judge.js"></script>
</head>
<body>
<!-- 登入页面 -->
<%
session.invalidate();
 %>
	<center>
		<h1>实训第一次作业---》javaScript验证</h1>
		  <form action="LoginServlet" οnsubmit="check()"
			method="post"> 
			<table>
				<tr>
					<th>输入姓名:</th>
					<th><input type="text" name="username" id="username" />
					</th>
				</tr>
				<tr>
					<th>输入密码:</th>
					<th><input type="password" name="pasw" id="pasw" />
					</th>
				</tr>
				<tr>
					<th><a href="demo1/Registered.jsp">注册</a></th>
					<th><input type="submit" value="验证"  onClick="check()"/>
						    <input type="reset" value="重置" />
					</th>
				</tr>
			</table>
		</form>
	</center>
</body>
</html>

Registered.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">  
    <title>商品注册</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
  </head>
  <body>
    <form action="LoginServlet?method=register" method="post">
    <table>
    <tr>
    <th>用户账号</th>
     <tr><input type="text" name="userId" id="userId" /></tr>
    </tr>
    <tr>用户密码</tr>
    <tr><input type="password" name="pasw" id="pasw" /></tr>
    <tr></tr>
    <tr><input type="submit" value="注册"/></tr>
    </table>
    </form>
  </body>
</html>

successful.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>结果</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>
<body>
	<center>
		<%
			/* HttpSession session = request.getSession(); */
			Object username = session.getAttribute("username");
			if (username == null) {
				username = request.getParameter("username");
				session.setAttribute("username", username);
			} else {
		%>
		<h1>您已经登入过了</h1>
		<%
			}
		%>
		<br> 姓名:<%=session.getAttribute("username")%>
		<a href="index.jsp">注销</a>
	</center>
</body>
</html>

judge.js:

function check() {
	var username = document.getElementById("username").value;
	var pasw = document.getElementById("pasw").value;
	if (username == "" || pasw == "") {
		alert("用户名和密码不能为空");
		return flase;
	} else {
		if (username.indexOf("#") != -1 || username.indexOf("*") != -1) {
			alert("包含非法字符#或者*,请从新验证");
			return flase;
		}
	}
	return true;
}

以上代码是利用序列化进行注册和登入验证的实例,修改和删除实例在FileObjectManager.java中都有封装好的方法,直接调用即可。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值