利用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中都有封装好的方法,直接调用即可。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统