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

1.oracle的脚本

 create table STUDENT
(
sid NUMBER primary key,
sname VARCHAR2(20),
age NUMBER,
pwd VARCHAR2(20)
) create sequence seq_student; insert into STUDENT (sid, sname, age, pwd)
values (seq_student.nextval, 'holly', 18, '');
insert into STUDENT (sid, sname, age, pwd)
values (seq_student.nextval, '钱涛', 108, '');
insert into STUDENT (sid, sname, age, pwd)
values (seq_student.nextval, '张睿', 10, '');
insert into STUDENT (sid, sname, age, pwd)
values (seq_student.nextval, '修地', 16, '');
commit;

student.sql

2.创建如下的项目结果

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

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

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

 package com.javabean;
/**
* 学生类
* @author Holly老师
*
*/
public class Student {
/*学生编号*/
private int sid;
/*学生姓名*/
private String sname;
/*学生密码*/
private String pwd;
/*年龄*/
private int age; public Student() {
super();
} public Student(int sid, String sname, String pwd, int age) {
super();
this.sid = sid;
this.sname = sname;
this.pwd = pwd;
this.age = age;
} public Student(int sid, String sname, int age) {
super();
this.sid = sid;
this.sname = sname;
this.age = age;
} public int getSid() {
return sid;
} public void setSid(int sid) {
this.sid = sid;
} public String getSname() {
return sname;
} public void setSname(String sname) {
this.sname = sname;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public String getPwd() {
return pwd;
} public void setPwd(String pwd) {
this.pwd = pwd;
} }

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

 package com.dao;

 import com.javabean.Student;
/**
*
* @author Holly老师
*
*/
public interface StudentDao {
/**
* 根据用户名和密码查询
* @param sname
* @param pwd
* @return
*/
Student getByNameAndPwd(String sname,String pwd); }

StudentDao.java

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

 package com.dao.impl;

 import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import com.dao.BaseDao;
import com.dao.StudentDao;
import com.javabean.Student;
/**
*
* @author Holly老师
*
*/
public class StudentDaoImpl extends BaseDao implements StudentDao {
/**
* 根据用户名和密码查询
* @param sname
* @param pwd
* @return
*/
public Student getByNameAndPwd(String sname,String pwd) {
Student stu=null;
String sql="select * from student where sname=? and pwd=?"; Object[] param={sname,pwd};
rs=this.executeQuery(sql, param);
try {
while(rs.next()){
stu=new Student(
rs.getInt("sid"),
rs.getString("sname"),
rs.getString("pwd"),
rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.closeAll(conn, pstm, rs);
}
return stu;
} }

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

 package com.action;

 import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Holly老师
*
*/
public interface Action {
/**
* 返回处理结果
* @param request 请求
* @param response 响应
* @return 失败或成功页面的字符串
* @throws Exception
*/
String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception; }

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文件

 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>page/login.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>requestFilter</filter-name>
<!-- 拦截器的类路径 -->
<filter-class>com.filter.ActionFilter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>mystruts.xml</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>requestFilter</filter-name>
<!-- 拦截所有以.action结尾的请求 -->
<url-pattern>*.action</url-pattern>
</filter-mapping>
</web-app>

web.xml

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

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
<fieldset style="width: 400px">
<legend>
登录
</legend>
<form action="login.action" method="post">
<table>
<tr>
<td>
用户名:
</td>
<td>
<input type="text" name="user" />
</td>
</tr>
<tr>
<td>
密码:
</td>
<td>
<input type="password" name="pwd" />
</td>
</tr>
<tr>
<td>
<input type="submit" value="登录" />
</td>
<td>
<input type="reset" value="重置" />
</td>
</tr> </table>
</form>
</fieldset>
</body>
</html>

login.jsp

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

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head> <body>
欢迎${stu.sname}登录首页!
</body>
</html>

index.jsp

19.写完了

自己测试一下

上一篇:html5属性placeholder的js 向下兼容支持(jquery版)


下一篇:PHP简单语法