自定義MVC框架(二),自定義mvc框架
1.oracle的腳本
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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)
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294281.jpg)
3.在com.javabean包下創建Student.java文件
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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文件
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
<?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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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包下創建
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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文件
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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 >
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
![](https://www.aspphp.online/bianchen/UploadFiles_4619/201701/2017011814294215.gif)
![]()
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.寫完了
自己測試一下