自定义MVC框架(二) -基于XML文件

1.oracle的脚本

 1 create table STUDENT
 2 (
 3   sid   NUMBER primary key,
 4   sname VARCHAR2(20),
 5   age   NUMBER,
 6   pwd   VARCHAR2(20)
 7 )
 8 
 9 create sequence seq_student;
10 
11 insert into STUDENT (sid, sname, age, pwd)
12 values (seq_student.nextval, 'holly', 18, '123');
13 insert into STUDENT (sid, sname, age, pwd)
14 values (seq_student.nextval, '钱涛', 108, '123');
15 insert into STUDENT (sid, sname, age, pwd)
16 values (seq_student.nextval, '张睿', 10, '123');
17 insert into STUDENT (sid, sname, age, pwd)
18 values (seq_student.nextval, '修地', 16, '123');
19 commit;
student.sql

2.创建如下的项目结果

(并在WebRoot下的lib文件夹下添加dom4j-1.6.1.jar和ojdbc14.jar)

3.在com.javabean包下创建Student.java文件

 1 package com.javabean;
 2 /**
 3  * 学生类
 4  * @author Holly老师
 5  *
 6  */
 7 public class Student {
 8     /*学生编号*/
 9     private int sid;
10     /*学生姓名*/
11     private String sname;
12     /*学生密码*/
13     private String pwd;
14     /*年龄*/
15     private int age;
16     
17     public Student() {
18         super();
19     }
20 
21     public Student(int sid, String sname, String pwd, int age) {
22         super();
23         this.sid = sid;
24         this.sname = sname;
25         this.pwd = pwd;
26         this.age = age;
27     }
28 
29     public Student(int sid, String sname, int age) {
30         super();
31         this.sid = sid;
32         this.sname = sname;
33         this.age = age;
34     }
35 
36     public int getSid() {
37         return sid;
38     }
39 
40     public void setSid(int sid) {
41         this.sid = sid;
42     }
43 
44     public String getSname() {
45         return sname;
46     }
47 
48     public void setSname(String sname) {
49         this.sname = sname;
50     }
51 
52     public int getAge() {
53         return age;
54     }
55 
56     public void setAge(int age) {
57         this.age = age;
58     }
59 
60     public String getPwd() {
61         return pwd;
62     }
63 
64     public void setPwd(String pwd) {
65         this.pwd = pwd;
66     }
67     
68 
69 }
Student.java

 

4.在com.dao包下创建BaseDao.java

package com.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * 链接数据库的工具类
 * @author Holly老师
 */
public class BaseDao {
    /**链接数据库的字符串*/
    private static final String driver="oracle.jdbc.driver.OracleDriver";
    private static final String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
    private static final String user="holly";
    private static final String password="sys";
    /**数据库操作的对象*/
    public Connection conn=null;
    public PreparedStatement pstm=null;
    public ResultSet rs=null;
    /**
     * 加载驱动
     */
    static{
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 获取数据库链接
     * @return
     */
    public Connection getConnection(){
        try {
            conn=DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;
    }
    
    /**
     * 查询公共方法
     * @param sql
     * @param param
     * @return
     */
    public ResultSet executeQuery(String sql,Object[] param){
        conn=this.getConnection();
        try {
            pstm=conn.prepareStatement(sql);
            if(param!=null){
                for (int i = 0; i < param.length; i++) {
                    pstm.setObject(i+1, param[i]);
                }
            }
            rs=pstm.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return rs;
    }
    /**
     * 增删改通用方法
     * @param sql
     * @param param
     * @return
     */
    public int executeUpdate(String sql,Object[] param){
        conn=this.getConnection();
        int num=0;
        try {
            pstm=conn.prepareStatement(sql);
            if(param!=null){
                for (int i = 0; i < param.length; i++) {
                    pstm.setObject(i+1, param[i]);
                }
            }
            num=pstm.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            this.closeAll(conn, pstm, rs);
        }
        return num;
    }
    /**
     * 释放资源
     * @param conn
     * @param pstm
     * @param rs
     */
    public void closeAll(Connection conn,PreparedStatement pstm,ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(pstm!=null){
                pstm.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
BaseDao.java

 

5.在com.dao包下创建StudentDao.java

 1 package com.dao;
 2 
 3 
 4 import com.javabean.Student;
 5 /**
 6  * 
 7  * @author Holly老师
 8  *
 9  */
10 public interface StudentDao {
11     /**
12      * 根据用户名和密码查询
13      * @param sname
14      * @param pwd
15      * @return
16      */
17     Student getByNameAndPwd(String sname,String pwd);
18 
19 }
StudentDao.java

 

6.在com.dao.impl包下创建StudentDaoImpl.java

 1 package com.dao.impl;
 2 
 3 import java.sql.SQLException;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 import com.dao.BaseDao;
 8 import com.dao.StudentDao;
 9 import com.javabean.Student;
10 /**
11  * 
12  * @author Holly老师
13  *
14  */
15 public class StudentDaoImpl extends BaseDao implements StudentDao {
16     /**
17      * 根据用户名和密码查询
18      * @param sname
19      * @param pwd
20      * @return
21      */
22     public Student getByNameAndPwd(String sname,String pwd) {
23         Student stu=null;
24         String sql="select * from student where sname=? and pwd=?";
25         
26         Object[] param={sname,pwd};
27         rs=this.executeQuery(sql, param);
28         try {
29             while(rs.next()){
30                 stu=new Student(
31                         rs.getInt("sid"),
32                         rs.getString("sname"),
33                         rs.getString("pwd"),
34                         rs.getInt("age"));
35             }
36         } catch (SQLException e) {
37             e.printStackTrace();
38         }finally{
39             this.closeAll(conn, pstm, rs);
40         }
41         return stu;
42     }
43 
44     
45 
46 }
StudentDaoImpl.java

 

7.在com.service包下创建StudentService.java

package com.service;

import com.javabean.Student;
/**
 * 服务器接口
 * @author Holly老师
 *
 */
public interface StudentService {
    Student loginUser(String name,String pwd);

}
StudentService.java

 

8.在com.service包下创建StudentServiceImp.java

package com.service.impl;

import com.dao.StudentDao;
import com.dao.impl.StudentDaoImpl;
import com.javabean.Student;
import com.service.StudentService;
/**
 * 
 * @author Holly老师
 *
 */
public class StudentServiceImpl implements StudentService{
    StudentDao dao=new StudentDaoImpl();
    
    public Student loginUser(String name, String pwd) {
        return dao.getByNameAndPwd(name, pwd);
    } 
    

}
StudentServiceImp.java

 

9.在src下创建mystruts.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mystruts[
    <!ELEMENT mystruts (actions)>
    <!ELEMENT actions (action*)>
    <!ELEMENT action (result*)>
    <!ATTLIST action
      name CDATA #REQUIRED
      class CDATA #REQUIRED
    >
    <!ELEMENT result (#PCDATA)>
    <!ATTLIST result
      name CDATA #IMPLIED
      redirect (true|false) "false" 
    >
]>
<mystruts>
  <actions>
    <!-- 登录 -->
    <action name="login" class="com.action.LoginAction">
      <result name="success">page/index.jsp</result>
      <result name="input">page/login.jsp</result>
    </action>
    
    <!-- 注册 -->
    <action name="register" class="com.action.RegisterAction">
      <result name="success">page/login.jsp</result>
      <result name="input">page/register.jsp</result>
    </action>
  </actions>
</mystruts>


<!-- 
  (1) 声明DTD:<!doctype 根元素 [定义内容]>
  (2)定义DTD元素标签节点 :<!ELEMENT 标签名称 元素类型>
  (3)定义DTD元素标签属性:<!ATTLIST 元素名称 属性名称 属性类型 属性默认值> 
  
  ELEMENT 定义标签节点
  ATTLIST 定义标签的属性
  CDATA 表示属性类型是字符数据
  #REQUIRED 属性值是必须的
  #IMPLIED 属性值不是必须的
  #FIXED 属性值是固定的
  ()给元素分组
  A|B 必须选择A或B
  A,B A和B按顺序出现 
  A* A出现0到n次
  A? A出现0到1次
  A+ A出现一次或n次
  

 -->
mystruts.xml

 

10.在com.action包下创建Action.java

 1 package com.action;
 2 
 3 import javax.servlet.http.HttpServletRequest;
 4 import javax.servlet.http.HttpServletResponse;
 5 /**
 6  * 
 7  * @author Holly老师
 8  *
 9  */
10 public interface Action {
11     /**
12      * 返回处理结果
13      * @param request 请求
14      * @param response  响应
15      * @return 失败或成功页面的字符串
16      * @throws Exception
17      */
18     String execute(HttpServletRequest request,
19             HttpServletResponse response) throws Exception;
20 
21 }
Action.java

 

11.在com.action包下创建LoginAction.java

package com.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.javabean.Student;
import com.service.StudentService;
import com.service.impl.StudentServiceImpl;
/**
 * 
 * @author Holly老师
 *
 */
public class LoginAction implements Action {
    /**
     * 处理请求返回处理结果
     */
    public String execute(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        //1.处理乱码
        request.setCharacterEncoding("UTF-8");  
        response.setCharacterEncoding("UTF-8");  
        response.setContentType("text/html;charset=UTF-8");
        
        //2.获取请求中的参数
        String name=request.getParameter("user");
        String pwd=request.getParameter("pwd");
        
        //3.业务处理
        StudentService service=new StudentServiceImpl();
        Student stu=service.loginUser(name, pwd);
        
        //4.业务判断
        if(stu!=null){
            HttpSession session=request.getSession();
            session.setAttribute("stu", stu);
            return "success";
        }else{
            return "input";
        }
    }

}
LoginAction.java

 

12.在com.mapper包下创建ActionMapping.java

package com.mapper;

import java.util.HashMap;
import java.util.Map;

/**
 * Action节点的映射类
 * @author Holly老师
 *
 */
public class ActionMapping {
    /**action节点的name属性*/
    private String name;
    
    /**action节点的class属性*/
    private String className;
    
    /**保存配置的result属性*/
    private Map<String,String> resultMap=new HashMap<String,String>();

    /**
     * 通过result-name属性,返回对应的某个result节点
     * @param name
     * @return
     */
    public String getResult(String name){
        return resultMap.get(name);
    }
    /**
     *在Map添加result节点=一个view*/
    public void addResult(String name,String result){
        this.resultMap.put(name, result);
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public Map<String, String> getResultMap() {
        return resultMap;
    }

    public void setResultMap(Map<String, String> resultMap) {
        this.resultMap = resultMap;
    }
    
    

}
Mapping.java

 

13.在com.mapper包下创建

package com.mapper;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * Action的管理类
 * @author Holly老师
 *
 */
public class ActionMappingManager {
    /**map里放入多个action节点,key是action的name属性值,
     * value是整个的action节点,也就是action映射类ActionMapping*/
    private static Map<String,ActionMapping> actionMappings
           =new HashMap<String,ActionMapping>();
    
    /**
     * init方法加载action的配置信息
     * @param configureFileName  配置文件的名字
     */
    public void init(String configureFileName){
       try {
          if(configureFileName==null ||configureFileName.isEmpty()){
               throw new Exception("configureFileName为空");
           }
          
          //1.获取配置文件信息
          InputStream is=this.getClass().getResourceAsStream("/"+configureFileName);
          
          //2.读取xml文件内容
          Document doc=new SAXReader().read(is);
          
          //3.获取xml文件的根节点
          Element root=doc.getRootElement();
          
          //4.获取根节点mystrusts的下的所有actions节点
          Iterator<Element> actionsIt=root.elements("actions").iterator();
          
          //5.获取第一个actions节点
          Element actions=actionsIt.next();
          
          //6.获取actions下的所有action节点
          Iterator<Element> actionIt=actions.elementIterator("action");
          
          //7.循环取出action
          while(actionIt.hasNext()){
              //取出下一个action
              Element action=actionIt.next();
              
              //创建action对应映射类ActionMapping对象
              ActionMapping mapping=new ActionMapping();
              
              //将action节点的name属性值赋值给ActionMapping映射类的name属性
              mapping.setName(action.attributeValue("name"));
              
              //将action节点的class属性值赋值给ActionMapping映射类的className属性
              mapping.setClassName(action.attributeValue("class"));
              
              //获取action节点下所有的result集合
              Iterator<Element> resultIt=action.elementIterator("result");
              
              //循环取得result节点内容
              while(resultIt.hasNext()){
                  //取得下一个result节点
                  Element resultElement=resultIt.next();
                  
                  //获取result节点上的name属性值
                  String name=resultElement.attributeValue("name");
                  
                  //获取result开始标签和结束标签之间的文本=跳转的页面地址
                  String result=resultElement.getText();
                  
                  if(name==null ||name.equals("")){
                      name="success";
                  }
                  //在我们映射类里添加result节点
                  mapping.addResult(name, result);
              }
              //把整个action节点添加到action管理类的集合中
              actionMappings.put(mapping.getName(), mapping);
          }
      } catch (Exception e) {
                e.printStackTrace();
      }        
    }
    /**
     * 通过构造方法来加载Action配置文件
     * @param 配置文件名数组
     */
    public ActionMappingManager(String[] configureFileNames){
        for (String configureFileName : configureFileNames) {
            init(configureFileName);
        }
    }
    
    /**
     * 根据actionName查询对应的ActionMapping实例
     * @param actionName
     * @return
     * @throws Exception 
     */
    public ActionMapping getActionMappingByName(String actionName) throws Exception{
        if(actionName==null || actionName.isEmpty()){
            return null;
        }
        ActionMapping mapping=this.actionMappings.get(actionName);
        if(mapping==null){
            throw new Exception("mapping为空:["+actionName+"]");
        }
        return mapping;
        
    }
    
    
    public static Map<String, ActionMapping> getActionMappings() {
        return actionMappings;
    }

    public static void setActionMappings(Map<String, ActionMapping> actionMappings) {
        ActionMappingManager.actionMappings = actionMappings;
    }
    
 
}
ActionMappingManager.java

 

14.在com.action包下创建ActionManager.java

package com.action;
/**
 * 通过反射获取某个Action的实例/对象
 * @author Holly老师
 *
 */
public class ActionManager {
    /**
     * 通过反射获取Class对象
     * @param className action的名字
     * @return Class对象
     * @throws ClassNotFoundException
     */
    public static Class loadClass(String className) throws ClassNotFoundException{
        Class clazz=null;
        //通过反射Class对象
        clazz=Class.forName(className);
        return clazz;
    }
    
    /**
     * 用来动态获取Action类对象
     * @param className  Action的名字
     * @return
     */
    public static Action createAction(String className){
        try {
            //通过class对象动态创建对象
            return (Action) loadClass(className).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

}
ActionManager.java

 

15.在com.filter包下创建ActionFilter.java

package com.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.action.Action;
import com.action.ActionManager;
import com.action.LoginAction;
import com.mapper.ActionMapping;
import com.mapper.ActionMappingManager;
/**
 * 
 * @author Holly老师
 *
 */
public class ActionFilter implements Filter {
    //定义储存拦截器初始化参数的成员变量
    private FilterConfig config=null;
    
    //创建action映射文件管理类对象
    private ActionMappingManager mappingManager=null;
    
    /**资源回收*/
    public void destroy() {}
    
    /**初始化方法:获取拦截器的参数*/
    public void init(FilterConfig conf) throws ServletException {
        this.config=conf;
        //获取xml文件中的参数值,:mystruts.xml
        String conStr=config.getInitParameter("config");
        String[] configFiles=null;
        if(conStr==null || conStr.isEmpty()){
            configFiles=new String[]{"mystruts.xml"};
        }else{
            //拆分配置文件名称字符串
            configFiles=conStr.split(",");
        }
        //向多个action管理类的构造中传入xml文件的名
        mappingManager=new ActionMappingManager(configFiles);
        
            
    }
    
    /**过滤请求*/ 
    public void doFilter(ServletRequest sr, ServletResponse sp,
            FilterChain chain) throws IOException, ServletException {
        //1.获取request和response对象
        HttpServletRequest request=(HttpServletRequest) sr;
        HttpServletResponse response=(HttpServletResponse) sp;
        
        try {
            //获取整个action节点
            ActionMapping mapping=this.getActionMapping(request);
            
            //通过反射获取Action对象
            Action action=ActionManager.createAction(mapping.getClassName());
            
            //获取action类里处理请求返回的字符串,result的name属性,success或fail等
            String resultName=action.execute(request, response);
            
            //通过返回的reuslt的name属性值获取result开始标签和结束标签之间的文本,跳转的页面
            String result=mapping.getResult(resultName);
            if(result==null){
                return;
            }
            
            //页面跳转(重定向)
            response.sendRedirect(result);
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
    /**
     * 获取不同的Action
     * @return
     * @throws Exception 
     */
    public ActionMapping getActionMapping(HttpServletRequest request) throws Exception {
        //1.获取请求的uri地址:项目名/Xxx.action
        String uri=request.getRequestURI();
        
        //2.获取上下文路径:项目名
        String contextpath=request.getContextPath();
        
        //3.获取Xxx.action,从某个位置截取到最后
        String actionPath=uri.substring(contextpath.length());
        
        //4.获取Action的名字:Xxx
        String actionName=actionPath.substring(1,
                actionPath.lastIndexOf('.')).trim();
        
        //5.获取某个Action的name属性值key获取整个acton类节点对象
        ActionMapping mapping=null;
        mapping=mappingManager.getActionMappingByName(actionName);
        
        return mapping;
    }

    

}
ActionFilter.java

 

16.在WebRoot下WEB-INF下编辑web.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7   <welcome-file-list>
 8     <welcome-file>page/login.jsp</welcome-file>
 9   </welcome-file-list>
10   <filter>
11     <filter-name>requestFilter</filter-name>
12     <!-- 拦截器的类路径 -->
13     <filter-class>com.filter.ActionFilter</filter-class>
14     <init-param>
15        <param-name>config</param-name>
16        <param-value>mystruts.xml</param-value>
17     </init-param>
18   </filter>
19   
20   <filter-mapping>
21     <filter-name>requestFilter</filter-name>
22     <!-- 拦截所有以.action结尾的请求 -->
23     <url-pattern>*.action</url-pattern>
24   </filter-mapping>
25 </web-app>
web.xml

 

17.在WebRoot下创建page文件夹并编辑login.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%
 3     String path = request.getContextPath();
 4     String basePath = request.getScheme() + "://"
 5             + request.getServerName() + ":" + request.getServerPort()
 6             + path + "/";
 7 %>
 8 
 9 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
10 <html>
11     <head>
12         <base href="<%=basePath%>">
13 
14         <title>My JSP 'index.jsp' starting page</title>
15         <meta http-equiv="pragma" content="no-cache">
16         <meta http-equiv="cache-control" content="no-cache">
17         <meta http-equiv="expires" content="0">
18         <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
19         <meta http-equiv="description" content="This is my page">
20         <!--
21     <link rel="stylesheet" type="text/css" href="styles.css">
22     -->
23     </head>
24 
25     <body>
26         <fieldset style="width: 400px">
27             <legend>
28                 登录
29             </legend>
30             <form action="login.action" method="post">
31                 <table>
32                     <tr>
33                         <td>
34                             用户名:
35                         </td>
36                         <td>
37                             <input type="text" name="user" />
38                         </td>
39                     </tr>
40                     <tr>
41                         <td>
42                             密码:
43                         </td>
44                         <td>
45                             <input type="password" name="pwd" />
46                         </td>
47                     </tr>
48                     <tr>
49                         <td>
50                             <input type="submit" value="登录" />
51                         </td>
52                         <td>
53                             <input type="reset" value="重置" />
54                         </td>
55                     </tr>
56 
57                 </table>
58             </form>
59         </fieldset>
60     </body>
61 </html>
login.jsp

 

18.在WebRoot下创建page文件夹并编辑index.jsp

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%
 3 String path = request.getContextPath();
 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
 5 %>
 6 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 7 <html>
 8   <head>
 9     <base href="<%=basePath%>">
10     
11     <title>My JSP 'index.jsp' starting page</title>
12     <meta http-equiv="pragma" content="no-cache">
13     <meta http-equiv="cache-control" content="no-cache">
14     <meta http-equiv="expires" content="0">    
15     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
16     <meta http-equiv="description" content="This is my page">
17     <!--
18     <link rel="stylesheet" type="text/css" href="styles.css">
19     -->
20   </head>
21   
22   <body>
23      欢迎${stu.sname}登录首页!
24   </body>
25 </html>
index.jsp


19.写完了

自己测试一下

posted @ 2016-05-16 12:32  红酒人生  阅读(725)  评论(0编辑  收藏  举报