精华内容
下载资源
问答
  • 在net.hw.student.gui包里创建个类LoginFrame、RegisterFrame和MainFrame 1、创建主界面窗口MainFrame 目前只是创建一个可以显示出来和关闭的主界面窗口,等到将各个功能模块窗口界面都完成了,我们会修改代码,...

    七、实现步骤

    (十)创建窗口界面类

    • 在上一讲,在net.hw.student.gui包包里已经创建三个类LoginFrame、RegisterFrame和MainFrame
      在这里插入图片描述

    1、创建主界面窗口MainFrame

    目前只是创建一个可以显示出来和关闭的主界面窗口,等到将各个功能模块窗口界面都完成了,我们会修改代码,给出主窗口界面的最终版。

    • MainFrame继承JFrame类
      在这里插入图片描述
    • 添加构造方法(有一个标题参数的构造方法)
      在这里插入图片描述
    • 在类的声明部分声明两个变量:状态服务变量与状态变量
      在这里插入图片描述
    • 创建初始化图形用户界面方法initGUI()
      在这里插入图片描述
    • 在构造方法里调用初始化图形用户界面方法initGUI()
      在这里插入图片描述
    • 编写主方法代码,实例化主窗口,设置空标题,保存到Application的变量mainFrame里
      在这里插入图片描述
    • 如果希望单击关闭按钮后,弹出一个询问框,询问用户是否要退出系统,那么就不用采用上述方法,而应该采用注册窗口监听器的方法,通过编写事件处理方法来弹出询问对话框。
      在这里插入图片描述
      在这里插入图片描述
    • 运行程序,查看结果
      在这里插入图片描述
      在这里插入图片描述

    2、创建用户登录窗口LoginFrame

    • 继承JFrame,创建LoginFrame
      在这里插入图片描述
    • 创建初始化图形用户界面方法
      在这里插入图片描述
    • 添加单参构造方法
      在这里插入图片描述
    • 添加主方法,实例化用户登录窗口
      在这里插入图片描述
    • 运行程序,查看结果
      在这里插入图片描述
    • 空白的用户登录窗口,不能调整大小
      在这里插入图片描述
    • 声明用户登录窗口所需变量
      在这里插入图片描述
    • 实例化组件
      在这里插入图片描述
    • 将控件添加到小面板,然后将小面板添加到主面板
      在这里插入图片描述
    • 设置按钮热键字母,以及密码框的回显字符
      在这里插入图片描述
    • 运行程序,查看效果
      在这里插入图片描述
    • 行间距太大,界面显得不紧凑,怎么设置窗口属性,才能让界面紧凑好看呢?很简单,调用窗口的pack()方法即可。
      在这里插入图片描述
    • 运行程序,查看效果
      在这里插入图片描述
    • 单击【确定】按钮,或当焦点落在【确定】按钮时按回车键,都会调用登录方法login()。
      在这里插入图片描述
    • 编写用户登录方法login()
    /**                                                                            
     * 登录方法                                                                        
     */                                                                            
    private void login() {                                                         
        // 获取用户名                                                                   
        username = txtUsername.getText().trim();                                   
        // 获取密码                                                                    
        password = new String(txtPassword.getPassword());                          
                                                                                   
        // 创建用户服务对象                                                                
        UserService userService = new UserServiceImpl();                           
        // 调用登录方法,返回登录用户对象                                                         
        User user = userService.login(username, password);                         
                                                                                   
        // 判断登录用户是否为空,决定登录是否成功                                                     
        if (user != null) {                                                        
            // 隐藏登录窗口                                                              
            Application.loginFrame.setVisible(false);                              
            // 定义状态服务对象                                                            
            StatusService statusService = new StatusServiceImpl();                 
            // 获取状态对象                                                              
            Status status = statusService.findStatusById(1);                       
            // 保存登录用户的信息                                                           
            Application.id = user.getId();                                         
            Application.username = user.getUsername();                             
            Application.password = user.getPassword();                             
            // 提示用户登录成功                                                            
            JOptionPane.showMessageDialog(null,                                    
                    "欢迎使用学生信息管理系统" + status.getVersion(),                          
                    "用户登录", JOptionPane.INFORMATION_MESSAGE);                      
            // 显示系统主窗口                                                             
            Application.mainFrame = new MainFrame("");                             
            // 释放登录窗口                                                              
            Application.loginFrame.dispose();                                      
        } else {                                                                   
            // 隐藏登录窗口                                                              
            Application.loginFrame.setVisible(false);                              
            // 提示用户登录失败,要重新输入用户名或密码                                                
            JOptionPane.showMessageDialog(null,                                    
                    "用户名或密码错误,请重新输入!",                                             
                    "用户登录", JOptionPane.ERROR_MESSAGE);                            
            // 显示登录窗口                                                              
            Application.loginFrame.setVisible(true);                               
            // 用户名文本框内容全选                                                          
            txtUsername.selectAll();                                               
            // 密码文本框内容全选                                                           
            txtPassword.selectAll();                                               
            // 用户名文本框获取焦点                                                          
            txtUsername.requestFocus();                                            
        }                                                                          
    }                                                                              
    
    • 运行程序,查看效果
      在这里插入图片描述
    • 输入用户名之后,敲回车让光标跳到密码文本框,就应该编写一个用户名文本框的按键事件。
      在这里插入图片描述
    • 编写【密码】文本框按键事件处理代码(敲回车后执行登录方法)
      在这里插入图片描述
    • 编写【取消】按钮单击事件处理代码
      在这里插入图片描述
    • 编写【注册】按钮单击事件处理代码
      在这里插入图片描述
    • 此时,需要修改用户注册窗口RegisterFrame,继承JFrame,添加单参构造方法,初始化图形用户界面方法,主方法
      在这里插入图片描述
      在这里插入图片描述
    • 再查看用户登录窗口【注册】按钮单击事件处理代码,就没有错误了。
      在这里插入图片描述
    • 运行程序,查看效果
      在这里插入图片描述
    • 登录窗口完整代码
      在这里插入图片描述

    3、创建用户注册窗口RegisterFrame

    • 在创建用户登录窗口过程中,已经创建了一个可以显示与关闭的空白注册窗口
      在这里插入图片描述
    • 单参构造方法
      在这里插入图片描述
    • 初始化图形用户界面方法
      在这里插入图片描述
    • 主方法
      在这里插入图片描述
    • 声明变量
      在这里插入图片描述
    • 创建组件(面板与控件)
      在这里插入图片描述
    • 将控件添加到四个小面板
      在这里插入图片描述
    • 置大面板布局,将四个小面板添加到大面板
      在这里插入图片描述
    • 设置窗口刚好容纳组件
      在这里插入图片描述
    • 在initGUI()方法里编写【提交】按钮事件处理代码
      在这里插入图片描述
    • 编写注册方法register()
    private void register() {                                                                        
        // 获取用户名                                                                                     
        username = txtUsername.getText().trim();                                                     
        // 获取密码                                                                                      
        password = new String(txtPassword.getPassword());                                            
        // 获取电话                                                                                      
        telephone = txtTelephone.getText().trim();                                                   
        // 定义当前时间为注册时间                                                                               
        registerTime = new Timestamp(System.currentTimeMillis());                                    
                                                                                                     
        // 对用户名进行非空校验                                                                                
        if (username.equals("")) {                                                                   
            JOptionPane.showMessageDialog(null, "用户名不能为空!",                                          
                    "学生信息管理系统", JOptionPane.WARNING_MESSAGE);                                        
            txtUsername.requestFocus();                                                              
            return;                                                                                  
        }                                                                                            
                                                                                                     
        // 对密码进行非空校验                                                                                 
        if (password.equals("")) {                                                                
            JOptionPane.showMessageDialog(null, "密码不能为空!",                                           
                    "学生信息管理系统", JOptionPane.WARNING_MESSAGE);                                        
            txtPassword.requestFocus();                                                              
            return;                                                                                  
        }                                                                                            
                                                                                                     
        // 定义用户服务对象                                                                                  
        UserService userService = new UserServiceImpl();                                             
        // 创建用户                                                                                      
        User user = new User();                                                                      
        user.setUsername(username);                                                                  
        user.setPassword(password);                                                                  
        user.setTelephone(telephone);                                                                
        user.setRegisterTime(registerTime);                                                          
                                                                                                     
        // 添加用户                                                                                      
        int count = userService.addUser(user);                                                       
                                                                                                     
        // 判断是否添加成功                                                                                  
        if (count > 0) {                                                                             
            setVisible(false);                                                                       
            JOptionPane.showMessageDialog(null, "恭喜!注册成功!",                                          
                    "学生信息管理系统", JOptionPane.INFORMATION_MESSAGE);                                    
            setVisible(true);                                                                        
        } else {                                                                                     
            JOptionPane.showMessageDialog(null, "遗憾!注册失败!",                                          
                    "学生信息管理系统", JOptionPane.INFORMATION_MESSAGE);                                    
        }                                                                                            
    }                                                                                                                                                                                           
    
    • 在initGUI()方法里编写【取消】按钮单击事件处理代码
      在这里插入图片描述
      • 在initGUI()方法里编写【登录】按钮单击事件处理代码 在这里插入图片描述
    • 在initGUI()方法里编写【用户名】文本框按键事件处理代码
      在这里插入图片描述
    • 在initGUI()方法里编写【密码】文本框按键事件处理代码
      在这里插入图片描述
    • 在initGUI()方法里编写【电话】文本框按键事件处理代码
      在这里插入图片描述
    • 先启动登录窗口,单击【注册】按钮,跳转到注册窗口,注册一个新用户,然后以新用户登录系统。
      在这里插入图片描述
    • 利用注册窗口,我们注册一个名叫“无心剑”的新用户,然后利用“无心剑”登录系统,测试取得成功。
    • 注册窗口完整代码
      在这里插入图片描述

    程序改进建议

    注意注册窗口程序存在不完善之处:用户名和密码为空时也能注册成功。为了让注册窗口程序更加完善,同学们自行修改实训讲义给出的参考代码,针对上述情况给用户弹出相应的警告消息,保证用户名与密码非空时才能注册新用户(非空校验)。

    4、创建设置学校信息窗口SetCollegeInfoFrame

    • 在net.hw.student.gui包里创建SetCollegeInfoFrame类
      在这里插入图片描述
      在这里插入图片描述
    • 运行程序,查看效果
      在这里插入图片描述
      在这里插入图片描述

    5、创建修改用户密码窗口ChangePasswordFrame

    • 在net.hw.student.gui包里创建ChangePasswordFrame类
      在这里插入图片描述
      在这里插入图片描述
    • 准备修改id = 2 的记录的密码
      在这里插入图片描述
    • 运行程序,查看效果
      在这里插入图片描述
    • 在NaviCat里,打开用户表,查看第二条记录的密码是否已经修改,确实已经由原先的111111修改成123456
      在这里插入图片描述
    • 改进建议:如果新密码与旧密码一样,应提示用户新旧密码一样,修改密码失败!

    6、创建浏览学生窗口BrowseStudentsFrame

    • 在net.hw.student.gui包里创建BrowseStudentsFrame类
      在这里插入图片描述
      在这里插入图片描述
    • 运行程序,查看结果
      在这里插入图片描述
    • 思考:为什么从学生列表获取数据时get()方法的参数不是currentRow而是currentRow - 1呢?
      在这里插入图片描述

    7、创建添加学生窗口AddStudentFrame

    • 在net.hw.student.gui包里创建添加学生窗口AddStudentFrame
      在这里插入图片描述
    package net.hw.student.gui;
    
    import net.hw.student.bean.Student;
    import net.hw.student.service.StudentService;
    import net.hw.student.service.impl.StudentServiceImpl;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    
    import java.util.List;
    
    /**
     * 功能:添加学生记录
     * 作者:华卫
     * 日期:2020年07月02日
     */
    public class AddStudentFrame extends JFrame {
        private JPanel panel;
        private JPanel pnlCenter;
        private JPanel pnlRow1;
        private JPanel pnlRow2;
        private JPanel pnlRow3;
        private JPanel pnlRow4;
        private JPanel pnlRow5;
        private JPanel pnlRow6;
        private JPanel pnlRow7;
        private JPanel pnlSouth;
    
        private JLabel lblId;
        private JLabel lblName;
        private JLabel lblSex;
        private JLabel lblAge;
        private JLabel lblDepartment;
        private JLabel lblClass;
        private JLabel lblTelephone;
    
        private JTextField txtId;
        private JTextField txtName;
        private JTextField txtSex;
        private JTextField txtAge;
        private JTextField txtDepartment;
        private JTextField txtClass;
        private JTextField txtTelephone;
    
        private JButton btnExit;
        private JButton btnOK;
        private JButton btnCancel;
        
        private int currentRow; // 当前记录行号
        private List<Student> students; // 学生列表
    
        public AddStudentFrame(String title) {
            super(title);
            initGUI();
        }
    
        /**
         * 初始化用户界面
         */
        private void initGUI() {
            // 创建组件
            panel = (JPanel) getContentPane();
            pnlCenter = new JPanel();
            pnlSouth = new JPanel();
    
            pnlRow1 = new JPanel();
            pnlRow2 = new JPanel();
            pnlRow3 = new JPanel();
            pnlRow4 = new JPanel();
            pnlRow5 = new JPanel();
            pnlRow6 = new JPanel();
            pnlRow7 = new JPanel();
    
            pnlRow1.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow2.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow3.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow4.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow5.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow6.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow7.setLayout(new FlowLayout(FlowLayout.LEFT));
    
            lblId = new JLabel("学号:");
            lblName = new JLabel("姓名:");
            lblSex = new JLabel("性别:");
            lblAge = new JLabel("年龄:");
            lblDepartment = new JLabel("系部:");
            lblClass = new JLabel("班级:");
            lblTelephone = new JLabel("电话:");
    
            txtId = new JTextField(20);
            txtName = new JTextField(20);
            txtSex = new JTextField(20);
            txtAge = new JTextField(20);
            txtDepartment = new JTextField(20);
            txtClass = new JTextField(20);
            txtTelephone = new JTextField(20);
            btnOK = new JButton("确定[O]");
            btnCancel = new JButton("取消[C]");
            btnExit = new JButton("退出[X]");
            btnOK.setMnemonic(KeyEvent.VK_O);
            btnCancel.setMnemonic(KeyEvent.VK_C);
            btnExit.setMnemonic(KeyEvent.VK_X);
    
            // 添加组件
            panel.setLayout(new BorderLayout());
            panel.add(pnlCenter, BorderLayout.CENTER);
            panel.add(pnlSouth, BorderLayout.SOUTH);
            pnlCenter.setLayout(new GridLayout(7, 1));
            pnlCenter.add(pnlRow1);
            pnlCenter.add(pnlRow2);
            pnlCenter.add(pnlRow3);
            pnlCenter.add(pnlRow4);
            pnlCenter.add(pnlRow5);
            pnlCenter.add(pnlRow6);
            pnlCenter.add(pnlRow7);
    
            pnlRow1.add(lblId);
            pnlRow1.add(txtId);
            pnlRow2.add(lblName);
            pnlRow2.add(txtName);
            pnlRow3.add(lblSex);
            pnlRow3.add(txtSex);
            pnlRow4.add(lblAge);
            pnlRow4.add(txtAge);
            pnlRow5.add(lblDepartment);
            pnlRow5.add(txtDepartment);
            pnlRow6.add(lblClass);
            pnlRow6.add(txtClass);
            pnlRow7.add(lblTelephone);
            pnlRow7.add(txtTelephone);
    
            pnlSouth.add(btnOK);
            pnlSouth.add(btnCancel);
            pnlSouth.add(btnExit);
    
            // 设置窗口属性
            setSize(500, 300);
            // 设置窗口不可调整大小
            setResizable(false);
            // 设置窗口刚好容纳组件
            pack();
            // 设置窗口屏幕居中
            setLocationRelativeTo(null);
            // 设置窗口标题
            setTitle("添加学生记录");
            // 设置窗口可见
            setVisible(true);
            // 设置窗口默认关闭操作(卸载当前窗口)
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            // 【确定】按钮单击事件
            btnOK.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 学号非空校验
                    if (txtId.getText().trim().equals("")) {
                        JOptionPane.showMessageDialog(null, "学号不能为空!", "增加学生记录", JOptionPane.WARNING_MESSAGE);
                        txtId.requestFocus();
                        return;
                    }
    
                    // 年龄数字校验
                    if (!isNumber(txtAge.getText().trim())) {
                        JOptionPane.showMessageDialog(null, "注意:年龄全由数字构成!", "增加学生记录", JOptionPane.WARNING_MESSAGE);
                        txtAge.setText("");
                        txtAge.requestFocus();
                        return;
                    }
    
                    // 创建学生实体
                    Student student = new Student();
                    // 设置学生实体属性
                    student.setId(txtId.getText().trim());
                    student.setName(txtName.getText().trim());
                    student.setSex(txtSex.getText().trim());
                    student.setAge(Integer.parseInt(txtAge.getText()));
                    student.setDepartment(txtDepartment.getText().trim());
                    student.setClazz(txtClass.getText().trim());
                    student.setTelephone(txtTelephone.getText().trim());
    
                    // 创建学生服务对象
                    StudentService studentService = new StudentServiceImpl();
                    // 添加学生记录
                    int count = studentService.addStudent(student);
                    // 判断是否添加成功
                    if (count > 0) {
                        JOptionPane.showMessageDialog(null, "添加记录成功!", "增加学生记录", JOptionPane.INFORMATION_MESSAGE);
                        txtId.setText("");
                        txtName.setText("");
                        txtSex.setText("");
                        txtAge.setText("");
                        txtDepartment.setText("");
                        txtClass.setText("");
                        txtTelephone.setText("");
                        txtId.requestFocus();
                    } else {
                        JOptionPane.showMessageDialog(null, "添加记录失败!", "增加学生记录", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
    
            // 【取消】按钮单击事件处理
            btnCancel.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    txtId.setText("");
                    txtName.setText("");
                    txtSex.setText("");
                    txtAge.setText("");
                    txtDepartment.setText("");
                    txtClass.setText("");
                    txtTelephone.setText("");
                    txtId.requestFocus();
                }
            });
    
            // 【退出】按钮单击事件处理
            btnExit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    dispose();
                }
            });
    
            // 【学号】文本框按键事件处理
            txtId.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        if (!txtId.getText().trim().equals("")) {
                            txtName.requestFocus();
                        }
                    }
                }
            });
    
            // 【姓名】文本框按键事件处理
            txtName.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtSex.requestFocus();
                    }
                }
            });
    
            // 【性别】文本框按键事件处理
            txtSex.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtAge.requestFocus();
                    }
                }
            });
    
            // 【年龄】文本框按键事件处理
            txtAge.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtDepartment.requestFocus();
                    }
                }
            });
    
            // 【系部】文本框按键事件处理
            txtDepartment.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtClass.requestFocus();
                    }
                }
            });
    
            // 【班级】文本框按键事件处理
            txtClass.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtTelephone.requestFocus();
                    }
                }
            });
        }
    
        /**
         * 判断一个字符串是否全是数字
         *
         * @param str
         * @return
         */
        boolean isNumber(String str) {
            for (int i = 0; i < str.length(); i++) {
                if (str.charAt(i) < '0' || str.charAt(i) > '9') {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 主方法
         *
         * @param args
         */
        public static void main(String[] args) {
            new AddStudentFrame("");
        }
    }
    
    • 运行程序,查看效果
      在这里插入图片描述

    程序改进建议

    建议对学号、姓名与性别等字段进行非空校验。性别字段只允许输入“男”或“女”。年龄范围设置为15~25之间的整数。

    8、创建编辑学生窗口EditStudentFrame

    • 在net.hw.student.gui包里创建编辑学生窗口EditStudentFrame
      在这里插入图片描述
    package net.hw.student.gui;
    
    import net.hw.student.bean.Student;
    import net.hw.student.service.StudentService;
    import net.hw.student.service.impl.StudentServiceImpl;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import java.util.List;
    
    /**
     * 功能:编辑学生记录
     * 作者:华卫
     * 日期:2020年07月02日
     */
    public class EditStudentFrame extends JFrame {
        private JPanel panel;
        private JPanel pnlCenter;
        private JPanel pnlRow1;
        private JPanel pnlRow2;
        private JPanel pnlRow3;
        private JPanel pnlRow4;
        private JPanel pnlRow5;
        private JPanel pnlRow6;
        private JPanel pnlRow7;
        private JPanel pnlSouth;
        private JPanel pnlSouth1;
        private JPanel pnlSouth2;
        
        private JLabel lblId;
        private JLabel lblName;
        private JLabel lblSex;
        private JLabel lblAge;
        private JLabel lblDepartment;
        private JLabel lblClass;
        private JLabel lblTelephone;
       
        private JTextField txtId;
        private JTextField txtName;
        private JTextField txtSex;
        private JTextField txtAge;
        private JTextField txtDepartment;
        private JTextField txtClass;
        private JTextField txtTelephone;
       
        private JButton btnTop;
        private JButton btnPrevious;
        private JButton btnNext;
        private JButton btnBottom;
        private JButton btnExit;
        private JButton btnEdit;
        private JButton btnOK;
        private JButton btnCancel;
       
        private int currentRow; // 当前记录行号
        private List<Student> students; // 学生列表
        StudentService studentService; // 创建学生服务对象
       
        public EditStudentFrame(String title) {
            super(title);
            initGUI();
        }
    
        /**
         * 初始化用户界面
         */
        private void initGUI() {
            // 创建组件
            panel = (JPanel) getContentPane();
            pnlCenter = new JPanel();
            pnlSouth = new JPanel();
            pnlSouth.setLayout(new GridLayout(2, 1));
    
            pnlRow1 = new JPanel();
            pnlRow2 = new JPanel();
            pnlRow3 = new JPanel();
            pnlRow4 = new JPanel();
            pnlRow5 = new JPanel();
            pnlRow6 = new JPanel();
            pnlRow7 = new JPanel();
            pnlSouth1 = new JPanel();
            pnlSouth2 = new JPanel();
    
            pnlRow1.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow2.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow3.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow4.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow5.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow6.setLayout(new FlowLayout(FlowLayout.LEFT));
            pnlRow7.setLayout(new FlowLayout(FlowLayout.LEFT));
    
            lblId = new JLabel("学号:");
            lblName = new JLabel("姓名:");
            lblSex = new JLabel("性别:");
            lblAge = new JLabel("年龄:");
            lblDepartment = new JLabel("系部:");
            lblClass = new JLabel("班级:");
            lblTelephone = new JLabel("电话:");
    
            txtId = new JTextField(40);
            txtName = new JTextField(40);
            txtSex = new JTextField(40);
            txtAge = new JTextField(40);
            txtDepartment = new JTextField(40);
            txtClass = new JTextField(40);
            txtTelephone = new JTextField(40);
            txtId.setEditable(false);
            txtName.setEditable(false);
            txtSex.setEditable(false);
            txtAge.setEditable(false);
            txtDepartment.setEditable(false);
            txtClass.setEditable(false);
            txtTelephone.setEditable(false);
    
            btnTop = new JButton("第一条[T]");
            btnPrevious = new JButton("上一条[P]");
            btnNext = new JButton("下一条[N]");
            btnBottom = new JButton("最后一条[B]");
            btnExit = new JButton("退出[X]");
            btnEdit = new JButton("编辑[E]");
            btnOK = new JButton("确定[O]");
            btnCancel = new JButton("取消[C]");
            btnOK.setEnabled(false);
            btnCancel.setEnabled(false);
            btnTop.setMnemonic(KeyEvent.VK_T);
            btnPrevious.setMnemonic(KeyEvent.VK_P);
            btnNext.setMnemonic(KeyEvent.VK_N);
            btnBottom.setMnemonic(KeyEvent.VK_B);
            btnExit.setMnemonic(KeyEvent.VK_X);
            btnEdit.setMnemonic(KeyEvent.VK_E);
            btnOK.setMnemonic(KeyEvent.VK_O);
            btnCancel.setMnemonic(KeyEvent.VK_C);
    
            // 添加组件
            panel.setLayout(new BorderLayout());
            panel.add(pnlCenter, BorderLayout.CENTER);
            panel.add(pnlSouth, BorderLayout.SOUTH);
            pnlCenter.setLayout(new GridLayout(7, 1));
    
            pnlCenter.add(pnlRow1);
            pnlCenter.add(pnlRow2);
            pnlCenter.add(pnlRow3);
            pnlCenter.add(pnlRow4);
            pnlCenter.add(pnlRow5);
            pnlCenter.add(pnlRow6);
            pnlCenter.add(pnlRow7);
    
            pnlRow1.add(lblId);
            pnlRow1.add(txtId);
            pnlRow2.add(lblName);
            pnlRow2.add(txtName);
            pnlRow3.add(lblSex);
            pnlRow3.add(txtSex);
            pnlRow4.add(lblAge);
            pnlRow4.add(txtAge);
            pnlRow5.add(lblDepartment);
            pnlRow5.add(txtDepartment);
            pnlRow6.add(lblClass);
            pnlRow6.add(txtClass);
            pnlRow7.add(lblTelephone);
            pnlRow7.add(txtTelephone);
    
            pnlSouth.add(pnlSouth1);
            pnlSouth.add(pnlSouth2);
            pnlSouth1.add(btnTop);
            pnlSouth1.add(btnPrevious);
            pnlSouth1.add(btnNext);
            pnlSouth1.add(btnBottom);
            pnlSouth1.add(btnExit);
            pnlSouth2.add(btnEdit);
            pnlSouth2.add(btnOK);
            pnlSouth2.add(btnCancel);
    
            // 设置窗口属性
            setSize(500, 300);
            // 设置窗口不可调整大小
            setResizable(false);
            // 设置窗口刚好容纳组件
            pack();
            // 设置窗口屏幕居中
            setLocationRelativeTo(null);
            // 设置窗口可见
            setVisible(true);
            // 设置窗口默认关闭操作(卸载当前窗口)
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            // 创建学生服务对象
            studentService = new StudentServiceImpl();
            // 获取全部学生列表
            students = studentService.findAllStudents();
            // 判断是否有学生记录
            if (students.size() > 0) {
                // 设置当前记录号
                currentRow = 1;
                // 设置窗口标题
                setTitle("浏览学生表记录" + " && 当前记录:" + currentRow);
                // 填充窗口各文本框数据
                fillFrameData(currentRow);
            } else {
                JOptionPane.showMessageDialog(null, "表中没有记录!", "浏览学生表记录", JOptionPane.ERROR_MESSAGE);
                btnTop.setEnabled(false);
                btnPrevious.setEnabled(false);
                btnNext.setEnabled(false);
                btnBottom.setEnabled(false);
            }
    
            // 【第一条】按钮单击事件
            btnTop.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 设置当前记录号
                    currentRow = 1;
                    // 填充当前记录数据
                    fillFrameData(currentRow);
                }
            });
    
            // 【上一条】按钮单击事件
            btnPrevious.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (currentRow > 1) {
                        // 设置当前记录号
                        currentRow--;
                        // 填充当前记录数据
                        fillFrameData(currentRow);
                    } else {
                        JOptionPane.showMessageDialog(null, "已到第一条记录!", "浏览学生表记录", JOptionPane.WARNING_MESSAGE);
                    }
                }
            });
    
            // 【下一条】按钮单击事件
            btnNext.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (currentRow < students.size() - 1) {
                        // 设置当前记录号
                        currentRow++;
                        // 填充当前记录数据
                        fillFrameData(currentRow);
                    } else {
                        JOptionPane.showMessageDialog(null, "已到最后一条记录!", "浏览学生表记录", JOptionPane.WARNING_MESSAGE);
                    }
                }
            });
    
            // 【最后一条】按钮单击事件
            btnBottom.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 设置当前记录号
                    currentRow = students.size() - 1;
                    // 填充当前记录数据
                    fillFrameData(currentRow);
                }
            });
    
            // 【退出】按钮单击事件
            btnExit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    dispose();
                }
            });
    
            // 【编辑】按钮单击事件
            btnEdit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 设置窗口标题
                    setTitle("编辑学生表记录" + " && 当前记录:" + currentRow);
    
                    txtName.setEditable(true);
                    txtSex.setEditable(true);
                    txtAge.setEditable(true);
                    txtDepartment.setEditable(true);
                    txtClass.setEditable(true);
                    txtTelephone.setEditable(true);
                    btnOK.setEnabled(true);
                    btnCancel.setEnabled(true);
                }
            });
    
            // 【确定】按钮单击事件
            btnOK.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // 获取当前学生实体
                    Student student = students.get(currentRow);
    
                    if (isNumber(txtAge.getText())) {
                        if (isLegalTelephone(txtTelephone.getText())) {
                            // 修改学生实体属性
                            student.setName(txtName.getText());
                            student.setSex(txtSex.getText());
                            student.setAge(Integer.parseInt(txtAge.getText()));
                            student.setDepartment(txtDepartment.getText());
                            student.setClazz(txtClass.getText());
                            student.setTelephone(txtTelephone.getText());
                            // 更新学生信息
                            int count = studentService.updateStudent(student);
                            // 判断是否更新成功
                            if (count > 0) {
                                JOptionPane.showMessageDialog(null, "更新记录成功!", "编辑学生记录", JOptionPane.INFORMATION_MESSAGE);
                                btnOK.setEnabled(false);
                                btnCancel.setEnabled(false);
                                btnEdit.setEnabled(true);
                                txtName.setEditable(false);
                                txtSex.setEditable(false);
                                txtAge.setEditable(false);
                                txtDepartment.setEditable(false);
                                txtClass.setEditable(false);
                                txtTelephone.setEditable(false);
                                // 重新获取全部学生列表
                                students = studentService.findAllStudents();
                                // 设置窗口标题
                                setTitle("浏览学生表记录" + " && 当前记录:" + currentRow);
                            } else {
                                JOptionPane.showMessageDialog(null, "更新记录失败!", "编辑学生记录", JOptionPane.ERROR_MESSAGE);
                            }
                        } else {
                            JOptionPane.showMessageDialog(null, "非法手机号!", "编辑学生记录", JOptionPane.ERROR_MESSAGE);
                            txtTelephone.selectAll();
                            txtTelephone.requestFocus();
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "年龄必须是数字!", "编辑学生记录", JOptionPane.ERROR_MESSAGE);
                        txtAge.selectAll();
                        txtAge.requestFocus();
                    }
                }
            });
    
            // 【取消】按钮单击事件
            btnCancel.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    btnOK.setEnabled(false);
                    btnCancel.setEnabled(false);
                    btnEdit.setEnabled(true);
                    txtName.setEditable(false);
                    txtSex.setEditable(false);
                    txtAge.setEditable(false);
                    txtDepartment.setEditable(false);
                    txtClass.setEditable(false);
                    txtTelephone.setEditable(false);
                    // 恢复文本框修改前的值
                    txtName.setText(students.get(currentRow).getName());
                    txtSex.setText(students.get(currentRow).getSex());
                    txtAge.setText(students.get(currentRow).getAge() + "");
                    txtDepartment.setText(students.get(currentRow).getDepartment());
                    txtClass.setText(students.get(currentRow).getClazz());
                    txtTelephone.setText(students.get(currentRow).getTelephone());
                }
            });
    
            // 【学号】文本框按键事件
            txtId.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtName.requestFocus();
                    }
                }
            });
    
            // 【姓名】文本框按键事件
            txtName.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtSex.requestFocus();
                    }
                }
            });
    
            // 【性别】文本框按键事件
            txtSex.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtAge.requestFocus();
                    }
                }
            });
    
            // 【年龄】文本框按键事件
            txtAge.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtDepartment.requestFocus();
                    }
                }
            });
    
            // 【系部】文本框按键事件
            txtDepartment.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtClass.requestFocus();
                    }
                }
            });
    
            // 【班级】文本框按键事件
            txtClass.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        txtTelephone.requestFocus();
                    }
                }
            });
        }
    
        /**
         * 将当前记录数据填充窗口各文本框
         *
         * @param currentRow
         */
        private void fillFrameData(int currentRow) {
            if (currentRow > 0) {
                setTitle("浏览学生表记录" + " && 当前记录:" + currentRow);
                txtId.setText(students.get(currentRow).getId());
                txtName.setText(students.get(currentRow).getName());
                txtSex.setText(students.get(currentRow).getSex());
                txtAge.setText(students.get(currentRow).getAge() + "");
                txtDepartment.setText(students.get(currentRow).getDepartment());
                txtClass.setText(students.get(currentRow).getClazz());
                txtTelephone.setText(students.get(currentRow).getTelephone());
            }
        }
    
        // 判断一个字符串是否全是数字
        private boolean isNumber(String str) {
            for (int i = 0; i < str.length(); i++) {
                if (str.charAt(i) < '0' || str.charAt(i) > '9') {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 判断是否合法手机号
         *
         * @param telephone
         * @return
         */
        private boolean isLegalTelephone(String telephone) {
            Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
            Matcher m = p.matcher(telephone);
            return m.matches();
        }
    
        /**
         * 主方法
         *
         * @param args
         */
        public static void main(String[] args) {
            new EditStudentFrame("");
        }
    }
    
    • 运行程序,查看效果
      在这里插入图片描述

    9、创建按学号删除学生窗口DeleteStudentByIdFrame

    • 在net.hw.student.gui包里创建按学号删除学生窗口DeleteStudentByIdFrame
      在这里插入图片描述
    package net.hw.student.gui;
    
    import net.hw.student.bean.Student;
    import net.hw.student.service.StudentService;
    import net.hw.student.service.impl.StudentServiceImpl;
    
    import javax.swing.*;
    import javax.swing.border.TitledBorder;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.Vector;
    
    import java.util.List;
    
    /**
     * 功能:按学号删除学生记录
     * 作者:华卫
     * 日期:2020年07月02日
     */
    public class DeleteStudentByIdFrame extends JFrame {
        private JLabel lblInputId; // 学号标签
        private JTextField txtId; // 学号文本框
    
        private JPanel panel;
        private JPanel pnlSouth;
        private JPanel pnlCenter;
        private JPanel pnlNorth;
    
        private JButton btnQuery;
        private JButton btnBrowseAll;
        private JButton btnDelete;
        private JButton btnExit;
    
        private JScrollPane scroller; // 滚动面板
    
        private Vector rows; // 记录行集
        private Vector<String> colHead; // 表格列标题
        private JTable table; // 表格
        private int currentRow; // 当前记录行号
        private List<Student> students; // 学生列表
        private StudentService studentService; // 学生服务对象
    
        public DeleteStudentByIdFrame(String title) {
            super(title);
            intiGUI();
        }
    
        private void intiGUI() {
            // 创建组件
            panel = (JPanel) getContentPane();
            pnlNorth = new JPanel();
            pnlCenter = new JPanel();
            pnlSouth = new JPanel();
    
            rows = new Vector();
            colHead = new Vector();
    
            lblInputId = new JLabel("输入学号:");
            txtId = new JTextField(10);
            txtId.setHorizontalAlignment(JTextField.CENTER);
            btnQuery = new JButton("查询[Q]");
            btnQuery.setMnemonic(KeyEvent.VK_Q);
            btnBrowseAll = new JButton("显示全部记录[A]");
            btnBrowseAll.setMnemonic(KeyEvent.VK_A);
            btnDelete = new JButton("删除查询的记录[D]");
            btnDelete.setEnabled(false);// 删除按钮不可用
            btnDelete.setMnemonic(KeyEvent.VK_D);
            btnExit = new JButton("退出[X]");
            btnExit.setMnemonic(KeyEvent.VK_X);
    
            // 添加组件
            panel.add(pnlSouth, BorderLayout.SOUTH);
            panel.add(pnlCenter, BorderLayout.CENTER);
            panel.add(pnlNorth, BorderLayout.NORTH);
    
            pnlNorth.add(lblInputId);
            pnlNorth.add(txtId);
            pnlNorth.add(btnQuery);
            pnlNorth.add(btnBrowseAll);
            pnlSouth.setLayout(new FlowLayout(FlowLayout.RIGHT));
            pnlSouth.add(btnDelete);
            pnlSouth.add(btnExit);
            pnlCenter.setLayout(new BorderLayout());
    
            // 创建标题边框对象
            TitledBorder tb = new TitledBorder("查询结果");
            pnlCenter.setBorder(tb);
    
            // 创建学生服务对象
            studentService = new StudentServiceImpl();
            // 获取全部学生列表
            students = studentService.findAllStudents();
            // 填充表格数据
            fillTableData();
    
            // 设置窗口大小
            setSize(600, 350);
            // 设置窗口不可调整大小
            setResizable(false);
            // 设置窗口屏幕居中
            setLocationRelativeTo(null);
            // 设置窗口标题
            setTitle("按学号删除学生记录");
            // 设置窗口可见
            setVisible(true);
            // 设置窗口默认关闭操作(卸载当前窗口)
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            // 【退出】按钮单击事件
            btnExit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    dispose();
                }
            });
    
            // 【删除】按钮单击事件
            btnDelete.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!rows.isEmpty()) {
                        long choice = JOptionPane.showConfirmDialog(null, "是否要删除记录?");
                        if (choice == JOptionPane.OK_OPTION) {
                            // 获取待删学生学号
                            String id = txtId.getText().trim();
                            // 按学号删除学生
                            int count = studentService.deleteStudentById(id);
                            if (count > 0) {
                                JOptionPane.showMessageDialog(null, "记录删除成功!", "提示", JOptionPane.INFORMATION_MESSAGE);
                                // 重新获取全部学生列表
                                students = studentService.findAllStudents();
                                // 清空待删学生学号文本框
                                txtId.setText("");
                                // 填充数据
                                fillTableData();
                                // 删除按钮不可用
                                btnDelete.setEnabled(false);
                            } else {
                                JOptionPane.showMessageDialog(null, "记录删除失败!", "警告", JOptionPane.WARNING_MESSAGE);
                            }
                        }
                    }
                }
            });
    
            // 【查询】按钮单击事件
            btnQuery.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    doQuery();
                }
            });
    
            // 【显示全部记录】按钮单击事件
            btnBrowseAll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    // 获取全部学生记录
                    students = studentService.findAllStudents();
                    // 填充表格数据
                    fillTableData();
                    // 删除按钮不可用
                    btnDelete.setEnabled(false);
                }
            });
    
            // 【学号】文本框按键事件
            txtId.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        doQuery();
                    }
                }
            });
    
            // 表格单击事件
            table.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    // 获取当前行的行数
                    int row = table.rowAtPoint(e.getPoint());
                    // 选中鼠标单击的行
                    table.setRowSelectionInterval(row, row);
                    // 设置文本框内容
                    txtId.setText(table.getValueAt(row, 0).toString());
                }
            });
        }
    
        /**
         * 查询方法
         */
        private void doQuery() {
            // 获取查询学号
            String id = txtId.getText().trim();
            if (!id.equals("")) {
                students.clear();
                Student student = studentService.findStudentById(id);
                if (student != null) {
                    // 将查询到的学生添加到列表
                    students.add(student);
                    // 让删除按钮可用
                    btnDelete.setEnabled(true);
                }
                // 填充表格
                fillTableData();
            } else {
                JOptionPane.showMessageDialog(this, "请输入待查学生学号!", "警告", JOptionPane.WARNING_MESSAGE);
                txtId.requestFocus();
            }
        }
    
        /**
         * 填充表格方法
         */
        private void fillTableData() {
            // 填充表头
            colHead.clear();
            colHead.add("学号");
            colHead.add("姓名");
            colHead.add("性别");
            colHead.add("年龄");
            colHead.add("系部");
            colHead.add("班级");
            colHead.add("电话");
    
            // 填充表记录
            rows.clear();
            for (Student student : students) {
                Vector<String> currentRow = new Vector<String>();
                currentRow.addElement(student.getId());
                currentRow.addElement(student.getName());
                currentRow.addElement(student.getSex());
                currentRow.addElement(student.getAge() + "");
                currentRow.addElement(student.getDepartment());
                currentRow.addElement(student.getClazz());
                currentRow.addElement(student.getTelephone());
                // 将当前行添加到记录行集
                rows.add(currentRow);
            }
    
            // 创建表格(参数1:记录集;参数2:表头)
            table = new JTable(rows, colHead);
    
            // 定义滚动面板
            scroller = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            // 将滚动面板添加到中心面板
            pnlCenter.add(scroller, BorderLayout.CENTER);
    
            // 重绘窗体
            repaint();
    
            // 判断是否有记录行
            if (rows.isEmpty()) {
                JOptionPane.showMessageDialog(this, "没有符合条件的记录!", "错误提示", JOptionPane.WARNING_MESSAGE);
                txtId.setText("");
            } else {
                // 让滚动条移到最上方
                scroller.getVerticalScrollBar().setValue(0);
            }
        }
    
        /**
         * 主方法
         *
         * @param args
         */
        public static void main(String[] args) {
            new DeleteStudentByIdFrame("");
        }
    }
    
    • 运行程序,查看效果
      在这里插入图片描述
    • 说明:单击某一行记录,其学号会显示在【输入学号】文本框里。

    10、创建按班级删除学生窗口DeleteStudentsByClassFrame

    • 在net.hw.student.gui包里创建按班级删除学生窗口DeleteStudentsByClassFrame
      在这里插入图片描述
    • 同学们可以参考按学号删除删除学生记录的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    11、创建按系部删除学生窗口DeleteStudentsByDepartmentFrame

    • 在net.hw.student.gui包里创建按系部删除学生窗口DeleteStudentsByDepartmentFrame
      在这里插入图片描述
    • 同学们可以参考按学号删除删除学生记录的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    12、创建按学号查询学生窗口FindStudentByIdFrame

    • 在net.hw.student.gui包里创建按学号查询学生窗口FindStudentByIdFrame
      在这里插入图片描述
    package net.hw.student.gui;
    
    import net.hw.student.bean.Student;
    import net.hw.student.service.StudentService;
    import net.hw.student.service.impl.StudentServiceImpl;
    
    import javax.swing.*;
    import javax.swing.border.TitledBorder;
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.print.PrinterException;
    import java.util.Vector;
    import java.util.List;
    
    /**
     * 功能:按学号查询学生记录
     * 作者:华卫
     * 日期:2020年07月05日
     */
    public class FindStudentByIdFrame extends JFrame {
        private JLabel lblInputId; // 学号标签
        private JTextField txtId; // 学号文本框
    
        private JPanel panel;
        private JPanel pnlSouth;
        private JPanel pnlCenter;
        private JPanel pnlNorth;
    
        private JButton btnQuery;
        private JButton btnBrowseAll;
        private JButton btnPrint;
        private JButton btnExit;
    
        private JScrollPane scroller;  // 滚动面板
    
        private Vector rows; // 记录行集
        private Vector<String> colHead; // 表格列标题
        private JTable table; // 表格    
        private List<Student> students; // 学生列表
        private StudentService studentService; // 学生服务对象
    
        public FindStudentByIdFrame(String title) {
            super(title);
            intiGUI();
        }
    
        /**
         * 初始化用户界面
         */
        private void intiGUI() {
            // 创建组件
            panel = (JPanel) getContentPane();
            pnlNorth = new JPanel();
            pnlCenter = new JPanel();
            pnlSouth = new JPanel();
    
            rows = new Vector();
            colHead = new Vector();
    
            lblInputId = new JLabel("输入学号:");
            txtId = new JTextField(10);
            txtId.setHorizontalAlignment(JTextField.CENTER);
            btnQuery = new JButton("查询[Q]");
            btnQuery.setMnemonic(KeyEvent.VK_Q);
            btnBrowseAll = new JButton("显示全部记录[A]");
            btnBrowseAll.setMnemonic(KeyEvent.VK_A);
            btnPrint = new JButton("打印[P]");
            btnPrint.setMnemonic(KeyEvent.VK_D);
            btnExit = new JButton("退出[X]");
            btnExit.setMnemonic(KeyEvent.VK_X);
    
            // 添加组件
            panel.add(pnlSouth, BorderLayout.SOUTH);
            panel.add(pnlCenter, BorderLayout.CENTER);
            panel.add(pnlNorth, BorderLayout.NORTH);
    
            pnlNorth.add(lblInputId);
            pnlNorth.add(txtId);
            pnlNorth.add(btnQuery);
            pnlNorth.add(btnBrowseAll);
            pnlSouth.setLayout(new FlowLayout(FlowLayout.RIGHT));
            pnlSouth.add(btnPrint);
            pnlSouth.add(btnExit);
            pnlCenter.setLayout(new BorderLayout());
    
            // 创建标题边框对象
            TitledBorder tb = new TitledBorder("查询结果");
            pnlCenter.setBorder(tb);
    
            // 创建学生服务对象
            studentService = new StudentServiceImpl();
            // 获取全部学生列表
            students = studentService.findAllStudents();
            // 填充表格数据
            fillTableData();
    
            // 设置窗口大小
            setSize(600, 350);
            // 设置窗口不可调整大小
            setResizable(false);
            // 设置窗口屏幕居中
            setLocationRelativeTo(null);
            // 设置窗口标题
            setTitle("按学号查询学生记录");
            // 设置窗口可见
            setVisible(true);
            // 设置窗口默认关闭操作(卸载当前窗口)
            setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
            // 【退出】按钮单击事件
            btnExit.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    dispose();
                }
            });
    
            // 【打印】按钮单击事件
            btnPrint.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        table.print();
                    } catch (PrinterException e1) {
                        e1.printStackTrace();
                    }
                }
            });
    
            // 【查询】按钮单击事件
            btnQuery.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    doQuery();
                }
            });
    
            // 【显示全部记录】按钮单击事件
            btnBrowseAll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    // 获取全部学生记录
                    students = studentService.findAllStudents();
                    // 填充表格数据
                    fillTableData();
                    // 删除按钮不可用
                    btnPrint.setEnabled(false);
                }
            });
    
            // 【学号】文本框按键事件
            txtId.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        doQuery();
                    }
                }
            });
    
            // 表格单击事件
            table.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    // 获取当前行的行数
                    int row = table.rowAtPoint(e.getPoint());
                    // 选中鼠标单击的行
                    table.setRowSelectionInterval(row, row);
                    // 设置文本框内容
                    txtId.setText(table.getValueAt(row, 0).toString());
                }
            });
        }
    
        /**
         * 查询方法
         */
        private void doQuery() {
            // 获取查询学号
            String id = txtId.getText().trim();
            if (!id.equals("")) {
                students.clear();
                Student student = studentService.findStudentById(id);
                if (student != null) {
                    // 将查询到的学生添加到列表
                    students.add(student);
                }
                // 填充表格
                fillTableData();
            } else {
                JOptionPane.showMessageDialog(this, "请输入待查学生学号!", "警告", JOptionPane.WARNING_MESSAGE);
                txtId.requestFocus();
            }
        }
    
        /**
         * 填充表格方法
         */
        private void fillTableData() {
            // 填充表头
            colHead.clear();
            colHead.add("学号");
            colHead.add("姓名");
            colHead.add("性别");
            colHead.add("年龄");
            colHead.add("系部");
            colHead.add("班级");
            colHead.add("电话");
    
            // 填充表记录
            rows.clear();
            for (Student student : students) {
                Vector<String> currentRow = new Vector<String>();
                currentRow.addElement(student.getId());
                currentRow.addElement(student.getName());
                currentRow.addElement(student.getSex());
                currentRow.addElement(student.getAge() + "");
                currentRow.addElement(student.getDepartment());
                currentRow.addElement(student.getClazz());
                currentRow.addElement(student.getTelephone());
                // 将当前行添加到记录行集
                rows.add(currentRow);
            }
    
            // 创建表格(参数1:记录集;参数2:表头)
            table = new JTable(rows, colHead);
    
            // 定义滚动面板
            scroller = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                    JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            // 将滚动面板添加到中心面板
            pnlCenter.add(scroller, BorderLayout.CENTER);
    
            // 重绘窗体
            repaint();
    
            // 判断是否有记录行
            if (rows.isEmpty()) {
                JOptionPane.showMessageDialog(this, "没有符合条件的记录!", "错误提示", JOptionPane.WARNING_MESSAGE);
                txtId.setText("");
            } else {
                // 让滚动条移到最上方
                scroller.getVerticalScrollBar().setValue(0);
            }
        }
    
        public static void main(String[] args) {
            new FindStudentByIdFrame("");
        }
    }
    
    • 运行程序,查看效果
      在这里插入图片描述

    13、创建按姓名查询学生窗口FindStudentsByNameFrame

    • 在net.hw.student.gui包里创建按姓名查询学生窗口FindStudentsByNameFrame
      在这里插入图片描述
    • 同学们可以参考按学号查询学生记录的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    14、创建按班级查询学生窗口FindStudentsByClassFrame

    • 在net.hw.student.gui包里创建按班级查询学生窗口FindStudentsByClassFrame
      在这里插入图片描述
    • 同学们可以参考按学号查询学生记录的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    15、创建按系部查询学生窗口FindStudentsByDepartmentFrame

    • 在net.hw.student.gui包里创建按系部查询学生窗口FindStudentsByDepartmentFrame
      在这里插入图片描述
    • 同学们可以参考按学号查询学生记录的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    16、创建按性别统计人数窗口CountStudentsBySexFrame

    • 在net.hw.student.gui包里创建性别统计人数窗口CountStudentsBySexFrame
      在这里插入图片描述
      在这里插入图片描述
    • 运行程序,查看效果
      在这里插入图片描述

    17、创建按班级统计人数窗口CountStudentsByClassFrame

    • 在net.hw.student.gui包里创建按班级统计人数窗口CountStudentsByClassFrame
      在这里插入图片描述
    • 同学们可以参考按性别统计人数的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    18、创建按系部统计人数窗口CountStudentsByDepartmentFrame

    • 在net.hw.student.gui包里创建按系部统计人数窗口CountStudentsByDepartmentFrame
      在这里插入图片描述
    • 同学们可以参考按性别统计人数的代码来编写本界面窗口的代码
    • 运行程序,查看效果
      在这里插入图片描述

    19、创建设置状态栏信息窗口SetStatusBarFrame

    • 在net.hw.student.gui包里创建设置状态栏信息窗口SetStatusBarFrame
      在这里插入图片描述
      在这里插入图片描述
    • 程序有一处会报错
      在这里插入图片描述
    • 等到MainFrame类里写好setStatusBar()方法之后,消除错误之后,才能测试该程序。

    20、修改主界面窗口MainFrame

    • 添加菜单系统及其事件处理

    • 添加主界面背景标签的图片

    • 设置主界面的状态栏信息
      在这里插入图片描述

    • 启动NaviCat,运行student.sql脚本,恢复数据

    • 启动用户登录窗口,测试整个应用程序
      在这里插入图片描述

    (十一)项目功能拓展说明

    本实训项目只是针对学生信息进行基本的管理操作,数据访问层DAO都是针对单表进行操作。有兴趣的同学可以添加成绩管理功能,那样就要添加课程表与选课表,涉及到学生表、选课表与课程表的三表关联查询操作。

    八、项目下载

    下载链接:学生信息管理系统(MySQL版)V1.0源码.rar

    展开全文
  • Idea (2017.2版) 创建分布式 Maven 项目步骤 &amp; SSM(SpringMVC + Spring + MyBatis) 基本配置;分布式项目主要用于比较大型的、多人合作的项目,小项目可能就没必要这样了。前言:CSDN上看到一篇高阅读量的...

    Idea (2017.2版) 创建分布式 Maven 项目步骤 & SSM(SpringMVC + Spring + MyBatis) 基本配置;分布式项目主要用于比较大型的、多人合作的项目,小项目可能就没必要这样了。

    前言:CSDN上看到一篇高阅读量的介绍Idea 分布式项目创建步骤的博客,比较复杂,但自己实际操作发现并没必要那么复杂,可能是因为Idea 的较新版本做了改进。

    参考博客:https://blog.csdn.net/liudongdong0909/article/details/52270604

    1)Maven 直接用的Idea 内置版本;创建空白工程ssm_distrituted。

    (更新:有个更好的方式:直接把主工程作为父工程,其它两个子工程直接继承父工程即可。)


    2)File - New - Module,用Maven - archetype-quickstart 创建父工程模块ssm_parent,用于管理公用Jar 包及其版本,只需要pom.xml 添加依赖即可;name 标签前加:<packaging>pom</packaging>;更新pom 后,需要在模块名上右键 -  Maven - Reimport,然后才会生效。


    3)File - New - Module,用Maven - archetype-webapp 创建子工程模块ssm_web,注意要选父工程


    4)File - New - Module,用Maven - archetype-webapp 创建子工程模块ssm_service,这个子工程负责服务层和数据层(当然数据层也可以再分离出来),是作为Jar 包给子工程ssm_web 用的,过程同第3步,只是还需要将packaging 改成jar,然后只需要把ssm_service 的依赖坐标添加到ssm_web 的pom.xml 即可。配置正确的话,按住Ctrl,鼠标点击依赖内容(如"com.qf") 是会跳转到ssm_service 的pom 文件的。

            <dependency>
                <groupId>com.qf</groupId>
                <artifactId>ssm_service</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>

    • 可用如下方法在ssm_web 模块 手动添加模块依赖:


    • 可在Maven 窗口手动创建(install) 模块的jar 包


    • 还有种笨办法:手动改ssm_service 的target 目录到ssm_web 的target 目录,可以运行。

    5)配置Tomcat,配好后即可启动,访问静态资源。

    6)以下是SSM 主要配置,按框架分;SpringMVC 在ssm_web: 

    • 在web.xml 配置 编码过滤器核心 DispatcherServlet 并指定配置文件位置
    	<filter>
    		<filter-name>encodingfilter</filter-name>
    		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    		<init-param>
    			<param-name>encoding</param-name>
    			<param-value>utf-8</param-value>
    		</init-param>
    	</filter>
    	<filter-mapping>
    		<filter-name>encodingfilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>
    	
    	<!-- 配置springmvc的核心servlet -->
    	<servlet>
    		<servlet-name>springmvc</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath:spring/spring-mvc.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>springmvc</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    • 在spring-mvc.xml 配置包扫描(子容器管理Controller Bean) & 注解驱动(开启后会注册常用的bean),静态资源忽略(也可配置<mvc:resources>),视图解析器(前缀/后缀)
    	<!-- 扫描controller -->
    	<context:component-scan base-package="com.qf.ssm.controller"/>
    
    	<!-- 注解驱动 -->
    	<mvc:annotation-driven/>
    	
    	<!-- 静态servlet 处理静态资源文件 -->
    	<mvc:default-servlet-handler/>
    	
    	<!-- 配置视图解析器 -->
    	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<!-- 配置前缀 -->
    		<property name="prefix" value="/"/>
    		<!-- 配置后缀 -->
    		<property name="suffix" value=".jsp"/>
    	</bean>

    7)Spring 

    • 在web.xml 配置容器初始化监听器classpath 后加* 表示除了扫描本工程的的classes 目录,还会扫关联Jar 工程的classes 目录。
    	<!-- 告诉spring容器,spring的配置文件的位置 -->
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>classpath*:spring/applicationContext-*.xml</param-value>
    	</context-param>
    	
    	<!-- 初始化spring容器 -->
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    • 在service 层配置applicationContext.xml:包扫描(父容器管理除Controller 以外的Bean)、数据源sqlSessionFactory (用于整合MyBatis) & dao层自动创建代理(即可不用dao 实现类)
    	<context:component-scan base-package="com.qf.ssm.service"/> 
    	
    	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    		<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    		<property name="username" value="root"/>
    		<property name="password" value="root"/>
    		<property name="url" value="jdbc:mysql:///mydb"/>
    	</bean>
    	
        <!-- 扫描所有的dao层的接口,不需要指定 sqlSessionFactory -->
        <mybaits:scan base-package="com.qf.ssm.dao"/>
    
        <!--也可用比较长的写法 -->
        <!--<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com.qf.dao"/>
            <property name="sqlSessionFactoryBeanName" value="SqlSessionFactory"></property>
        </bean>-->
        
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        	<!-- 数据源 -->
        	<property name="dataSource" ref="dataSource"/>
        	<!-- 映射文件的扫描 -->
        	<property name="mapperLocations" value="classpath*:com/qf/ssm/dao/mapper/*Mapper.xml"/>
        	<!-- 配置mybatis核心配置文件 -->
            <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
        </bean> 
        ***** 上面映射文件扫描的classpath 不加*的话,会报错:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.qf.ssm.dao.IUserDao.queryByUserName,因为找不到Mapper.xml 文件加* 表示也会扫描jar 包内的classspath。

    8)MyBatis,在servcie (dao) 层

    • mybatis-config.xml 配置插件别名,这两项也可放在applicationContext.xml 中配置。
    	<!-- 扫描别名 -->
    	<typeAliases>
    		<package name="com.qf.ssm.entity"/>
    	</typeAliases>
        <!-- 分页插件 -->
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageHelper">
                <property name="dialect" value="mysql"/>
                <!--reasonable 默认false,设为true 时,当pageNum(当前页) 小于1时,会自动为其赋值为1。-->
                <property name="reasonable" value="true"/>
            </plugin>
        </plugins>
    • 映射文件(也可把SQL 用注解写在IDao 方法上):resultMapSQL
    <mapper namespace="com.qf.ssm.dao.IUserDao">
    	<select id="queryByUserName" resultType="user">
    		select * from user where username = #{username}
    	</select>
    </mapper>

    9)按文件分:

    1) log4j
    2) jdbc.properties
    3) springmvc.xml
    a) 视图解析器
    b) 静态资源忽略
    c) 包扫描自定义bean(controller),注解驱动
    4) applicationContext.xml

    a) 包扫描自定义bean(service,dao)
    b) 数据源
    c) 事务管理器
    d) 事务策略
    e) AOP的配置
    f) Spring和MyBatis整合(sqlSessionFactoryBean)

    5) mybatis-config.xml / mapper.xml
    a) 插件; 别名
    6) web.xml
    a) Springmvc 编码过滤器
    b) Spring 监听器 -初始化Spring 容器 ContextLoaderListener,需要context-param

    c) SpringMVC核心组件 DispatcherServlet,需要init-param(同context-param 配的两项一样

    展开全文
  • 一段经过精简的代码: <!-- var map = new GMap2(document.getElementById("mapContainer")); map.setCenter(new GLatLng...// --> 新建一空白的文本文件,把上面这段代码copy过去,不要改变代码的任何顺序,然后

    一段经过精简的代码:

     

     

    新建一个空白的文本文件,把上面这段代码copy过去,不要改变代码的任何顺序,然后把这个文本文件保存为html文件,使用浏览器打开(不要使用MS的IE),看看你能看到什么!

    对这段代码的详细解释

    上面的这段代码就是创建一个地图的核心步骤:

    1、导入地图API类库。

          <script src="http://ditu.google.com/maps?file=api&hl=zh-CN&v=2&key=abcdefg" type="text/javascript"></script>

          注意这里的参数key,我在以前的文章里已经详细解释过了,如果你只是在本地运行,暂时可以不用管它。

    2、在页面的body元素中定义一个地图容器。

          <body>

            <div id="mapContainer" style="height:400px; width:400px;"></div>

          </body>

          这个地图容器一般使用div元素来定义,如果你愿意,使用p元素或者其他你能想到的元素都可以,但是都应该是块元素,并且必须定义它的id,保证在后面的步骤里能够通过document.getElementById找到这个元素。

          容器的style属性在这里是用来定义这个容器的大小,从而决定所显示地图的大小,当然,如果你在这里不定义也可以通过其他的手段来达到目的,这里暂且先认为这个style的定义和id属性一样也是必不可少的吧。

          其实body元素在这里也有一些特殊的作用,就是保证下一步骤在页面的html元素全部加载结束后再执行,详细的理论就不细说了。

    3、定义你自己的script区域,在里面new一个GMap2对象,并且指定其显示所需的两个基本要素:中心、缩放层次。

          <script type="text/javascript">

             var map = new GMap2(document.getElementById("mapContainer"));

             map.setCenter(new GLatLng(33.0, 106.0), 3);

          </script>

         这里的GMap2是谷歌地图API中最重要的核心类,对应在页面上显示的地图,所有对地图的操作都需要在已经创建(new)了GMap2对象的基础上才能够进行。在调用GMap2构造函数是使用的参数就是在上一步定义的地图容器,DOM对象,使用document.getElementById获取。

         要在页面上正常显示地图,仅仅调用GMap2类的构造函数创建一个GMap2对象还不够,你还需要指定这个GMap2对象的中心,通常也顺便指定它的缩放层次,否则就会默认显示缩放层次为0。

         要指定新创建地图的中心,需要使用地图API里面定义的另一个常用类GLatLng,可以把这个类简单的认为是对地理坐标的封装类,构造函数中第一个参数是南北向的纬度,第二个参数是东西向的经度。

         调用GMap2的setCenter方法设定完地图的中心和缩放层次,这个地图就可以正常显示了。

    还需要关心的几个问题:

        上面的示例代码仅仅是为了显示一个试验性质的简单地图,所以把很多暂时不是很必要的代码都去掉了,如果你需要创建具有很好的兼容性、并且能够发布到你自己的网站上的地图,还需要注意这几个问题:

        1、为了保证有足够的兼容性,谷歌建议使用XHTML来定义显示地图的html页面,所以,你需要在这个页面的顶部声明XHTML的DOCTYPE,并且在html中声明XHTML的命名空间

           <!DOCTYPE html PUBLIC

            "-//W3C//DTD XHTML 1.0 Strict//EN"

            "http://www.w3.org/TR/xhtmll/DTD/xhtmll-strict.dtd">

          <html xmlns="http://www.w3.org/1999/xhtml">

          当然,最好你自己的页面代码也能够符合XHTML的语法规则。相对我们现在的HTML4.01来说,可以把XHTML语法规则简单的归纳如下:

          html、head、title、body元素一个都不能少,并且只能有html一个root元素;

          不要使用简化的属性,必须使用“name='value'”的形式;

          标签名和属性名都用小写字母,属性值要用引号括起来;

          标签必须是闭合的,并且不能交叉嵌套;

          使用id属性而不是name属性来获取元素;

        2、为了兼容“伟大的”IE浏览器,以便能够在IE中也正确显示地图中的折线,需要在html标签中增加对VML命名空间的声明

            <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">

            这个很容易忽略,导致你在IE里的折线不能正常显示,所以把这一点单列出来加以强调。

        3、对于通用的浏览器兼容性检查,地图API提供了一个全局方法GBrowserIsCompatible()来保证地图API是在它所兼容的浏览器里运行的,这个兼容浏览器列表我也没找到最新的,谷歌文档里给出了一个远古时代的列表,所以不列也罢,对我们目前通用的FireFox、IE、Safari、Opera浏览器里运行地图API都没有问题。

          这里只说一下GBrowserIsCompatible()这个方法的使用:

          从名字也可以看出,GBrowserIsCompatible()方法返回一个boolean类型的值,所以,把我们对地图操作的起点放在对这个方法返回值的判断块中,形如:

          if(GBrowserIsCompatible()){

            //开始创建和操作地图

          } else {

            //如果有必要,就在这里定义你对这个异常的处理

          }

          当然,在你自己的代码中,针对不同的浏览器环境你还是需要自己实现兼容性的代码,这里的GBrowserIsCompatible()只是保证地图API类库是在它兼容的环境中运行的。

        4、注册你要发布页面所在网站的谷歌地图API密钥,替换掉示例代码里的key,我在这里详细解释过这个密钥,不多说了。

        5、为了保证你的页面在任何可用的网络环境下都能快速加载并且正确显示,建议定义body元素的onload方法,在onload方法中开始你的JS动作。同时,把读入地图API的script标签放在head元素中,而把你自己的JavaScript代码块放到body标签的后面去定义。如果对浏览器的加载顺序比较熟悉的话,你就不必遵守我说的规则了,自由定义你认为应该的JavaScript声明顺序。

        6、为了避免JavaScript中引用页面的DOM元素可能存在的内存泄漏(尤其是在“伟大的”IE浏览器中),你需要使用地图API中定义的GUnload()方法作为你的body元素的onunload方法,并且最好把这个作为一个必须的规则记住。但是GUnload()方法不是避免内存泄漏的大力丸,所以,你在自己的代码中还是需要注意避免内存泄漏这个问题。

        7、为了能够在页面上正常显示中文,需要把页面的字符集定义为utf-8。

        所以,一个完整的应用谷歌地图API的页面代码如下:

     

     

    展开全文
  • SSH配置详细步骤及异常处理

    万次阅读 2009-10-23 16:04:00
    Technorati 标签: SSH,hibernate,struts,spring SSH配置详细步骤及异常处理 该文章详细介绍了SSH的配置步骤与工程代码。 配置步骤见:http://blog.csdn.net/sipsir/archive/2009/10/23/4721526.aspx 代码下载:...

    Technorati 标签: SSH,hibernate,struts,spring

     

    SSH配置详细步骤及异常处理
    该文章详细介绍了SSH的配置步骤与工程代码。
    配置步骤见:http://blog.csdn.net/sipsir/archive/2009/10/23/4721526.aspx
    代码下载:http://sipsir.download.csdn.net/

    本文word格式:http://download.csdn.net/source/1764763

     

    1 环境介绍

    Jdk:1.5s

    服务器:tomcat5.5

    开发工具:myeclipse 6.5 ga

    数据库工具:oracle 10g(确定有class12.jar或带有oracle驱动的jar包)

    开发技术:Spring2.0,struts1.3,hibernate3.1,jsp

    好了,进行SSH的开发。

     

     

    2 新建web project

    新建web项目(使用j2ee 5.0),项目名称为guestbook2,如图:

    clip_image002

    (图一)

    第二步:为项目创建一个文件夹lib(用来将来存放相应的jar包,在添加相应的SSH支持后,要把lib里面的jar通过configure build-path—add jar的方式将其加入),

    --可以采用系统默认的lib库位置,目录为WebRoot/WEB-INF/lib(Add by Michael)

    如图:

    clip_image004

    (图二)

    3 配置MyEclipse数据库(Add by Michael)

    打开Hibernate视图

    clip_image006

    new一个

    clip_image008

    配置数据库,其中要手动指定Class12.jar的目录,如下图

    clip_image010

    4 添加hibernate支持

    第1步:为项目添加hibernate 支持,如图:

    clip_image012

    (图三)

    如下图,我们添加hibernate3.1的核心库而且采用:copy checked library jars to project folder and add to build-path 的方式把包添加至我们刚刚新建的lib文件夹处。完成后,点击”next”.

    hibe

    clip_image014

    接着,他会询问是否创建hibernate的配置文件:hibernate.cfg.xml,我们不需要发动,直接点”next”。

    clip_image016

    我们需要配置项目中要应用的数据库的配置信息:

    clip_image018

    在上图中,我使用了名为DB Driver 为Linkoracle10g的连接方式(可使用myeclipse的myeclipse database explorer方式来创建与oracle10g的连接),相应地,myeclipse会使项目具有与oracle数据库连接的能力了。

    接着点”next”,会看见如下图:

    clip_image020

    默认是挑选了“create SessionFactory class”的,在这里,它想为我们创建一个sessionfactory的类,但我们不创建sessionfactory,因为我将来使用spring来完成这步操作,使用spring ,可以帮助我们可以生成一个能获得hibernate session对象的一个类。

    点击”finish”完成的hibernate的支持。

    5 添加Spring支持

    第1步:为项目添加Spring 支持,如图:

    clip_image022

    在这里,我使用spring2.0的支持,把相应的四个选项选中:

    clip_image024

    第四个为:

    clip_image025

    --选择了spring2.0,如何选择sping2.5的jar?实际情况是我没有选择spring2.5也能完成这个测试(Add by Michael)

    而且,我们采用:copy checked library jars to project folder and add to build-path 的方式把包添加至我们刚刚新建的lib文件夹处。完成后,如图:

    clip_image027

    完成后,点击”next”.会看到如下图:(Myeclipse会为我们创建spring的配置文件,我们确定创建)

    clip_image029

    点击”next”.进入下一步。这时会看到,如图:

    clip_image031

    在上图中,他会创建一个能获得hibernate session 对象的一个sessionFactory 类型的对象,他被设置在了applicationContext.xml文件中。

    点击“finish”,完成Spring 的支持了。

    备注:打开applicationContext.xml文件,源码如下:
    <?xml version="1.0" encoding="UTF-8"?>

    <beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="sessionFactory"

    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="configLocation"

    value="classpath:hibernate.cfg.xml">

    </property>

    </bean>

    </beans>

    在这里,我们发现设置了一个id为sessionFactory类型的一个对象,他的类型是 org.springframework.orm.hibernate3.LocalSessionFactoryBean,当中还有属性configLocation,value="classpath:hibernate.cfg.xml,这些配置信息呢。实际上可以这样理解:

    设定了一个id为sessionFactory 类型的对象,它的类型是:org.springframework.orm.hibernate3.LocalSessionFactoryBean的,通过这个对象就能获取hibernate 的session 对象,进行完成对数据的添加、删除、修改的操作。也就是说这个对象是spring 帮我们提供的一个支持.

    6 开发持久层的这些类和接口

    6.1 oracle表SQL

    增加了hibernate ,spring的支持后,我们就可以开发持久层的这些类和接口了。首先,我们的项目要用到了guestbook、admin两个表,所以要使用oracle来创建这两个表,表的创建的sql提供给大家,如下所示:

    create table ADMIN

    (

    ID NUMBER not null,

    USERNAME VARCHAR2(20),

    PASSWORD VARCHAR2(20)

    );

    alter table ADMIN add constraint ADMIN_PK primary key (ID);

    create table GUESTBOOK

    (

    ID NUMBER not null,

    NAME VARCHAR2(40),

    EMAIL VARCHAR2(60),

    URL VARCHAR2(60),

    TITLE VARCHAR2(200),

    CONTENT VARCHAR2(2000),

    TIME VARCHAR2(40)

    );

    alter table GUESTBOOK add constraint GBOOK_PK primary key (ID);

    insert into ADMIN (ID, USERNAME, PASSWORD)

    values (1, 'liuwei', '123456');

    commit;

    insert into GUESTBOOK (ID, NAME, EMAIL, URL, TITLE, CONTENT, TIME)

    values (100026, '刘伟', 'liuwei8809@163.com', 'http://www.v512.com', '欢迎大家观看我的视频', '感谢大家对我们的支持,请持续关注我们的网站。更多内容,更多视频,尽在www.v512.com。', '2007-16-14 02:12:51');

    insert into GUESTBOOK (ID, NAME, EMAIL, URL, TITLE, CONTENT, TIME)

    values (1000072, '开发工具与软件', null, 'http://news.sina.com.cn', '我们爱大家', '开发工具与软件开发工具与软件开发工具与软件开发工具与软件,我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家。', '2007-42-20 01:12:17');

    insert into GUESTBOOK (ID, NAME, EMAIL, URL, TITLE, CONTENT, TIME)

    values (1000074, '开发工具与软件', 'liuwei@v512.com', 'http://news.sina.com.cn', '我们爱大家', '开发工具与软件开发工具与软件开发工具与软件开发工具与软件,我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家我们爱大家。', '2007-50-20 02:12:52');

    commit;

    而且还应该在oracle10g中创建名为gb_seq的序列,sql语句为:(有问题,在哪里创建sequence的?)

    我只用了一个创建sequence的SQL,如下:

    create sequence GB_SEQ

    minvalue 1

    maxvalue 99999999

    start with 1

    increment by 1

    cache 20;

    以下是原作者关于sequence的sql,我都没有使用因为不知道在哪里create。

    -- Alter sequence

    alter sequence gb_seq

    nominvalue

    nomaxvalue

    nocache;

    -- Modify the last number

    alter sequence gb_seq increment by -20 nocache;

    select gb_seq.nextval from dual;

    alter sequence gb_seq increment by 1 nocache;

    declare

    LastValue integer;

    begin

    loop

    select gb_seq.currval into LastValue from dual;

    exit when LastValue >= 100000 - 1;

    select gb_seq.nextval into LastValue from dual;

    end loop;

    end;

    /

    alter sequence gb_seq increment by 1 nocache;

    (备注:在创建数据库的表时,我是使用了PLSQLDeveloper工具来创建的,这样更方便快捷些,要使用这个工具,请自行下载。)

    好了,接着做下去。

    6.2 生成Admin,guestbook表model

    首先,我们打开myeclipse database explorer 视图,在这里,我们进行逆向工程的操作,如图:

    clip_image033

    这样就打开了逆向工程的操作的界面了。

    接着,我们会看到如下的操作界面,如图:

    clip_image035

    使用如上图的设置,com.v512.guestbook.model存放的是映射文件和相应的实体类(POJO),再点击”next”.

    这时,会出现操作界面,如下图:

    clip_image037

    在这一步,他设置了主键的生成方式,我使用了native,其它不用改变。最后点击”finish”.

    同理,添加guestbook表。(add by Michael)

    再查看目录结构,会显示如下的目录结构,如图:

    clip_image039

    里面针对两个表生成了相应的.hbm.xml的映射文件和相应的两个类。查看hibernate.cfg.xml,其源码如下:

    <?xml version='1.0' encoding='UTF-8'?>

    <!DOCTYPE hibernate-configuration PUBLIC

    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

    <!-- Generated by MyEclipse Hibernate Tools. -->

    <hibernate-configuration>

    <session-factory>

    <property name="connection.username">scott</property>

    <property name="connection.url">

    jdbc:oracle:thin:@localhost:1521:ora10g

    </property>

    <property name="dialect">

    org.hibernate.dialect.Oracle9Dialect

    </property>

    <property name="myeclipse.connection.profile">

    Linkoracle10g

    </property>

    <property name="connection.password">tiger</property>

    <property name="connection.driver_class">

    oracle.jdbc.driver.OracleDriver

    </property>

    <mapping resource="com/v512/guestbook/model/Admin.hbm.xml" />

    <mapping resource="com/v512/guestbook/model/Guestbook.hbm.xml" />

    </session-factory>

    </hibernate-configuration>

    执行上面的操作后,接着往下做。呵呵。

    6.3 数据库接口

    6.3.1 GuestbookDao接口

    我们为项目新建一个包,包名称为:com.v512.guestbook.dao,它用来存放对底层数据库进行的操作的一系列接口。接着在包中新建一个接口,名为:GuestbookDao,如图:

    clip_image041

    在接口中,我们定义了几个方法,如下:

    package com.v512.guestbook.dao;

    import java.util.*;

    import com.v512.guestbook.model.Guestbook;

    //DAO指的是能对底层数据训进行怎样的操作,通常是增删改查的操作

    public interface GuestbookDao {

    public void save(Guestbook g);

    public void delete(Long id);

    public List getGuestbooks();

    public Guestbook getGuestbook(Long id);

    }

    6.3.2 GuestbookDao接口的实现类GuestbookDaoHibernate

    紧接着我们创建一个包,包名为:com.v512.guestbook.dao.hibernate,这个包存放的是实现了上面定义的dao接口的类,而这些类当中都是通过使用Hibernate 的技术来执行相应的操作的。

    在该包中,我创建了一个类,类的名称为:GuestbookDaoHibernate,它要实现上面定义的GuestbookDao接口,并且继承于HibernateDaoSupport.类的完整的源码是:

    package com.v512.guestbook.dao.hibernate;

    //这个包存放的实现了dao接口的一些类,而这些类都是通过Hibernate的技术来执行相应的操作

    import java.util.List;

    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

    import com.v512.guestbook.dao.GuestbookDao;

    import com.v512.guestbook.model.Guestbook;

    public class GuestbookDaoHibernate extends HibernateDaoSupport implements GuestbookDao {

    public void delete(Long id) {

    this.getHibernateTemplate().delete(getGuestbook(id));

    }

    public Guestbook getGuestbook(Long id) {

    return (Guestbook)getHibernateTemplate().get(com.v512.guestbook.model.Guestbook.class, id);

    }

    public List getGuestbooks() {

    return getHibernateTemplate().find("from Guestbook order by id desc");

    }

    public void save(Guestbook g) {

    getHibernateTemplate().saveOrUpdate(g);

    }

    }

    6.3.3 GuestbookManager接口

    在上面操作完成后,我们开始编写服务层的接口和相应的接口实现类(可以理解为spring层)。

    我们新建一个包,包的名称为com.v512.guestbook.service,接着我们在该包中定义了一个接口。完整的源如下:

    package com.v512.guestbook.service;

    import java.util.List;

    import com.v512.guestbook.model.Guestbook;

    public interface GuestbookManager {

    public void save(Guestbook g);

    public void delete(String id);

    public Guestbook getGuestbook(String id);

    public List getGuestbooks();

    }

    6.3.4 GuestbookManager接口的实现类GuestbookManagerImpl

    到了这里,我们新建一个包,包名称为:com.v512.guestbook.service.impl,在包中,我定义了上面GuestbookManager的实现类,完整的源码如下:

    package com.v512.guestbook.service.impl;

    import java.util.List;

    import com.v512.guestbook.dao.GuestbookDao;

    import com.v512.guestbook.model.Guestbook;

    import com.v512.guestbook.service.GuestbookManager;

    public class GuestbookManagerImpl implements GuestbookManager {

    private GuestbookDao dao;

    public void setGuestbookDao(GuestbookDao dao) {

    this.dao = dao;

    }

    public void delete(String id) {

    dao.delete(new Long(id));

    }

    public Guestbook getGuestbook(String id) {

    return dao.getGuestbook(new Long(id));

    }

    public List getGuestbooks() {

    return dao.getGuestbooks();

    }

    public void save(Guestbook g) {

    dao.save(g);

    }

    }

    6.3.5 AdminDao接口

    执行类似的操作,我们在com.v512.guestbook.dao中定义AdminDao的接口,代码如下:

    package com.v512.guestbook.dao;

    public interface AdminDao {

    public boolean validate(String username,String password);

    }

    6.3.6 AdminDao接口的实现类AdminDaoHibernate

    再创建AdminDao的实现类,类名称为AdminDaoHibernate,把它放置在com.v512.guestbook.dao.hibernate包中,完整的源码是:

    package com.v512.guestbook.dao.hibernate;

    import java.util.List;

    import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

    import com.v512.guestbook.dao.AdminDao;

    public class AdminDaoHibernate extends HibernateDaoSupport implements AdminDao {

    public boolean validate(String username, String password) {

    String param[]={username,password};

    List list =getHibernateTemplate().find("from Admin where username=? and password=?",param);

    return list.size()>0;

    }

    }

    在上面操作完成后,我们开始编写服务层的接口和相应的接口实现类(可以理解为spring层)。

    6.3.7 AdminManager接口

    我们新建一个包,包的名称为com.v512.guestbook.service,接着我们在该包中定义了一个接口。完整的源如下:

    package com.v512.guestbook.service;

    public interface AdminManager{

    public boolean validate(String username,String password);

    }

    6.3.8 AdminManager接口的实现类

    到了这里,我们新建一个包,包名称为:com.v512.guestbook.service.impl,在包中,我定义了上面AdminManager的实现类,完整的源码如下:

    package com.v512.guestbook.service.impl;

    import com.v512.guestbook.dao.AdminDao;

    import com.v512.guestbook.service.AdminManager;

    public class AdminManagerImpl implements AdminManager {

    private AdminDao dao;

    public void setAdminDao(AdminDao dao){

    this.dao=dao;

    }

    public boolean validate(String username, String password) {

    return dao.validate(username, password);

    }

    }

    6.4 在spring的配置文件配置数据源,舍弃hibernate.cfg.xml

    紧接着,我们在执行完上面的操作后,我们去修改项目当中的配置文件。在applicationContext.xml中,我想把Hibernate 的配置信息也设置到applicationContext.xml 文件中去,这样的话,hibernate.cfg.xml文件就不需要了.

    首先,打开applicationContext.xml,右键,我在当中创建一个dataSource的bean,如图:

    clip_image043

    接着会弹出这样一个操作界面,如图:

    clip_image045

    设置后,applicationContext.xml中便新增了名为dataSourece的bean。如图:

    clip_image047

    注意:这里会提示错误,因为project里没有commons-dbcp.jar把导致。到D:/MyEclipse 6.5/myeclipse/eclipse/plugins 的目录下搜索, copy到project lib目录下,再加到project的build path(add by Michael)

    在增加了DataSource bean的设置后,再增加两个bean的设置,右键,在“Spring”---"New Bean" ,我们添加了guestbookDao和guestbookManager 两个bean,如图,

    clip_image049

    在上图中,要注意三点:

    1)Bean id 指的是bean 的id;

    2)Bean class :选择

    clip_image051的”Browse”按钮,选择GuestbookDaoHibernate.

    3)最重要的就是:Properties

    clip_image053

    在上图,表示guestbookDao要依赖注射一个sessionFactory的一个对象,添加玩后,如下图

    clip_image055

    (guestbookManager, adminDao, adminManager的添加与上类同,不再赘述。同理他也依赖于guestbookManager 依赖于(ref) guestbookDao;

    adminDao 依赖于(ref) sessionFactory;

    adminManager 依赖于(ref) adminDao;)。(add by Michael)

    现在呢,我们想不再使用Hibernat.cfg.xml文件 ,这里,要修改一下这个applicationContext.xml文件。完整的applicationContext.xml代码如下:

    <?xml version="1.0" encoding="UTF-8"?>

    <beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <!-- 设定了一个id为sessionFactory 类型的对象,它的类型是:org.springframework.orm.hibernate3.LocalSessionFactoryBean的,通过这个对象就能获取hibernate 的session 对象,进行完成对数据的添加、删除、修改的操作。也就是说这个对象是spring 帮我们提供的一个支持. -->

    <bean id="sessionFactory"

    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <!-- <property name="configLocation"

    value="classpath:hibernate.cfg.xml">

    </property>

    -->

    <property name="dataSource">

    <ref bean="dataSource" />

    </property>

    <property name="mappingResources">

    <list>

    <value>com/v512/guestbook/model/Admin.hbm.xml</value>

    <value>

    com/v512/guestbook/model/Guestbook.hbm.xml

    </value>

    </list>

    </property>

    <property name="hibernateProperties">

    <props>

    <prop key="hibernate.dialect">

    org.hibernate.dialect.Oracle9Dialect

    </prop>

    </props>

    </property>

    </bean>

    <bean id="dataSource"

    class="org.apache.commons.dbcp.BasicDataSource">

    <property name="driverClassName"

    value="oracle.jdbc.driver.OracleDriver">

    </property>

    <property name="url"

    value="jdbc:oracle:thin:@localhost:1521:ora10g">

    </property>

    <property name="username" value="scott"></property>

    <property name="password" value="tiger"></property>

    </bean>

    <!-- guestbookDao bean -->

    <bean id="guestbookDao"

    class="com.v512.guestbook.dao.hibernate.GuestbookDaoHibernate"

    abstract="false" lazy-init="default" autowire="default"

    dependency-check="default">

    <property name="sessionFactory"><!-- 表示guestbookDao要依赖注射一个sessionFactory的一个对象 -->

    <ref bean="sessionFactory" />

    </property>

    </bean>

    <!-- guestbookManager bean -->

    <bean id="guestbookManager"

    class="com.v512.guestbook.service.impl.GuestbookManagerImpl"

    abstract="false" lazy-init="default" autowire="default"

    dependency-check="default">

    <property name="guestbookDao"><!--表示guestbookManager需要一个DAO的支持,这里我注射一个guestbookDao -->

    <ref bean="guestbookDao" />

    </property>

    </bean>

    <bean id="adminDao"

    class="com.v512.guestbook.dao.hibernate.AdminDaoHibernate"

    abstract="false" lazy-init="default" autowire="default"

    dependency-check="default">

    <property name="sessionFactory">

    <ref bean="sessionFactory" />

    </property>

    </bean>

    <bean id="adminManager"

    class="com.v512.guestbook.service.impl.AdminManagerImpl"

    abstract="false" lazy-init="default" autowire="default"

    dependency-check="default">

    <property name="adminDao">

    <ref bean="adminDao" />

    </property>

    </bean>

    </beans>

    好了,我们现在应用的持久和服务层的实现类都编写好了,就到了web的开发了。

    现在做2件事:(add by Michael)

    1. src下的hibernate.cfg.xml要删除。

    2. 把src的applicationContext.xml移到WebRoot/WEB-INF下,否则启动服务器时会报错找不到配置文件。

    7 添加struts支持

    为项目添加struts1.3的支持。包名为com.v512.guestbook.web,如图:

    clip_image057

    这时,项目结构发生了改变,如下图:

    clip_image059

    最后,我们修改配置文件,把struts和spring 结合起来。

    修改配置文件web.xml文件,如下:

    <?xml version="1.0" encoding="UTF-8"?>

    <web-app xmlns="http://java.sun.com/xml/ns/javaee"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"

    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- spring 提供了一个过滤器,我们直接拿来用 -->

    <filter>

    <filter-name>encodingFilter</filter-name>

    <filter-class>

    org.springframework.web.filter.CharacterEncodingFilter

    </filter-class>

    <!-- 指定使用UTF-8 -->

    <init-param>

    <param-name>encoding</param-name>

    <param-value>UTF-8</param-value>

    </init-param>

    <init-param>

    <param-name>forceEncoding</param-name>

    <param-value>true</param-value>

    </init-param>

    </filter>

    <!-- 指对所有进行过滤,要加过滤映射,告诉他哪些文件要过滤-->

    <filter-mapping>

    <filter-name>encodingFilter</filter-name>

    <url-pattern>/*</url-pattern>

    </filter-mapping>

    <!-- 下面的代码为了在web中使用spring,还要加载spring 的配置文件,所以要指定application.xml文件的位置-->

    <context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/applicationContext.xml</param-value> <!-- 在这里,指定applicationContext.xml文件的路径,因此呆会要把applicationContext.xml剪切至/WEB-INF目录下 -->

    </context-param>

    <!-- 为了让web应用能加载spring,设置一个侦听,通过这样一个监听器,一启动WEB应用它自动根据上面设置好的配置文件的位置把配置文件加载到内存中,为进一步使用spring中的bean做好准备 -->

    <listener>

    <listener-class>

    org.springframework.web.context.ContextLoaderListener

    </listener-class>

    </listener>

    <servlet>

    <servlet-name>action</servlet-name>

    <servlet-class>

    org.apache.struts.action.ActionServlet

    </servlet-class>

    <init-param>

    <param-name>config</param-name>

    <param-value>/WEB-INF/struts-config.xml</param-value>

    </init-param>

    <init-param>

    <param-name>debug</param-name>

    <param-value>3</param-value>

    </init-param>

    <init-param>

    <param-name>detail</param-name>

    <param-value>3</param-value>

    </init-param>

    <load-on-startup>0</load-on-startup>

    </servlet>

    <servlet-mapping>

    <servlet-name>action</servlet-name>

    <url-pattern>*.do</url-pattern>

    </servlet-mapping>

    <welcome-file-list>

    <welcome-file>input.jsp</welcome-file>

    </welcome-file-list>

    </web-app>

    紧接着,struts-config.xml中我们要创建相应的Form,action,jsp页面,创建方式如图:

    clip_image061

    在此之后,详细的请参见所提供的源码的struts-config.xml文件,通过这个方式,就创建了相应的action,form,在完成这些操作后,SSH的配置就完成了。

    (注:读者如果觉得看不懂的话,可以依照着源码重新做一次,文档写的不是很详细)

    最后部署项目至tomcat容器下,就能够通过这个地址访问了:

    http://localhost:8080/guestbook2/ .

    原作者说到此结束,如果对于一个新手来说要把这个project运行起来可以还会有不少的困难。

    8 运行project

    8.1 copy相关文件到project

    JSP文件:admin.jsp,display.jsp,edit.jsp,index.jsp,input.jsp,login.jsp,loginfail.jsp到WebRoot。

    目录:css,images到WebRoot。

    配置文件: action-servlet.xml,spring.tld,spring-form.tld,validations.xml到WebRoot/WEB-INF。

    8.2 配置tomcat的log4j

    目的是跟踪可能出现的异常,实践证明log能够快速的发现问题。另外很多新手的确也出现很多的问题,也包括我。

    1. commons-logging-1.0.4.jar,log4j-1.2.11.jar copy到project的lib下。

    2. 在Project的WebRoot下建目录logs。

    clip_image063

    3. 在src下新建log4j.properties文件,内容如下

    log4j.rootLogger=info,Console,R

    log4j.appender.Console=org.apache.log4j.ConsoleAppender

    log4j.appender.Console.layout=org.apache.log4j.PatternLayout

    #log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

    log4j.appender.Console.layout.ConversionPattern=%d{yy-MM-dd HH/:mm/:ss} %5p %c{1}/:%L - %m%n

    log4j.appender.R=org.apache.log4j.DailyRollingFileAppender

    log4j.appender.R.File=D://Tomcat5.5// logs//tomcat.txt

    log4j.appender.R.layout=org.apache.log4j.PatternLayout

    log4j.appender.R.layout.ConversionPattern=%d{yyyy.MM.dd HH/:mm/:ss} %5p %c{1}(%L)/:? %m%n

    log4j.logger.org.apache=info, R

    log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG, R

    log4j.logger.org.apache.catalina.core=info, R

    log4j.logger.org.apache.catalina.session=info, R

    log4j.appender.R.File要修改成你的log目录。

    8.3 配置tomcat

    Windows->preference

    clip_image065

    8.4 Deploy project

    点击Deploy按钮,如下图

    clip_image067

    clip_image069

    clip_image071

    clip_image073

    8.5 运行服务器tomcat

    clip_image075

    在你的IE里输入http://localhost:8080/guestbook2/

    此时如果你认为已经结束就太乐观了,大问题在后头呢。我第一次运行时被Error listenerStart搞的晕头。

    9 服务器异常处理

    9.1 服务器启动异常1

    现象:

    09-10-23 21:07:10 ERROR [/guestbook]:667 - action: null

    java.lang.ClassNotFoundException: org.springframework.web.struts.ContextLoaderPlugIn

    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1352)

    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1198)

    解决:

    到D:/MyEclipse 6.5/myeclipse搜索spring-web.jar,加到project的lib下.重新部署Redeploy,再启动。

    又遇到了下面的异常。

    9.2 服务器启动异常2

    现象:

    2009.10.23 21:22:47 ERROR [/guestbook2](3678):? Error configuring application listener of class com.sun.faces.config.ConfigureListener

    java.lang.NoClassDefFoundError: org/apache/commons/digester/RuleSet

    at java.lang.Class.getDeclaredConstructors0(Native Method)

    解决:

    到D:/MyEclipse 6.5/myeclipse搜索commons-pool.jar,jsf-impl,加到project的lib下.重新部署Redeploy,再启动。

    至此,问题已经解决。

    9.3 可能的其他异常供参考(从网上找的)

    9.3.1 JSF--整合spring

    使用JSF-Spring整合
    一、下载
    进官方网站http://jsf-spring.sourceforge.net,下载lib
    二、参考quickstart配置相应文件
    http://jsf-spring.sourceforge.net/quickstart.shtml
    最终配置结果如下
    web.xml

    clip_image076<?xml version="1.0" encoding="UTF-8"?>
    clip_image076[1]<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    clip_image076[2]    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
    clip_image076[3]    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    clip_image076[4] <context-param>
    clip_image076[5] <param-name>javax.faces.CONFIG_FILES</param-name>
    clip_image076[6] <param-value>
    clip_image076[7]            /WEB-INF/classes/faces/faces-config.xml, 
    clip_image076[8]            /WEB-INF/classes/faces/faces-config-beans.xml
    clip_image076[9] </param-value>
    clip_image076[10] </context-param>
    clip_image076[11] <context-param>
    clip_image076[12] <param-name>contextConfigLocation</param-name>
    clip_image076[13] <param-value>
    clip_image076[14]            classpath*:spring/applicationContext-*.xml
    clip_image076[15] </param-value>
    clip_image076[16] </context-param>
    clip_image076[17]
    clip_image076[18] <servlet>
    clip_image076[19] <servlet-name>Faces Servlet</servlet-name>
    clip_image076[20] <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    clip_image076[21] <load-on-startup>0</load-on-startup>
    clip_image076[22] </servlet>
    clip_image076[23] <servlet-mapping>
    clip_image076[24] <servlet-name>Faces Servlet</servlet-name>
    clip_image076[25] <url-pattern>*.faces</url-pattern>
    clip_image076[26] </servlet-mapping>
    clip_image076[27] <listener>
    clip_image076[28] <listener-class>
    clip_image076[29]            org.springframework.web.context.request.RequestContextListener
    clip_image076[30] </listener-class>
    clip_image076[31] </listener>
    clip_image076[32] <listener>
    clip_image076[33] <listener-class>
    clip_image076[34]            org.springframework.web.context.ContextLoaderListener
    clip_image076[35] </listener-class>
    clip_image076[36] </listener>
    clip_image076[37] <listener>
    clip_image076[38] <listener-class>de.mindmatters.faces.spring.context.ContextLoaderListener</listener-class>
    clip_image076[39] </listener>
    clip_image076[40]
    clip_image076[41]</web-app>
    clip_image076[42]
    clip_image076[43]

    请注意以上listener的顺序,如果位置不同可能出现找不到在spring中定义的bean。请按以上顺序配置即可。
    根据quitstart配置完之后可能还有如下异常:
    org.apache.jasper.JasperException: javax.servlet.ServletException: javax.servlet.jsp.JspException: javax.faces.el.EvaluationException: de.mindmatters.faces.spring.factory.BeansEvaluationException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uiBean': Scope 'request' is not active; nested exception is java.lang.IllegalStateException: No thread-bound request: use RequestContextFilter
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:532)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:408)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:320)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:266)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:322)
    com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:147)
    de.mindmatters.faces.lifecycle.RenderResponsePhase.executePhase(RenderResponsePhase.java:45)
    de.mindmatters.faces.lifecycle.AbstractPhase.execute(AbstractPhase.java:37)
    de.mindmatters.faces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:166)
    de.mindmatters.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:226)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)
    然后再把这个listener加上
    <listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    就ok了。
    可选
    如果还有问题,在faces-config.xml中添加
    <application>
         <variable-resolver>
          org.springframework.web.jsf.DelegatingVariableResolver
         </variable-resolver>
      <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
    </application>

    posted on 2007-04-26 16:18 风人园 阅读(2936) 评论(3) 编辑 收藏 所属分类: JSF

    clip_image077

    评论

    # re: JSF--整合spring  回复 更多评论

    我按照你的配置修改后,后台老提示
    严重: Error configuring application listener of class com.sun.faces.config.ConfigureListener
    java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1352)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1198)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:3677)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4183)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:759)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:739)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:524)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:608)
    at org.apache.catalina.startup.HostConfig.deployDescriptors(HostConfig.java:535)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:470)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1112)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:310)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1021)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:718)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1013)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:442)
    at org.apache.catalina.core.StandardService.start(StandardService.java:450)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:709)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:551)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:275)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
    请问什么原因?我该如何解决? 急啊!
    老大

    2007-07-16 12:04 | zzb

    # re: JSF--整合spring  回复 更多评论

    我的也是这个问题
    严重: Error configuring application listener of class com.sun.faces.config.ConfigureListener
    java.lang.ClassNotFoundException: com.sun.faces.config.ConfigureListener

    2007-09-27 17:02 | wxyhibernate

    # re: JSF--整合spring 回复 更多评论

    com.sun.faces.config.ConfigureListener在jsf的sun参考实现jsf-impl.jar中。
    如果你使用的是apache的myfaces实现的话可以去掉这个listener。

    2007-12-04 15:18 | KimmKing

    9.3.2 严重: Exception sending context initialized event to listener instance

    clip_image078已解决提问者:smallbqxy_062 - 二副 十一级

    严重: Exception sending context initialized event to listener instance o

    悬赏分:clip_image079100 解决时间:2008-12-25 12:29

    用 myeclipse 做 spring+hibernate+struts2 时报错,不知为什么,可能是spring包有问题 ,说是asm..之类的我都弄了也不行,如有知道请告诉一下。
    严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
    java.lang.NoClassDefFoundError: org/springframework/context/support/AbstractRefreshableConfigApplicationContext
    2008-12-6 16:08:39 org.apache.catalina.core.StandardContext start
    严重: Context [/t8] startup failed due to previous errors

    clip_image080最佳答案

    clip_image0817481086_582 - 二副 十一级

    你可能把不要的包也导进去了或是哪个必需的包没导入,以下是必需包:
    Spring包(9个): 
    commons-dbcp.jar、commons-pool.jar、spring.jar、spring-beans.jar、
    spring-context.jar、spring-core.jar、spring-dao.jar、
    spring-hibernate3.jar、spring-web.jar。
    struts2.0包(6个):commons-logging-api-1.1.jar、freemarker-2.3.8.jar 
    ognl-2.6.11.jar、struts2-core-2.0.8.jar、
    struts2-spring-plugin-2.0.11.2.jar、xwork-2.0.3.jar 
    hibernate包:myeclipse工具自动添加生成导入。
    还有就是数据库驱动包。
    如果还有什么问题加:QQ 274339969

    回答采纳率达:27%(440个被采纳)

    评价已经被关闭 目前有 0 个人评论

    好不好

    0% (0)0% (0)

    相关问题

    其它回答 (2)

    clip_image081[1]xuan6325293_706 - 二副 十一级

    别的我不多说,我只告诉你些配置Spring的问题所报出的这种错误
    你这问题如果是启动Tomcat出的问题报错解决方法很简单如下:
    需要加载的包(必须):commons-dbcp.jar和commons-pool.jar
    需要删除的包(必须):asm-2.2.3.jar 
    如果按照此方法,必定解除你的错误 如果这加载包没有 我给你!

    回答采纳率达:30%(472个被采纳)

    clip_image081[2]89B2A3604_868 - 二副 十一级

    java.lang.NoClassDefFoundError: 
    你在配置文件里定义的某个类,没有找到,估计是包名没有写对,把报错信息再仔细地看一看

    回答采纳率达:29%(453个被采纳)

    9.3.3 严重: Error listenerStart

    最近关于SPRING的配置的问题一启动TOMCAT就出现"严重: Error listenerStart",通过BAIDU和GOOLGE查找了差不多两天,没有找一个有建设性的意见.都是一些转载,我真的想问问他们有没有真真的去面对过,和测试过,就在这里乱说!出现这种错误的主要原因是由于WEB.XML配置SPRING的时候出错的:
    org.springframework.web.context.ContextLoaderListener

    现在我认为有必要说说我解决的方面了:要考虑的方面有:

    1、web.xml的配置有没有问题!

    2、一些必要的JAR文件,有没有多余JAR文件,是不是版本问题

    3、是不是JDK和TOMCAT的版本问题

    4、最重要的是在这里了:SPRING配置文件是不是有配置BEAN有错误!

    补充:还一个更绝的方法:通过TOMCAT的LOG来解决这个问题,更方便,更简单.不过要配置TOMCAT的LOG

    首先在TOMCAT目录下找到common下的lib,在这个目录下加入两个JAR文件,分别是commons-logging-1.0.4.jar和log4j-1.2.9.jar,同时还需要在common下的classes目录下加入log4j.properties文件,

    我的log4j.properties文件配置如下:

    log4j.rootLogger=info, A1 , R
    log4j.appender.A1=org.apache.log4j.ConsoleAppender
    #log4j.appender.A1.layout=org.apache.log4j.HTMLLayout
    #log4j.appender.A1.layout=org.apache.log4j.SimpleLayout
    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=${myappfuse.root}/WEB-INF/classes/log/log4j.log
    log4j.appender.R.MaxFileSize=200KB
    log4j.appender.R.MaxBackupIndex=100
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    #log4j.appender.R.layout=org.apache.log4j.DailyRollingFileAppender
    #log4j.appender.R.layout.ConversionPattern=%p -thread: %t - %l - %c - %m%n
    log4j.appender.R.layout.ConversionPattern=%p -%-d{yyyy-MM-dd HH:mm:ss} %l - %m%n
    ### set log levels - for more verbose logging change 'info' to 'debug' ###
    #log4j.logger.org.hibernate=info
    #log4j.logger.org.hibernate=debug

    ### log HQL query parser activity
    #log4j.logger.org.hibernate.hql.ast.AST=debug

    ### log just the SQL#
    log4j.logger.org.hibernate.SQL=INFO
    #log4j.logger.java.sql.PreparedStatement=DEBUG

    ### log JDBC bind parameters ###
    #log4j.logger.org.hibernate.type=info
    #log4j.logger.org.hibernate.type=debug

    ### log schema export/update ###
    #log4j.logger.org.hibernate.tool.hbm2ddl=debug

    ### log HQL parse trees
    #log4j.logger.org.hibernate.hql=info

    ### log cache activity ###
    #log4j.logger.org.hibernate.cache=debug

    ### log transaction activity
    #log4j.logger.org.hibernate.transaction=debug

    ### log JDBC resource acquisition
    #log4j.logger.org.hibernate.jdbc=debug

    ### enable the following line if you want to track down connection ###
    ### leakages when using DriverManagerConnectionProvider ###
    #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

    9.3.4 使用spring中,出现深恶痛绝的Error listenerStart!!

    使用spring,出现深恶痛绝的Error listenerStart!!

    楼主syhgxyhzb(剑雨飞花)2006-09-30 22:10:24 在 Java / 框架、开源 提问

    web.xml:
      <?xml   version="1.0"   encoding="UTF-8"?>  
      <web-app   version="2.4"   xmlns="http://java.sun.com/xml/ns/j2ee"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
                        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee  
      http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
      <context-param>  
      <param-name>contextConfigLocation</param-name>  
      <param-value>classpath:applicationContext.xml</param-value>  
      </context-param>                
      <listener>  
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
      </listener>  
      </web-app>  
      applicationContext.xml在src下:
      <?xml   version="1.0"   encoding="UTF-8"?>  
      <!DOCTYPE   beans   PUBLIC   "-//SPRING//DTD   BEAN//EN"   "http://www.springframework.org/dtd/spring-beans.dtd">  
      <beans>  
      <bean   id="dataSource"  
      class="org.apache.commons.dbcp.BasicDataSource">  
      <property   name="driverClassName"   value="com.mysql.jdbc.Driver"   />  
      <property   name="url"   value="jdbc:mysql://localhost:3306/study"   />  
      <property   name="username"   value="root"   />  
      <property   name="password"   value="admin"   />  
      </bean>  
      <bean   id="sessionFactory"  
      class="org.springframework.orm.hibernate.LocalSessionFactoryBean">  
      <property   name="dataSource"   ref="dataSource"></property>  
      <property   name="mappingResources">  
      <list>  
      <value>/org/study/domain/hbm/Test1.hbm.xml</value>  
      <value>/org/study/domain/hbm/Test2.hbm.xml</value>  
      </list>  
      </property>  
      </bean>  
      </beans>  
    这样的话,启动tomcat便出现熟悉的:
      2006-9-30   21:50:30   org.apache.catalina.core.StandardContext   start  
    严重:   Error   listenerStart  
      2006-9-30   21:50:30   org.apache.catalina.core.StandardContext   start  
    严重:   Context   [/yumen]   startup   failed   due   to   previous   errors  
    如果将applicationContext当中的:
      <property   name="mappingResources">  
      <list>  
      <value>/org/study/domain/hbm/Test1.hbm.xml</value>  
      <value>/org/study/domain/hbm/Test2.hbm.xml</value>  
      </list>  
      </property>  
    去掉就没有问题了,但是我确信目录没有错。
    请问这是怎么回事??
    问题点数:100、回复次数:10Top

    1 kinsey0514(春天的老黄牛)回复于 2006-09-30 22:59:37 得分 0

    upTop

    2 timtin0361(究极奥义)回复于 2006-10-01 11:32:11 得分 0

    /org/study/domain/hbm/Test1.hbm.xml  
    第一个/   要吗Top

    3 syhgxyhzb(剑雨飞花)回复于 2006-10-01 12:25:06 得分 0

    无论要不要,都照样出错。Top

    4 jrwx()回复于 2006-10-01 19:00:49 得分 0

    可能Test2.hbm.xml,Test1.hbm.xml的格式不对,读不出里面的内容 你转一下本地编码格式试试Top

    5 syhgxyhzb(剑雨飞花)回复于 2006-10-01 19:27:18 得分 0

    什么叫本地编码格式呢?Top

    6 zqpsswh(似水无痕)回复于 2006-10-03 17:27:35 得分 0

    明显格式不对 仔细检查吧
    是否DTD错误?Top

    7 syhgxyhzb(剑雨飞花)回复于 2006-10-04 08:38:51 得分 0

    什么叫明显格式不对呢?  
    好多书上,网上都是这样写的,那这么明显,您看出来了?Top

    8 Saro(这也不是江水,这是二十年流不尽的英雄血。)回复于 2006-10-04 11:46:20 得分 100

    运行一下
      new   ClassPathXmlApplicationContext("applicationContext.xml").getBean("sessionFactory");  
    看看报什么异常。Top

    9 syhgxyhzb(剑雨飞花)回复于 2006-10-04 21:13:17 得分 0

    按照Saro的方法找到了错误,原来是hibernate2和hibernate3的版本问题.解决了.  
    Top

    10 syhgxyhzb(剑雨飞花)回复于 2006-10-04 21:15:37 得分 0

    贴子回复次数大于跟给分次数   ,是什么意思,不能给分

    9.3.5 开发异常的解决方法

    2009年04月09日 00时00分

    1、java.lang.NoSuchMethodError: sun.rmi.transport.ObjectTable.getStub(Ljava/rmi/Remote;)Ljava/rmi/server/RemoteStub

    问题描述:当集成JOTM 2.0.13到Tomcat 5.5.27时出现。

    解决方法:修改carol.properties文件中的carol.jvm.rmi.local.call属性为true。

    2、java.lang.NoSuchMethodError: org.springframework.util.Assert.noNullElements([Ljava/lang/Object;Ljava/lang/String;)V

    解决方法:不能将Spring 2.0和Spring 2.5中的spring.jar与spring-[modules].jar混合使用。

    9.3.6 Tomcat严重错误,日志里出现: java.lang.NoClassDefFoundError: javax/el/ExpressionFactory

    发布工程时,抛出以下异常:
    java.lang.NoClassDefFoundError: javax/el/ExpressionFactory
    Apache Tomcat/5.0.28
    则将javaee.jar包再copy一份放在tomcat目录的common/lib下就不会了。
    关于用到的javaee.jar、jsf-api.jar、jsf-impl.jar、jstl-1.2.jar这四个包可以通过myeclipse中获得,这四个包的所在的目录是:
    D:/Program Files/MyEclipse 6.5/myeclipse/eclipse/plugins/com.genuitec.eclipse.j2eedt.core_6.5.0.zmyeclipse650200806/data/libraryset/EE_5

    posted on 2008-08-29 19:39 Documents 阅读(1370) 评论(0) 编辑 收藏 所属分类: Tomcat

    clip_image077[1]

    IT新闻 新用户注册 刷新评论列表

    9.3.7 tomcat启动时出现的 严重: Error listenerStart

    最近看《WebWork.Spring.Hibernate整合开发网络书城》视频教程,自己按照教程上说的做练习,在启动tomcat时总是出一个错误:<o:p></o:p>

      2007-5-31 14:27:13 org.apache.catalina.core.StandardContext start
    严重: Error listenerStart
          2007-5-31 14:27:13 org.apache.catalina.core.StandardContext start
    严重: Context [/testWSH] startup failed due to previous errors
    教程的作者在录制教程时也遇到了此问题,但是他删了一个jar包后就没事了,可是我的一直无法正常启动,从昨天到现在一天的时间都在研究这个问题,也“百 度”到了很多有关此问题的信息,但是都没有很明确的解决方案。现在此问题已经解决,而且基本肯定问题所在,所以将解决方案写出来以供参考。
    有一种解决方案是把web.xml文件中的<o:p></o:p>

    <listener>       <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
    listener>
    改为
       <servlet>
            <servlet-name>SpringContextServletservlet-name>
            <servlet-class>
                org.springframework.web.context.ContextLoaderServlet
            servlet-class>
            <load-on-startup>1load-on-startup>
        servlet><o:p></o:p>

    但这种方法可能会出现其他问题(网上又说会导致其他文件无法打开)。
        <o:p></o:p>

    我的最终解决方案如下:
    我用的是tomcat5.5,配置了日志之后打印出下列信息:
       ERROR main org.springframework.web.context.ContextLoader - Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
    Caused by:
    java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
        at java.lang.Class.getDeclaredConstructors0(Native Method)
      at java.lang.Class.privateGetDeclaredConstructors(Class.java:2328)
        at java.lang.Class.getConstructor0(Class.java:2640)
        at java.lang.Class.getDeclaredConstructor(Class.java:1953)
        ……
    从日志信息看问题已经很明显了,是 applicationContext.xml dataSource 问题。

    <bean class="org.apache.commons.dbcp.BasicDataSource" id="dataSource"></bean><bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <bean class="org.apache.commons.dbcp.BasicDataSource" id="dataSource"></bean>改为
    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource"></bean><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    之后问题得到解决。 <o:p></o:p>

    出现"Error listenerStart"一般是applicationContext.xml中的bean加载有问题。在用eclipse做webwork + spring + hibernate 的项目时一般都是用Myeclipse自动生成那些配置文件,而有些相关的jar或者文件并没有加载在至项目中,以至引出奇怪的问题,又因为是自动生成的东西所以往往会忽略一些文件,而问题确恰恰是这些生成的文件所致,所以自动化的东西也未必一定是正确的,呵呵……<o:p></o:p>

        org.springframework.jdbc.datasource.DriverManagerDataSource 不可以使用连接池。org.apache.commons.dbcp.BasicDataSource作为注入的DataSource源,为了使用 DBCP的功能,必须要将commons-dbcp.jar加入CLASSPATH中,另外还需要commons-pool.jar和commons- collections.jar,这些都可以在Spring的lib目录下找到。
    org.springframework.jdbc.datasource.DriverManagerDataSource并没有提供连接池的功能,只能作作简单的单机连接测试。
    使用org.apache.commons.dbcp.BasicDataSource时缺少commons-pool.jar所以会出现如题的问题。 <o:p></o:p>

    再次修正:<o:p></o:p>

    昨天又遇到此问题,解决的办法是删除无用的jar。<o:p></o:p>

    工程是 spring+hibernate+tomcat<st1:chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on">5.5.25</st1:chsdate>,jar都是用eclipse自动加载的,很多jar明显的用不到,例如:ibatis,toplink等。将无用的jar删除后问题解决。<o:p></o:p>

    <o:p> </o:p>

    评论

    12 楼 shudikoo 2008-05-21   引用

    我也遇到了这个问题,研究了3天,最后知道是少了几个spring的包。去官网下载spring的最新包。就ok了。具体的文件配置在http://user.qzone.qq.com/3470537/blog/1211351181

    11 楼 摆渡人 2008-04-07   引用

    怪事,偶也是报这个错误,发现没加入spring.jar包,加了之后.tomcat6启动就OK了

    10 楼 richardlovejob 2007-10-26   引用

    谢谢你的提示帮助!

    9 楼 danielchen19 2007-09-01   引用

    我也曾经试过这样可以过一次,但现在又出现这种情况,原因是在web.xml 删了<listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListener
    </listener-class>
    </listener>就可以了, 正常情况是可以的,不知是什么原因,请高手解答一下。

    8 楼 xj4150 2007-08-23   引用

    danielchen19 写道

    我也是将它变成这样<!--<listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListener
    </listener-class>
    </listener>
    -->
    <servlet>
            <servlet-name>SpringContextServlet</servlet-name>
            <servlet-class>    </servlet-class>
              <load-on-startup>1</load-on-startup>
        </servlet>
    但是还是出现严重: Error listenerStart
    2007-8-12 8:37:30 org.apache.catalina.core.StandardContext start
    严重: Context [/ConnectNote] startup failed due to previous errors, 请问是什么原因??

    ybbtgvusr 写道

    我也遇到了楼主说的情况,按你说的解决方法试过了。但没有用呀,还是出现Error listenerStart错误!!

    先看看日志吧,看看报什么异常

    7 楼 danielchen19 2007-08-12   引用

    我也是将它变成这样<!--<listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListener
    </listener-class>
    </listener>
    -->
    <servlet>
            <servlet-name>SpringContextServlet</servlet-name>
            <servlet-class>    </servlet-class>
              <load-on-startup>1</load-on-startup>
        </servlet>
    但是还是出现严重: Error listenerStart
    2007-8-12 8:37:30 org.apache.catalina.core.StandardContext start
    严重: Context [/ConnectNote] startup failed due to previous errors, 请问是什么原因??

    6 楼 ybbtgvusr 2007-07-05   引用

    我也遇到了楼主说的情况,按你说的解决方法试过了。但没有用呀,还是出现Error listenerStart错误!!

    5 楼 hcconquer 2007-06-15   引用

    楼上说的很对,commons-dbcp.jar、commons-pool.jar和commons- collections.jar都加到lib就好了
    我现在报sessionFactory不能创建,请问要加那几个包啊

    4 楼 aimama_1314 2007-06-04   引用

    在这里搜到你的帖`~  XJ~~
    我又遇见这样的问题了``
    估计是刚才applicationContext.XML 加bean的时候加错了``555
    泪``继续改错``

    3 楼 xj4150 2007-06-01   引用

    使用org.apache.commons.dbcp.BasicDataSource时缺少commons-pool.jar所以会出现如题的问题。

    2 楼 xj4150 2007-05-31   引用

    org.springframework.jdbc.datasource.DriverManagerDataSource并没有提供连接池的功能,只能作作简单的单机连接测试。

    1 楼 xj4150 2007-05-31   引用

    <bean id="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">不可以使用连接池。org.apache.commons.dbcp.BasicDataSource作为注入的DataSource源,为了使用DBCP的功能,必须要将commons-dbcp.jar加入CLASSPATH中,另外还需要commons-pool.jar和commons- collections.jar,这些都可以在Spring的lib目录下找到。

    9.3.8 在部署Struts时,出现如下404错误信息

    struts常见问题1:HTTP Status 404 - Servlet action is not available 收藏

    在部署Struts时,出现如下错误信息:

    HTTP Status 404 - Servlet action is not available

    --------------------------------------------------------------------------------

    type Status report

    message Servlet action is not available

    description The requested resource (Servlet action is not available) is not available.

    问题原因:

    1.、web.xml文件中未配置ActionServlet。

    2、struts-config.xml文件未配置你要访问的Action。

    3、你的jsp文件form标记中action属性的路径名称错误。

    4、非以上三种情况。

    针对以上4种情况相应的解决方案如下:

    1、在web.xml文件中加上ActionServlet的配置信息

    clip_image083

    2、在struts-config.xml文件检查你要访问的Action配置文件。

    3、检查jsp文件form标记中action属性的路径名称是否与struts-config.xml文件中action标记的path属性的路径名称一致。

    4、非以上情况的解决办法就是检查web容器的log日志,如果时tomcat则检查下logs目录下的localhost_log文件,看里边是否记录有错误信息,然后根据错误信息提示将其纠正。

    发表于 @ 2008年06月27日 10:53:00 | 评论( 0 ) | 编辑| 举报| 收藏

    旧一篇:java遇到的错误 | 新一篇:Acegi学习一

    本文来自CSDN博客,转载请标明出处:file:///D:/DOC/SSH/struts常见问题1:HTTP%20Status%20404%20-%20Servlet%20action%20is%20not%20available%20-%20xu_zh_h的专栏%20-%20CSDN博客.htm

    展开全文
  • SurfaceView是视图(View)的继承,这视图里内嵌了一专门用于绘制的surface。我们可以控制这surface的格式和尺寸。SurfaceView控制这surface绘制的位置。surface直接继承Object,对应了一块屏幕缓冲区,...
  • 创建和打印大宗邮件的标签--Word篇

    千次阅读 2007-06-11 14:07:00
    资源内容: 如果希望使用地址标签向地址列表发送大宗邮件,可以使用邮件合并创建地址标签表。每个标签都包含列表中的一地址。邮件合并过程需要执行以下所有步骤: 设置标签。设置一次标签布局,邮件合并中的所有...
  • 自定义jsp标签

    2017-02-17 16:42:24
    1.创建自定义标签处理类(Tag Handler Class) 2.创建TLD标签库描述文件(Tag Library Desciptor) web应用使用标签: 1.标签处理类和相关.class文件放到WEB-INF\CLASS目录下 2.把TLD放到WEB-INF或者其...
  • 自定义JSTL标签

    2015-06-18 23:34:29
    步骤1:创建自定义标签处理类 步骤2:创建TLD标签库描述文件   使用步骤: 配置TLD文件 修改JSP文件,使用自定义标签   步骤: 1、实现Tag接口或SimpleTag接口或者继承TagSupport 使用接口方式则要...
  • 4、将分类所得到的正负文本放进不同的文档中,自己检查看大体上是否分类正确 """ import csv # import sys import jieba import re # import importlib path_meituan = r'D:\lagua\study\...
  • 自定义标签

    千次阅读 2010-12-28 10:24:00
    简单标签 —— 不对其正文操作的标签称为 ,简单标签可以实现 Tag 接口简单标签第 1 步:创建实现了 Tag 接口的标签处理程序Tag 接口定义了标签处理程序和 JSP 页实现之间的基本协议。它定义了在标签开始和结束...
  • 创建实体 XML方式概述及步骤 1. 首先在src/main/resources下com.artisan.mybatis.xml.mapper目录下创建5表各自对应的XML文件 2. 然后在src/main/java先创建包com.artisan.mybatis.xml.mapper,接着在该包...
  • 07_javaweb之自定义标签

    2013-12-11 21:32:32
    、自定义标签 1.传统标签 1).写一个类去实现Tag接口 2).写一个tld文件描述写好的标签处理器类 2.简单标签 1).开发步骤 1'.写一个类去实现simpletag接口,也可以去继承simpletag的默认实现类simpleTagSupport,覆盖...
  • 前言这篇博客和上一篇性质差不多,都是旨在说明...多标签分类/回归问题和单标签的工作流程比较类似,大致分为以下几个步骤,然后本博客再对各个环节做进一步解释。 准备数据(图像整理好放到合适的文件夹中,对应的gr
  • JSTL自定义标签

    千次阅读 2016-05-02 16:37:49
    这节我们总结一下JSTL自定义标签相关内容。 1. 自定义标签简介  自定义标签主要用于...那么这时候我们就可以自己定义一个标签,来完成需要用java代码完成的事情,这样Jsp页面就会清洁很多,可读性也更强。JSP中使用
  • 博文已完成,版本号v1.0范例网址已移除,请下载源码(下载后需要自行设置mysql)附完整源代码下载链接(0积分下载):http://download.csdn.net/detail/qq20004604/9638269v1.01订正一数据库查询重复内容的bug,在...
  • (2)、使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤: 编写一实现Tag接口的Java(标签处理器)。编写标签库描述符(tld)文件,在tld文件中对标签处理器进行描述。 快速入门:使用标签输出...
  • UIView只负责对数据的展示,采集用户的输入、监听用户的事件等,其他操作比如:每UIView的创建、销毁、用户触发事件后的事件处理程序等这些都交给UIViewController来处理。控制器管理部分如下图: 11、...
  • Struts 1 之标签

    千次阅读 2015-01-28 08:40:56
    如果为,该标签体中嵌入的内容就会被处理。该标签用于以下情况: 当Java对象为null时 当String对象为""时 当java.util.Collection对象中的isEmpty()返回true时 当java.util.Map对象中的isEmpty()返回true时...
  • 知识点:理解 ASP.NET 的概念和优势、会创建 ASP.NET Web Form 程序、理解 ASP.NET Web Form 程序的执行阶段、会使用代码内嵌和代码后置两种方式进行编码。 1、网站开发基础了解 1.1 网站开发各环节组成 1.2 ...
  • 添加消息处理函数或重载MFC

    千次阅读 2007-07-26 14:12:00
    目标在中,添加一消息处理函数或者重载一M F C成员函数。策略首先,用Class Wi z a r d自动地添加一消息处理函数或重载成员函数;然后,讨论当需要的处理函数或重载函数在Class Wi z a r d指令系统的外面时...
  • 四大标签库: core:核心库,重点 fmt:格式化:日期、数字 sql:过时 xml:过时导入标签库jar包 在jsp页面中:”前缀” uri=”路径”%> core –> c标签!out和set remove url if choose
  • 创建图片搜索引擎的完整指南

    千次阅读 2015-06-01 15:30:22
    大家都知道,通过文本或标签来搜索图片的体验非常糟糕。 无论你是将个人照片贴标签并分类,或是在公司的网站上搜索一堆照片,还是在为下一篇博客寻找合适的图片。在用文本和关键字来描述图片是非常痛苦的事。...
  • 文本和输入:创建IME:简介

    千次阅读 2017-05-08 09:55:22
    输入法编辑器(IME)是用户可以控制,以让用户输入文本的编辑器。 Android提供了一可扩展的输入法框架,允许应用程序为用户提供替代...要向Android系统添加IME,您可以创建包含扩展InputMethodService的Androi
  • JSP的标签技术

    千次阅读 2016-12-08 11:06:36
    JSP的标签技术主要有下面种: jsp标签。 EL表达式。 JSTL标签库。 自定义标签技术。 一、jsp标签sun原生提供的标签,可以直接在jsp页面中使用。这种标签技术在实际使用中用的不是很多。它有很多标签,下面介绍其中...
  • 自定义标签&&JSTL标签库详解

    万次阅读 2015-10-27 14:33:25
    今天来看一下自定义标签的内容,自定义标签是JavaWeb的一部分非常重要的核心功能,我们之前就说过,JSP规范说的很清楚,就是Jsp页面中禁止编写一行Java代码,就是最好不要...编写一实现Tag接口的Java,并覆盖doStar
  • 5w字长文带你彻底看懂Spring是怎么创建对象的!附10几张图,在创作这篇文章的过程中给官方提交了两issue
  • TabControl的用法步骤详解

    千次阅读 2014-04-03 16:17:18
    在对话框资源上从工具箱中添加上一Tab Control 控件,根据需要修改一下属性,然后右击控件,为这控件添加一变量,将此控件跟一CTabCtrl变量绑定在一起,这里设为m_tabctrl 2、创建新的对话框资源,...
  • ************步骤一*******************:在你的web应用目录下,找到WEB-INF文件夹,在里面新建一tld类型的文件:&lt;!-- 标签库描述符 --&gt; &lt;taglib xmlns="http://java....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 63,626
精华内容 25,450
关键字:

创建空标签处理类的4个步骤