您的位置:首页 > 编程语言 > Java开发

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

2015-07-20 11:17 691 查看

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" onsubmit="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中都有封装好的方法,直接调用即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  io流 操作 java