【XML解析】(6)利用XML+DOM4j+Xpath+MD5加密+图形界面(Jtabe+Vector)实现《通讯录管理系统》

【通讯录管理系统】

(一)项目所需的技术:

1、XML相关技术

2、DOM4J相关技术

3、Xpath相关技术

4、MD5加密相关技术

5、图形界面JTable、历史集合Vector相关技术

拥有了上面的这些技术,可以写一个简单的“通讯录管理程序了”!

(二)实现方式:

首先需要对整个系统框架进行分层:

这里写图片描述

(三)代码分析演示:

(1)表现层:

LoginWin:

package cn.hncu.contact.ui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.dao.factory.ContactDAOfactory;

public class LoginWin extends JFrame{
    ContactDAO dao=ContactDAOfactory.getContactDAO();
    public LoginWin(String string) {
        //界面基本默认参数设置
        setTitle(string);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(200, 200, 300, 150);
        Container c=getContentPane();
        c.setLayout(new FlowLayout());
        //显示表格的 
        //用户交互组件:----输入
        JLabel jlb1=new JLabel("姓名");
        c.add(jlb1);
        final JTextField tfdName= new JTextField(20);
        c.add(tfdName);
        JLabel jlb2=new JLabel("密码");
        c.add(jlb2);
        final JPasswordField tfdPwd=new JPasswordField(20);
        c.add(tfdPwd);

        //用户交互组件:----按钮
        JPanel jpl2=new JPanel();
        c.add(jpl2,BorderLayout.SOUTH);
        /*
         * 登录按钮的事件交互
         */
        JButton btnLogin=new JButton("登录");
        jpl2.add(btnLogin);
        btnLogin.setActionCommand("login");
        btnLogin.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getActionCommand().equals("login")){
                    //1、收集参数
                    String name=tfdName.getText();
                    String pwd=new String(tfdPwd.getPassword());
                    //2、组织参数(略过,因为逻辑层没有写,JavaBean也就不用封装了)
                    //3、调用逻辑层(略过,直接在表现层调用DAO,不用在逻辑层调用DAO,小程序就简写了)
                    boolean boo=dao.login(name,pwd);
                    //4、根据逻辑层返回结果执行不同的结果页面
                    if(boo){
                        /*【注意】:
                         * 此时有个问题:
                         * --①某个用户登录成功后,ContactWin中的JTable会显示【当前用户】下的所有联系人的详细信息;
                         * --②当我们new ContactWin之后,该如何知道当前的ContactWin界面的用户就是已经登录的用户;
                         * --③ContactWin完全没有必然的联系,该如何将登录时候的用户传到登录后的界面中去呢?
                         * --④可以将当前登录时候调用的dao传给ContactWin界面,因为dao是唯一的;
                         * --⑤因为传的是同一个dao,用户肯定是同一个;
                         * --⑥但是我们在登录的同时要将所调用的dao作为当前dao存储记录下来,好让下个界面使用;
                         * 
                         */
                        new ContactWin(dao);
                    }else{
                        JOptionPane.showMessageDialog(LoginWin.this, "用户名或密码错误");
                        return;
                    }
                }
            }
        });
        /*
         * 注册按钮的事件交互
         */
        JButton btnReg=new JButton("注册");
        jpl2.add(btnReg);
        btnReg.setActionCommand("reg");
        btnReg.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getActionCommand().equals("reg")){
                    String name=tfdName.getText();
                    String pwd=new String(tfdPwd.getPassword());
                    boolean boo=dao.reg(name, pwd);
                    if(boo){
                        System.out.println(boo);
                    }else{
                        System.out.println(boo);
                    } 
                }
            }
        });
        /*
         * 取消按钮的事件交互
         */
        JButton btnCancel =new JButton("取消");
        jpl2.add(btnCancel);
        btnCancel.setActionCommand("cancel");
        btnCancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getActionCommand().equals("cancel")){
                    System.exit(0);
                }
            }
        });
        setVisible(true);
    }

    public static void main(String[] args) {
        new LoginWin("通讯录管理系统");
    }

}

ContactWin:

package cn.hncu.contact.ui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

import cn.hncu.contact.dao.ContactDAO;

public class ContactWin extends JFrame{
    /*
     * 接收当前dao为参数中的dao
     */
    private static ContactDAO dao=null;
    public ContactWin(final ContactDAO dao){
        /*
         * 表现层默认参数设置
         */
        setTitle("联系人管理");
        setBounds(100, 100, 900, 400);
        Container c=getContentPane();

        /*
        维护Table数据层数据
        data the data of the table, a Vector of Vectors of Object values
        columnNames vector containing the names of the new columns
        */
        //①添加表头---将固定的表头添加到列名集合中
        final Vector<String> columnNames =new Vector<String>();
        columnNames.add("ID");
        columnNames.add("Name");
        columnNames.add("Sex");
        columnNames.add("Tell");
        columnNames.add("Addr");
        //②添加表数据---从数据库中拿到所有的信息,然后逐行遍历并且添加到表格
        Vector<Vector<Object>> data=new Vector<Vector<Object>>();
        Vector<Vector<Object>> vv=dao.getAllContacts();
        for(Vector<Object> v:vv){
            data.add(v);
        }
        //③添加数据库中读取的所有信息加入到表格中
        final DefaultTableModel dtm=new DefaultTableModel(data, columnNames);
        final JTable jtable=new JTable(dtm);
        jtable.removeColumn(jtable.getColumn("ID"));
        c.add(new JScrollPane(jtable));

        /*
         * 用户交换数据的表现层
         */
        JPanel jpl2=new JPanel();
        JLabel jlb1=new JLabel("姓名");
        jpl2.add(jlb1);
        final JTextField tfdName=new JTextField(10);
        jpl2.add(tfdName);

        JLabel jlb2=new JLabel("性别");
        jpl2.add(jlb2);
        final JTextField tfdSex=new JTextField(10);
        jpl2.add(tfdSex);

        JLabel jlb3=new JLabel("电话");
        jpl2.add(jlb3);
        final JTextField tfdTel=new JTextField(10);
        jpl2.add(tfdTel);

        JLabel jlb4=new JLabel("地址");
        jpl2.add(jlb4);
        final JTextField tfdAddr=new JTextField(10);
        jpl2.add(tfdAddr);

        /*
         * 按钮---实现逻辑层功能
         */
        //按钮---添加
        JButton btnAdd=new JButton("添加");
        jpl2.add(btnAdd);
        btnAdd.setActionCommand("add");
        btnAdd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getActionCommand().equals("add")){
                    //1、收集数据
                    //2、组织数据
                    String name=tfdName.getText();
                    String sex=tfdSex.getText();
                    String tell=tfdTel.getText();
                    String addr=tfdAddr.getText();
                    //3、调用数据层
                    boolean boo=dao.addContact(name,sex,tell,addr);
                    //4、根据调用结果返回不同结果页面
                    if(boo){
                        //回显---从数据库中读出所有信息添加到表格中
                        Vector<Vector<Object>> dataVector =dao.getAllContacts();
                        dtm.setDataVector(dataVector, columnNames);
                        jtable.removeColumn(jtable.getColumn("ID"));
                    }else{
                        JOptionPane.showMessageDialog(ContactWin.this, "此联系人已经存在");
                    }
                }
            }
        });

        //按钮---删除
        JButton btnDel=new JButton("删除");
        jpl2.add(btnDel);
        btnDel.setActionCommand("del");
        btnDel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int num=jtable.getSelectedRow();
                if(num==-1){
                    JOptionPane.showMessageDialog(ContactWin.this, "请选择要删除的一行表格数据");
                    return;
                }
                //Object getValueAt(int row, int column) 返回 row 和 column 处单元格的属性值。
                String id=(String) dtm.getValueAt(num, 0);
                String name=(String) dtm.getValueAt(num, 1);
                boolean boo=dao.delContact(id);
                if(boo){
                    dtm.setDataVector(dao.getAllContacts(), columnNames);
                    JOptionPane.showMessageDialog(ContactWin.this, "联系人"+name+"已经删除成功!");
                    return;
                }else{
                    JOptionPane.showMessageDialog(ContactWin.this, "联系人"+name+"删除失败!");
                    return;
                }
            }
        });
        //按钮---修改
        JButton btnUpDate=new JButton("修改");
        jpl2.add(btnUpDate);
        btnUpDate.setActionCommand("update");
        btnUpDate.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int num=jtable.getSelectedRow();
                if(num==-1){
                    JOptionPane.showMessageDialog(ContactWin.this, "请选择要修改的一行表格数据");
                    return;
                }
                String id=(String) dtm.getValueAt(num, 0);
                //直接读取对应编辑框中的内容作为修改的值
                String name=tfdName.getText();
                String sex=tfdSex.getText();
                String tell=tfdTel.getText();
                String addr=tfdAddr.getText();
                boolean boo=dao.upDateContact(id,name,sex,tell,addr);
                if(boo){
                    dtm.setDataVector(dao.getAllContacts(), columnNames);
                    JOptionPane.showMessageDialog(ContactWin.this, "联系人修改成功");
                    return;
                }else{
                    JOptionPane.showMessageDialog(ContactWin.this, "联系人修改失败");
                    return;
                }
            }
        });


        //按钮---查询
        JButton btnQuery=new JButton("查询");
        jpl2.add(btnQuery);
        btnQuery.setActionCommand("query");
        btnQuery.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("查询");
            }
        });



        c.add(jpl2,BorderLayout.SOUTH);

        setVisible(true);
    }
    public static void main(String[] args) {
        new ContactWin(dao);
    }
}

(2)DAO层:

(2-1)接口:

ContactDAO:

package cn.hncu.contact.dao;

import java.util.Vector;

public interface ContactDAO {
    public boolean login(String name,String pwd);
    public boolean reg(String name,String pwd);
    public Vector<Vector<Object>> getAllContacts();
    public boolean addContact(String name, String sex, String tell, String addr);
    public boolean delContact(String id);
    public boolean upDateContact(String id, String name, String sex, String tell, String addr);
}

(2-2)工厂:

ContactDAOfactory:

package cn.hncu.contact.dao.factory;

import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.dao.impl.ContactDAOImpl;

public class ContactDAOfactory {
    private ContactDAOfactory(){
    }
    public static ContactDAO getContactDAO(){
        return new ContactDAOImpl();
    }

}

(2-3)实现类:

ContactDAOImpl:

package cn.hncu.contact.dao.impl;

import java.util.List;
import java.util.Vector;

import org.dom4j.Document;
import org.dom4j.Element;

import cn.hncu.contact.commons.DocumentFactory;
import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.utils.PwdUtils;
import cn.hncu.contact.utils.UUIDUtils;

public class ContactDAOImpl implements ContactDAO{
    private Document dom=DocumentFactory.getDom();
    private Element eCurrentUser=null;
    /**
     * 登录某一个用户
     */
    @Override
    public boolean login(String name, String pwd) {
        //1、收集数据
        //2、组织数据对密码进行MD5加密
        String newPwd=PwdUtils.mkMD5Pwd(pwd);
        //3、调用逻辑层
        Element root=dom.getRootElement();
        Element euser=(Element) root.selectSingleNode("/contacts/user[@name='"+name+"'][@pwd='"+newPwd+"']");
//      Element euser =root.element("user");
        if(euser!=null){
            /*
             * 将当前登录的用户元素记录下来,以供下次调用用户管理界面使用
             */
            eCurrentUser=euser;
            return true;
        }
        return false;
    }

    /**
     * 用户注册
     */
    @Override
    public boolean reg(String name, String pwd) {
        //1、收集参数
        //2、组织参数
        //判断此注册用户是否已经存在:::
        Element root=dom.getRootElement();
        List<Element>list=root.elements("user");
        for(Element e:list){
            if(name.equals(e.attribute("name"))){
                return false;
            }
        }
        String newPwd=PwdUtils.mkMD5Pwd(pwd);
        Element user=root.addElement("user");
        user.addAttribute("name", name);
        user.addAttribute("pwd", newPwd);
        //保存修改后的DOM树
        DocumentFactory.save();
        return true;
    }

    /**
     * 获得所有的联系人
     */
    @Override
    public Vector<Vector<Object>> getAllContacts() {
        Vector<Vector<Object>> vv=new Vector<Vector<Object>>();
        List<Element> list=eCurrentUser.elements("contact");
        for(Element e:list){
            Vector<Object> v=new Vector<Object>();
            v.add(e.attribute("id").getText());
            v.add(e.elementText("name"));
            v.add(e.elementText("sex"));
            v.add(e.elementText("tell"));
            v.add(e.elementText("addr"));
            vv.add(v);
        }
        return vv;
    }

    /**
     * 添加某一个联系人
     */
    @Override
    public boolean addContact(String name, String sex, String tell, String addr) {
        List<Element> list=eCurrentUser.elements("contact");
        //需要判断下联系人是否已经存在
        for(Element e:list){
            if(name.equals(e.elementText("name"))){
                return false;
            }
        }
        String id=UUIDUtils.getID();
        Element eContact=eCurrentUser.addElement("contact").addAttribute("id", id);
        eContact.addElement("name").setText(name);
        eContact.addElement("sex").setText(sex);
        eContact.addElement("tell").setText(tell);
        eContact.addElement("addr").setText(addr);
        //保存修改后的DOM树
        DocumentFactory.save();
        return true;
    }

    /**
     * 删除一个联系人
     */
    @Override
    public boolean delContact(String id) {
        //利用XPath直接找到要删除的联系人
        Element contact=(Element) eCurrentUser.selectSingleNode("//contact[@id='"+id+"']");
        boolean boo=contact.getParent().remove(contact);
        if(boo){
            DocumentFactory.save();
        }
        return boo;
    }

    /**
     * 更新一个联系人
     */
    @Override
    public boolean upDateContact(String id, String name, String sex,
            String tell, String addr) {
        Element contact=(Element) eCurrentUser.selectSingleNode("//contact[@id='"+id+"']");
        contact.element("name").setText(name);
        contact.element("sex").setText(sex);
        contact.element("tell").setText(tell);
        contact.element("addr").setText(addr);
        DocumentFactory.save();
        return true;
    }


}

(3)公共数据层:

DocumentFactory:

package cn.hncu.contact.commons;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class DocumentFactory {
    private static File file = null;
    private static Document dom = null;

    private DocumentFactory() {
    }

    /**
     * 
     * @return 获得DOM树
     */
    public static Document getDom() {
        try {
            file = new File("./xml/contacts.xml");
            SAXReader sax = new SAXReader();
            dom = sax.read(file);
        } catch (DocumentException e) {
            throw new RuntimeException("xml数据库读取异常");
        }
        return dom;
    }

    /**
     * 保存修改后的DOM树
     */
    public static void save() {
        try {
            XMLWriter xw=new XMLWriter(new FileOutputStream(file),
                    OutputFormat.createPrettyPrint());
            xw.write(dom);
            xw.close();
        } catch (IOException e) {
            throw new RuntimeException("数据库写入失败");
        }
    }
}

(4)工具层:

PwdUtils:

package cn.hncu.contact.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class PwdUtils {
    public PwdUtils(){
    }
    public static String mkMD5Pwd(String pwd){
        String newPwd="";
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("加密失败");
        }
        byte[] b=md.digest(pwd.getBytes());
        /*
         * 对b字节数组进一步处理转换成16进制
         */
        for(byte i:b){
            String s=Integer.toHexString(i&0xFF);
            if(s.length()==1){
                s="0"+s;
            }
            newPwd+=s;
        }
        newPwd=newPwd.toUpperCase();
        return newPwd;
    }

}

UUIDUtils:

package cn.hncu.contact.utils;

import java.util.UUID;

public class UUIDUtils {
    private UUIDUtils(){
    }
    public static String getID(){
        return UUID.randomUUID().toString().replace("-", "");
    }
}

结果:

这里写图片描述
这里写图片描述
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值