第一章 自定义MVC框架
第一章 自定义MVC框架
1.1 MVC模式设计
组成;Model:模型,用于数据和业务的处理
View :视图,用于数据的显示
Controller:控制器,用于进行流程控制
特点:1.一个模型可以对应多个视图
2.显示与逻辑控制的分离
3.分层控制,减低了代码间的耦合
1.2 DTD验证XML文档
声明:<!DOCTYPE 根元素 [定义内容]>
例:<!DOCTYPE poem [
<!ELEMENT poem (author,title,content)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT content (#PCDATA)>
]>
<peom>
<author>王维</author>
<title>鹿柴</title>
<content>空山不见人,但闻人语声。返景入深林,复照青苔上</content>
</peom>
使用外部DTD验证XML
myStruts.dtd:
<!ELEMENT poems (poem*)>
<!ELEMENT poem (title,author,year,content)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT year (#PCDATA)>
<!ELEMENT content (#PCDATA)>
myMvc.xml:
<!DOCTYPE poems SYSTEM "myStruts.dtd">
<poems>
<poem>
<title>春晓</title>
<author>孟浩然</author>
<content>春眠不觉晓......</content>
</poem>
</poems>
DTD元素
<!ELEMENT name CONTENT>
ELEMENT:关键字
name:元素名称
CONTENT:元素类型
#PCDATA:任何字符数据,不能在其中包含任何子元素
纯元素类型:只包含子元素,且这些子元素外没有文本
符号:():表示分成几组
| :必须选其一
,:按顺序出现
* :可以出现0到多次
?:可出现也可不出现,出现且只有一次
+ :必须出现,且可以出现多次
DTD属性
<!ATTLIST 元素名称 属性名称 属性类型 属性默认值>
属性类型描述:
CDATA:字符数据
ID:唯一ID
IDREFS:另一个ID
ENTITY:实体
ENTITIES:实体列表
属性值描述:
#REQUIRED:属性值是必须的
#IMPLIED:属性值不是必须的
#FIXED:属性值是固定的
例:<!DOCTYPE mystruts[
<!ELEMENT mystruts (actions)>
<!ELEMENT actions (action*)>
<!ELEMENT action (result*)>
<!ATTLIST auction
name CDATA #REQUIRED
CLASS CDATA #REQUIRED>
<!ATTLIST result
name CDATA #IMPLIED
redirect (true|false) "false">
]>
<mystruts>
<actions>
<action name="register" class="cn.jbit.action.RegisterAction">
<result name="success">page/login.jsp</result>
<result name="input">page/register.jsp</result>
</action>
<action name="login" class="cn.jbit.mvc.LoginAction">
<result name="success">page/guanli.jsp</result>
<result name="input">page/login.jsp</result>
</action>
</actions>
</mystruts>
1.3 XML文档解析
获取root节点 ELement root
1、获取节点名称 root.getName()
2、获取节点属性 root.attribute("dname")
3、获取节点中的text root.getText()
4、获取子节点
使用DOM4J操作XML数据(如:dom4j-1.6.1.jar)
例:student.xml:
<?xml version="1.0" encoding="gb2312"?>
<students>
<student age="31"><!-- 如果没有固定的age 默认为20 -->
<name>崔卫兵</name>
<college>pc学院</college>
<telephone>6234666</telephone>
<notes>男,1985年出生,硕士</notes>
</student>
<student>
<name>张洪泽</name>
<!-- 如果没有固定的leader 默认为leader -->
<college leader="Leader">pc学院</college>
<telephone>6238888</telephone>
<notes>男,1987年出生,硕士</notes>
</student>
</students>
Dom4jReadExmple.java:
public class Dom4jReadExmple {
public void iterateWholeXML(String filename,HashMap<String,String> hm){
SAXReader saxReader=new SAXReader();
try {
Document document=saxReader.read(new File(filename));
Element root=document.getRootElement();
int num=-1;//记录学生编号的变量
//遍历根元素(students)的所有子节点(student)
for(Iterator iter=root.elementIterator();iter.hasNext();){
Element element=(Element) iter.next();
num++;
//获取person节点的age属性
Attribute ageAttribute=element.attribute("age");
if(ageAttribute!=null){
String age=ageAttribute.getValue();
if(age!=null && !age.equals("")){
hm.put(element.getName()+"-"+ageAttribute.getName()+num, age);
}else{
hm.put(element.getName()+"-"+ageAttribute.getName()+num, "20");
}
}else{
hm.put(element.getName()+"-age"+num, "20");
}
//遍历student节点下的所有子节点(name,college,telephone,notes)
for(Iterator iterInner=element.elementIterator();iterInner.hasNext();){
Element elementInner=(Element) iterInner.next();
if(elementInner.getName().equals("college")){
hm.put(elementInner.getName()+num,elementInner.getText());
//获取college节点的leader属性
Attribute leaderAttr=elementInner.attribute("leader");
if(leaderAttr!=null){
String leader=leaderAttr.getValue();
if(leader!=null && !leader.equals("")){
hm.put(elementInner.getName()+"-"+leaderAttr.getName()+num,leader);
}else{
hm.put(elementInner.getName()+"-"+leaderAttr.getName()+num,"leader");
}
}else{
hm.put(elementInner.getName()+"-leader"+num, "leader");
}
}else{
hm.put(elementInner.getName()+num, elementInner.getText());
}
}
}
} catch (DocumentException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
TestDom4jReadExmple.java:
public class TestDom4jReadExmple {
public static void main(String[] args) {
try {
//获取解析后的解析信息
HashMap<String, String> hashMap;
Dom4jReadExmple dre=new Dom4jReadExmple();
//遍历xml文件
hashMap=new HashMap<String, String>();
String n=System.getProperty("user.dir");
//获取xml文件
dre.iterateWholeXML(n+"\\src\\cn\\jbit\\action\\Student.xml", hashMap);
for (int i = 0; i < hashMap.size(); i++) {
int j=i/6;
System.out.print(hashMap.get("name"+j)+"\t");
System.out.print(hashMap.get("student-age"+j)+"\t");
System.out.print(hashMap.get("college"+j)+"\t");
System.out.print(hashMap.get("college-leader"+j)+"\t");
System.out.print(hashMap.get("telephone"+j)+"\t");
System.out.println(hashMap.get("notes"+j)+"\t");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果:崔卫兵 31 pc学院 leader 6234666 男,1985年出生,硕士
张洪泽 20 pc学院 Leader 6238888 男,1987年出生,硕士
关键操作如下:
1、Document对象相关
SAXReader saxReader=new SAXReader();
Document document=saxReader.read(new File("index.xml"));
2、节点相关
1、获取文档的根节点
Element root=document.getRootElement();
2、获取某节点的单个子节点
Element meberElm=root.element("Member");
3、取得节点的文字
String text=MemberElm.getText();
4、取得某节点下名为:Member的所有子节点并进行遍历
List nodes=rootElm.elements("Member");
5、对某节点下的所有子节点进行遍历
for(Iterator iterInner=element.elementIterator();iterInner.hasNext();){
Element elementInner=(Element) iterInner.next();
//...
}
6、在某节点下添加子节点
Element ageElm=newMemberElm.addElement("age");
7、设置节点文字
ageElm.setText("19");
8、删除某节点
parentElm.remove(childElm);//childElm是待删除的节点,parentElm是父节点
9、添加一个CDATA节点
Element contentElm=infoElm.addElement(content);
contentElm.addCDATA(diary.getContent());
contentElm.getText();
contentElm.clearContent();
3、属性相关
1、取得某节点下的属性
Element root=document.getRootElement();
Attribute ageAttribute=root.attribute("age");
2、取得属性的文字
String text=ageAttribute.getText();
3、遍历某节点的所有属性
Element root=document.getRootElement();
for(Iterator it=root.elementIterator();it.hasNext();){
Attribute attribute=(Attrinute) it.next();
String text=ageAttribute.getText();
System.out.print(text);
}
4、设置某节点的属性和文字
newMemberElm.addAttribute("name","sitinspring');
5、设置属性的文字
Attribute attribute=root.attribute("age");
attribute.setText("sitinspring");
1.4 反射机制
反射的3个动态性质
1.运行时伸出对象实例
2.运行期间调用对象
3.运行时更改对象
反射常用API
Class类:反射核心类
Field类:类的属性
Method类:类的方法
Constructor类:类的构造方法
使用反射的步骤
1、导入jar包
2、获得需要操作的类的java.lang.CLass对象
3、调用Class的方法获取Field、Method等对象
4、使用反射API进行操作
反射的应用
1、获取Class对象
例;
Class clazz=Class.forName("java.lang.String");//正确
Class clazz=Class.forName("String");//错误
2、从Class对象获取信息
访问类信息的常用方法
Constructor[] getConstructors()//返回所表示的类的public构造方法
Constructor[] getDeclaredConstructors()//返回所表示的类的构造方法
Method [] getMethods()//返回所表示的类的public方法
Method [] getDeclaredMethods()//返回所表示的类的全部方法
Field[] getFields()//返回所表示的类的public属性
field[] getDeclaredFields()//返回所表示的类的全部属性
Object get(Object obj)//得到引用类属性值
void set(Object obj,Object val)//将Obj对象的属性设置val值,针对引用类型
Object invoke(Object obj,Object args)//调用类的方法obj是执行方法的对象,args是执行方法时传入的参数
3、创建对象
newInstance():
例:Object retBean=defaultCtor.newInstance();
1.5 构建基于MVC模式的框架(Controller为MVC的核心)
1.5.1、Controller的设计
1、定义Action接口
public interface Action {
public String execute(HttpServletRequest request,HttpServletResponse response)throws Exception;
}
实现接口:
public class LoginAction implements Action {
@Override
public String execute(HttpServletRequest request,
HttpServletResponse response) throws Exception {
String name=request.getParameter("name");
String password=request.getParameter("password");
//业务处理
UserBiz userBiz=new UserBizImpl();
User user=userBiz.login(name,password);
//判断是否登录成功
if(user==null){
request.setAttribute("message","用户名或密码错误!");
return "/page/login.jsp";
}else{
request.getSession().setAttribute("login", user);
return "/page/guanli.jsp";
}
return null;
}
}
2、实现Controller类
public class ActionFilter implements Filter {
private FilterConfig config;
private ActionMappingManager mappingManager;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//将请求装换成HttpServletRequest
HttpServletRequest hsr=(HttpServletRequest) request;
HttpServletResponse hsp=(HttpServletResponse) response;
//调用Action的execute方法
Action action=this.getAction(hsr);
String resultView=null;
try {
resultView=action.execute(hsr, hsp);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
//页面跳转
if(resultView!=null){
request.getRequestDispatcher(resultView).forward(request, response);
}
}
@Override
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[]{"myMvc.xml"};
}else{
//拆分配置文件名称字符串
configFiles=conStr.split(",");
}
this.mappingManager=new ActionMappingManager(configFiles);
}
private Action getAction(HttpServletRequest request) {
//获取请求的uri
String uri = request.getRequestURI();
//获取上下文路径
String contextPath=request.getContextPath();
//截取上下文路劲后面的部分
String actionPath=uri.substring(contextPath.length());
//获取Action名称
String actionName=actionPath.substring(1,actionPath.lastIndexOf(".")).trim();
Action action=null;
//添加新功能时在这里添加
if("login".equals(actionName)){
action=new LoginAction();
}
return null;
}
}
web.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
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_3_0.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>requestFilter</filter-name>
<filter-class>cn.jbit.mvc.ActionFIlter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
</web-app>
1.6 升级Controller控制器
1、配置文件
myStruts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mystruts[
<!ELEMENT mystruts (actions)>
<!ELEMENT actions (action*)>
<!ELEMENT action (result*)>
<!ATTLIST auction
name CDATA #REQUIRED
CLASS CDATA #REQUIRED>
<!ATTLIST result
name CDATA #IMPLIED
redirect (true|false) "false">
]>
<mystruts>
<actions>
<action name="register" class="cn.jbit.action.RegisterAction">
<result name="success">page/login.jsp</result>
<result name="input">page/register.jsp</result>
</action>
<action name="login" class="cn.jbit.mvc.LoginAction">
<result name="success">page/guanli.jsp</result>
<result name="input">page/login.jsp</result>
</action>
</actions>
</mystruts>
2、保存Action信息
public class ActionMapping {
//action元素的name属性
private String name;
//action元素的className属性
private String className;
//保存配置爱的result属性信息
private Map<String, String > resultMap=new HashMap<String, String>();
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;
}
/*
* 根据result-name返回Result实例
*/
public String getResult(String name,String result){
return resultMap.get(name);
}
public String getResult(String name){
return resultMap.get(name);
}
/*
* 向Map中添加一个View
*/
public void addResult(String name,String result){
this.resultMap.put(name, result);
}
}
3、读取配置文件
public class ActionMappingManager {
//保存所有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为空");
}
InputStream is=this.getClass().getResourceAsStream("/"+configureFileName);
Document doc=new SAXReader().read(is);
Element root=doc.getRootElement();
Iterator<Element> actionsIt=root.elements("actions").iterator();
Element actions =actionsIt.next();
for(Iterator<Element> actionIt=actions.elementIterator("action");actionIt.hasNext();){
Element action=actionIt.next();
ActionMapping mapping=new ActionMapping();
mapping.setName(action.attributeValue("name"));
mapping.setClassName(action.attributeValue("class"));
for(Iterator<Element> resultIt=action.elementIterator("result");resultIt.hasNext();){
Element resultElement=resultIt.next();
String name=resultElement.attributeValue("name");
String result=resultElement.getText();
if(name==null || "".equals(name)){
name="success";
}
mapping.addResult(name, result);
}
actionMappings.put(mapping.getName(), mapping);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* 加载Action配置文件
* @param configureFileNames 配置文件名的数组
*/
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;
}
}
4、反射生成Action
public class ActionManager {
public static Action createAction(String className)throws Exception{
try {
return (Action)loadClass(className).newInstance();
}catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (InstantiationException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
private static Class loadClass(String className) throws ClassNotFoundException {
Class clazz=null;
clazz=Class.forName(className);
return clazz;
}
}
5、完善Controller
web.xml:
<filter>
<display-name>requestFilter</display-name>
<filter-name>requestFilter</filter-name>
<filter-class>cn.jbit.mvc.ActionFIlter</filter-class>
<init-param>
<param-name>config</param-name>
<param-value>myMvc.xml</param-value>
</init-param>
</filter>
ActionFilter.java修改:
public class ActionFilter implements Filter {
private FilterConfig config;
private ActionMappingManager mappingManager;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//将请求装换成HttpServletRequest
HttpServletRequest hsr=(HttpServletRequest) request;
HttpServletResponse hsp=(HttpServletResponse) response;
try {
ActionMapping mapping=this.getActionMapping(hsr);
Action action=ActionManager.createAction(mapping.getName());
//得到结果的逻辑名
String resultName=action.execute(hsr, hsp);
//根据逻辑名返回实际跳转的视图名,也就是跳转的路径
String result=mapping.getResult(resultName);
if(result==null){
return;
}
//页面跳转
hsp.sendRedirect(result);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
@Override
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[]{"myMvc.xml"};
}else{
//拆分配置文件名称字符串
configFiles=conStr.split(",");
}
this.mappingManager=new ActionMappingManager(configFiles);
}
private ActionMapping getActionMapping(HttpServletRequest request) throws Exception {
//获取请求路径
String uri=((HttpServletRequest)request).getRequestURI();
String contextPath=((HttpServletRequest)request).getContextPath();
//截取上下文路劲后面的部分
String actionPath=uri.substring(contextPath.length());
//获取Action名称
String actionName=actionPath.substring(1,actionPath.lastIndexOf(".")).trim();
ActionMapping mapping=null;
mapping=mappingManager.getActionMappingByName(actionName);
return mapping;
}
}
转载于:https://www.cnblogs.com/luobailin/p/6093116.html
第一章 自定义MVC框架相关推荐
- 第一章 Web MVC简介 —— 跟开涛学SpringMVC
第一章 Web MVC简介 -- 跟开涛学SpringMVC Web MVC简介 1.1.Web开发中的请求-响应模型: 在Web世界里,具体步骤如下: 1. Web浏览器(如IE)发起请求,如访问 ...
- PHP笔记-自定义MVC框架
膜拜 膜拜下黑马大佬程序员的项目,学习到了这样的手写MVC框架的方式,受益匪浅,感觉自己在C/C++和Java方面,还有许多要学习的地方,看看能不能抄下这个php自己撸一个C/C++的MVC框架. 下 ...
- 第一章 Web MVC简介 —— 跟开涛学SpringMVC 博客分类: 跟开涛学SpringMVC webmvcjavaeespring跟开涛学SpringMVC Web MVC简介 1.1、We
第一章 Web MVC简介 -- 跟开涛学SpringMVC 博客分类: 跟开涛学SpringMVC webmvcjavaeespring跟开涛学SpringMVC Web MVC简介 1.1.Web ...
- PhalAPI学习笔记 ——— 第一章自定义HelloWorld接口
PhalAPI学习笔记 --- 第一章自定义HelloWorld接口 前言 自定义接口 项目实例 结果 分布解析 结束语 前言 公司业务需要转学PHP,而PHP中一个功能强大且生态链完整的PHP接口框 ...
- 自定义MVC框架之工具类-图像处理类
截止目前已经改造了4个类: ubuntu:通过封装验证码类库一步步安装php的gd扩展 自定义MVC框架之工具类-分页类的封装 自定义MVC框架之工具类-文件上传类 图像处理类: 1,图片加水印处理( ...
- 自定义mvc框架复习(crud)
目录 一.搭建自定义mvc框架的环境 1.1导入框架的jar包依赖 1.2导入框架配套的工具类 1.3导入框架的配置文件 1.4将框架与web容器进行集成,配置web.xml 二.完成实体类与数据库表 ...
- java struts2 mvc_struts2自定义MVC框架
本文实例为大家分享了struts2自定义MVC框架的方法,供大家参考,具体内容如下 自定义MVC:(首先了解Model1和Model2的概念) Model1与Model2: Model1:就是一种纯j ...
- 使用Intellij Idea自定义MVC框架
今天我学习了自定义一个简单的MVC框架,这个我们首先要知道什么是MVC框架! MVC框架: MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(co ...
- 学到微笑之 - 自定义 MVC 框架
没啥想说的,就放个表情包吧 1 Spring MVC 执行流程 2 MVC 框架注解开发 自定义注解 (1)MyController @Documented @Target(ElementType.T ...
最新文章
- bash history 命令记录日志 实时发送到syslog server
- matlab做pca人脸识别,[转载]一个修改后的PCA进行人脸识别的Matlab代码,识
- [数论]拓展中国剩余定理
- 如何做好Serv-U安全设置,保护FTP服务器安全
- spring书籍调研
- linux中传输文件方法,Linux快速传输文件几种方法
- @NotBlank注解地正确使用
- SQL Server基础之索引
- 2018.8.2 python中is和==的区别
- pcie数据反_PCIe事务层の详解(一)
- 解决问题--mysql可以远程通过IP访问,不能通过localhost与127.0.0.1访问
- Oracle 11g Database和ASM默认的审计策略和相关操作
- oracle vm 4.3.12,Oracle VM VirtualBox 4.3.12_ZZZZ这个程序肿么卸载啊,卸载不了
- 【播放器】git上著名播放器
- MFC使用自带的MSXML6.dll解析xml(开发环境vc2010)
- springboot admin 解决 client 注册不到 server
- 从新一代华为全屋智能解决方案看智能家居的本质
- 自然语言处理NLP文本分类顶会论文阅读笔记(二)
- 轻松一下,做一道题目吧
- python语法认为条件x=y=z是合法的-python if条件判断语句