Struts2技术内幕 读书笔记三 表示层的困惑
表示层能有什么疑惑?很简单,我们暂时忘记所有的框架,就写一个注册的servlet来看看。
index.jsp
<form id="form1" name="form1" method="post" action="loginServlet">
<table width="357" border="0" align="center">
<tr>
<td width="128">用户名:</td>
<td width="219"><label>
<input name="user" type="text" id="user" value="dlf" />
</label></td>
</tr>
<tr>
<td>生日:</td>
<td>
<input name="birthday" type="text" id="pwd" value="2012-05-04" />
</td>
</tr>
<tr>
<td>
<input type="submit" name="Submit" value="登录" />
</td>
</tr>
</table>
</form>
User.java
public Class User{
private String user;
private Date birthday;
public User(){}
.....//省略get/set
}
RegisterServlet.java
package example;
public class RegisterServlet extends HttpServlet {
public void destroy() {
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8"); //设置格式
response.setContentType("text/html");
PrintWriter out = response.getWriter(); //获得参数
String name = new String (request.getParameter("user").getBytes("ISO8859_1"), "UTF-8");
String birthday= new String(request.getParameter("birthday").getBytes("ISO8859_1"), "UTF-8");
Date date=null; //参数类型转换
try{
date=new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
}catch(ParseException e){
e.printStackTrace();
}
User user = new User(); // 相当于MVC模型图中 第二步create
user.setName(name); // 相当于MVC模型图中 第四步extract
user.setBirthday(date); // bean中的数据来自于视图
UserService us=new UserService(); //核心业务逻辑
us.register(user);
//返回处理结果
// 相当于MVC模型图中 第三步forward
request.getRequestDispatcher("/success.jsp").forward(request,response);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request,response);
}
}
web.xml
<servlet>
<servlet-name>register</servlet-name> <!--这里是servlet的名字-->
<servlet-class>example.RegisterServlet</servlet-class> <!-- 这里写servlet类在的包路径-->
</servlet>
<servlet-mapping> <!-- 这里是地址映射-->
<servlet-name>register</servlet-name><!--这个和上面的同名-->
<url-pattern>/loginServlet</url-pattern><!--这里写servlet映射地址-->
</servlet-mapping>
我们对照之前的MVC元素
Model(数据模型)----User.java
View(对外交互)-----registration.jsp
Control(程序执行与控制)-----RegistrationServlet.java
URL Mapping(请求转化)----web.xml
上面的代码有问题吗?
没有问题(除了取参数那部分)
上面的代码好吗?
不好。
哪里不好?
不好的地方主要在以下两点:
1 出于程序可读性和可维护性的考虑,程序还需要重构。
2 业务扩展也存在问题。
上面说的问题很宏观也很泛,下面具体说几个问题。
1 当浏览器发送一个Http请求,Web容器是如何接收这个请求并指定相应的java类来执行业务逻辑并返回处理结果呢?
这其实就是一个URL Mapping的问题。
对这个感兴趣的朋友 可以阅读 下面的一篇文章
how tomcat works 读书笔记 十一 StandWrapper 上
里面的参数由web.xml而来。
其实如何查找对应的java类,说白了就是servlet容器会分析请求的url并且和web.xml里面的servlet-mapping元素下的uri-pattern对照,如果找到一致的,就按照servlet-name查找到相应的java类。
至于这个根据uri生成java对象,在tomcat中使用的是digerter库。相关内容见:
How tomcat works 读书笔记十五 Digester库 上
很简单吧。但是这里也有一个问题,如果一个web.xml里面就写3-5个servlet,我们看着也方便;可问题是,如果一个系统里程序执行与控制部分由几十个几百个,都放在web.xml里面,那就是一场灾难了。
解决这个问题的策略是建立一套由uri到java类的规则匹配引擎。
2 在web请求中,数据是如何顺利地流转与浏览器与java世界中的。我们能否做到自动匹配?
在浏览器中,我们看到的信息都是字符串(弱类型),但是在java中,有string,int,boolean等等不同的数据类型(java是强类型)。在上面的servlet中,我们看到了birthday这个属性的转换。看上去也不复杂,不过如何属性不是一个是100个呢?属性的类型也不再是基本类型呢?
解决这个问题的策略是使用表达式引擎
3 servlet的多线程问题。
这是一个比较大的问题,详细说明见
tomcat中的线程问题
http://blog.csdn.net/dlf123321/article/details/42222303
4 Control层作为mvc的核心控制器,如何能在最大程度上支持功能点上的扩展。
这个问题很大。
这其实就是一个不断分层细化的问题。
上面的那句话肯定让大家很是不懂。我来仔细说说。
想想我们之前讨论分层的时候,为什么要分层?因为分层后,把相同的逻辑功能点放到了一起不管是可读性还是扩展性都有了保证。
那就上面的servlet而言能不能再次进行功能细分呢?
首先我们看看在那个servlet中代码在逻辑层面上都干了什么。
1 获得参数
2 类型转换
3 执行核心业务逻辑
4 返回处理结果
其实一个servlet(程序执行与控制模块)干的事情无外乎就是上面四步。那么我们能不能把它们四个再分割呢?
就像一个汽车工厂,最开始的时候,从原料(钢铁)的获得,材料的切割,焊接,喷色到最后的销售都是一个人负责的(在上面的例子中,就是说上面的四点都是在一个servlet中干的),这好不好?不好。为什么?
如果本来车子是喷蓝色油漆,我现在想改成喷白色漆。在一个人干所以事情的架构下回很麻烦,那怎么办?
做一条"流水线",一个人负责采购原料,一个人负责原料切割,一个人负责喷漆......
我现在想要改变喷漆的颜色,直接找那一个人就OK。
我们回到代码上,问题的难点在于,要构建一条"流水线"是很麻烦的,特别是这个流水线不仅能生产汽车,还能生产飞机,还能生产大炮。总而言之,这个"流水线"应该是一套规则,而不是实体。怎么做?我们自己来做流水线不现实的,所以看看前辈们的最佳实践,看看他们使用的框架是怎么构建"流水线"的。
5 View层的表现形式是多种多样的,随着Web开发技术的不断发展,MVC如何在框架级别提供一种完全透明的方式来应对不同的视图表现形式。
在之前的servlet中,我们是使用硬编码的形式来控制视图的流转。对上面这个问题的解决,其实也是第二个问题的答案。构建流水线。
6 MVC模式虽然很直观的为我们规定了表示层的各种元素,但是如何通过某种机制吧这些元素有机的整合在一起,从而形成一个整体呢。
这个问题太大,我在目前没有办法理解,只能截图了。
参考资料
http://blog.csdn.net/dlf123321/article/details/42222303
Struts2技术内幕 读书笔记三 表示层的困惑的更多相关文章
- Struts2技术内幕 读书笔记一 框架的本质
本读书笔记系列,主要针对陆舟所著<<Struts2技术内幕 深入解析Strtus2架构设计与实现原理>>一书.笔记中所用的图片若无特殊说明,就都取自书中,特此声明. 什么是框架 ...
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- Struts2技术内幕 读书笔记二 web开发的基本模式
最佳实践 在讨论基本模式之前,我们先说说一个词:最佳实践 任何程序的编写都得遵循一个特定的规范.这种规范有约定俗称的例如:包名全小写,类名每个单词第一个字母大写等等等等;另外还有一些需要我们严格遵守的 ...
- Kafka技术内幕 读书笔记之(三) 生产者——消费者:高级API和低级API——基础知识
1. 使用消费组实现消息队列的两种模式 分布式的消息系统Kafka支持多个生产者和多个消费者,生产者可以将消息发布到集群中不同节点的不同分区上:消费者也可以消费集群中多个节点的多个分区上的消息 . 写 ...
- webkit技术内幕读书笔记 (二、三)
可视区和网页 通常网页比屏幕的可视区面积要大,因此当网页内容在可视区中放不下时,一般浏览器会提供滚动条. 从URL到构建完DOM树的过程 当用户输入网页URL的时候,WebKit调用其资源加载器加载该 ...
- Kafka技术内幕 读书笔记之(三) 消费者:高级API和低级API——消费者消费消息和提交分区偏移量
消费者拉取钱程拉取每个分区的数据,会将分区的消息集包装成一个数据块( FetchedDataChunk )放入分区信息的队列中 . 而每个队列都对应一个消息流( KafkaStream ),消费者客户 ...
- MySQL技术内幕读书笔记(三)——文件
目录 文件 参数文件 日志文件 套接字文件 pid文件 表结构定义文件 INNODB存储引擎文件 文件 有以下类型文件 参数文件:告诉MYSQL实例启动时在哪里找到数据库文件,并且制定某些初始化参 ...
- MySQL技术内幕读书笔记(八)——事务
事务的实现 事务隔离性由锁来实现.原子性.一致性.持久性通过数据库的redo log和undo log来完成.redo log称为重做日志,用来保证事务的原子性和持久性.undo log用来保证事 ...
- MySQL技术内幕读书笔记(七)——锁
锁 锁是数据库系统区分与文件系统的一个关键特性.为了保证数据一致性,必须有锁的介入.数据库系统使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性. lock与latch 使用命令 ...
随机推荐
- 使用OpenCV读、操作、写图像并与bash合作对某个目录下所有图像进行类似处理
我门要对某个目录下所有图像文件进行统一处理,如果图像的数量过多,那么手动地一张张处理就会显得有些麻烦.本文使用OpenCV和bash来完成我们指定的任务. 任务 将目录A下的所有统一格式的jpg图像变 ...
- 使用DWR实现自动补全 类似百度搜索框的自动显示效果
使用DWR实现自动补全 自动补全:是指用户在文本框中输入前几个字母或汉字的时候,自动在存放数据的文件或数据库中将所有以这些字母或汉字开头的数据提示给用户供用户选择 在日常上网过程中,我们经常使用搜索引 ...
- Python optparser库详解
一直以来对optparser不是特别的理解,今天就狠下心,静下心研究了一下这个库.当然了,不敢说理解的很到位,但是足以应付正常的使用了.废话不多说,开始今天的分享吧. 简介 optparse模块主要用 ...
- Afinal加载网络图片及下载文件使用方法
Afinal快速开发框架使用起来非常方便,下面将讲解如何利用Afinal加载网络图片及下载文件: 先看效果图: 注意:使用Afinal前需添加Afinal的jar,可以在这里下载:http://dow ...
- 自定义控件辅助神器ViewDragHelper
ViewDragHelper作为官方推出的手势滑动辅助工具,极大的简化了我们对手势滑动的处理逻辑,v4包中的SlidingPaneLayout和DrawerLayout内部都有ViewDragHelp ...
- 【一天一道LeetCode】#303.Range Sum Query - Immutable
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 我的个人博客已创建,欢迎大家持续关注! 一天一道le ...
- PullToRefreshScrollView 嵌套RecyclerView实现特卖列表倒计时抢购
不久之前,我们谈到了通过Handler与timer及TimerTask结合实现倒计时抢购列表,那个是PullToRefreshListView实现的,今天要讲的是PullToRefreshScroll ...
- 【一天一道LeetCode】#342. Power of Four
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- 学习笔记3-开发与运行(卸载)第一个ANDROID应用
新建Android项目 1. 配置好Android坏境以后,新建项目选择Android Project. 2. 选择针对哪个平台开发的应用(Android2/Android4等) ...
- iOS中 本地通知/本地通知详解 韩俊强的博客
布局如下:(重点讲本地通知) iOS开发者交流QQ群: 446310206 每日更新关注:http://weibo.com/hanjunqiang 新浪微博 Notification是智能手机应用编 ...