你的位置:首页 > Java教程

[Java教程]自定义MVC框架(二)


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 sname14    * @param pwd15    * @return16   */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 sname19    * @param pwd20    * @return21   */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.

<??><!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.

 

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 Exception17   */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包下创建Action

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.读取     Document doc=new SAXReader().read(is);          //3.获取     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;    //获取    String conStr=config.getInitParameter("config");    String[] configFiles=null;    if(conStr==null || conStr.isEmpty()){      configFiles=new String[]{"mystruts.};    }else{      //拆分配置文件名称字符串      configFiles=conStr.split(",");    }    //向多个action管理类的构造中传入    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.

 1 <??> 2 <web-app version="2.5"  3   ="http://java.sun.com/  4   ="http://www.w3.org/2001/  5   xsi:schemaLocation="http://java.sun.com/ 6   http://java.sun.com/> 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.</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.

 

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.写完了

自己测试一下