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 使用命令 ...
随机推荐
- Unity UGUI图文混排(七) -- 下划线
之前更新超链接的时候,忘了搭配实现一个下划线的功能,这篇文章就是来补上这一个功能,时间有点长,一方面没有很好的思路,一方面也没多少时间. 先在网上收集了一下下划线的实现操作,一种是在文本下再创建一个文 ...
- mysql进阶(二十六)MySQL 索引类型(初学者必看)
mysql进阶(二十六)MySQL 索引类型(初学者必看) 索引是快速搜索的关键.MySQL 索引的建立对于 MySQL 的高效运行是很重要的.下面介绍几种常见的 MySQL 索引类型. 在数 ...
- Java安全套接字扩展——JSSE
上节已经介绍了SSL/TLS协议的通信模式,而对于这些底层协议,如果要每个开发者都自己去实现显然会带来不必要的麻烦,正是为了解决这个问题Java为广大开发者提供了Java安全套接字扩展--JSSE,它 ...
- Android简易实战教程--第二十一话《内容观察者监听数据库变化》
当数据库的数据发生改变,我们又想知道具体改变的情况时,就需要对数据库的变化情况做一个监控.这个任务,就由内容观察者来完成.下面这个案例,为短信数据库注册内容观察者,来监控短信的变化情况,当短信数据库发 ...
- EBS应付(AP)模块常用表
select * from ap_invoices_all INVOICE头 select * from ap_invoice_distributions_all INVOICE行 select ...
- SQL 数据库语言分析总结(三)
这次介绍通过mysql-WorkBench这个工具来管理操作数据库. 创建和删除数据库 1.点击创建数据库按钮 2.选中后右键,出现drop schema一项,这个用来删除. 设置默认数据库 选中右键 ...
- [ExtJS5学习笔记]第十九节 Extjs5中通过设置form.Panel的FieldSet集合属性控制多个field集合
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39209533 官方例子:http://docs.sencha.com/extjs/5. ...
- Java基础---Java---IO流-----File 类、递归、删除一个带内容的目录、列出指定目录下文件夹、FilenameFilte
File 类 用来将文件或者文件夹封装成对象 方便对文件与文件夹进行操作. File对象可以作为参数传递给流的构造函数 流只用操作数据,而封装数据的文件只能用File类 File类常见方法: 1.创建 ...
- 高通8x12平台开机画面制作工具
你可能在网上看到很到关于手动更换手机开机图片的文章,想想自己的开机画面是小两口,好基友的照片多么个性啊.但是你有没有发现,网上下载的什么"一键生成"之类的,在你的手机上不能用啊,( ...
- shell入门之expr的使用
在expr中加减乘除的使用,脚本如下: #!/bin/sh #a test about expr v1=`expr 5 + 6` echo "$v1" echo `expr 3 + ...