携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
本文项目见:JavaWeb: 本仓库介绍JavaWeb的三个项目。 (gitee.com))
MVC
- 将各种Servlet转为一个FruitServlet。
JavaWeb_mvc之前的做法是,一个请求对应一个Servlet,这样Servlet太多了。所以把各种Servlet整合为一个FruitServlet。通过一个operator的值决定调用哪个Servlet。这里使用反射获取operator的值。 JavaWeb_mvc00_dispatcher:引入使用中央控制器。 由于每一个Servlet中都有反射代码,所以继续抽取,设计一个中央控制器。
DispatcherServlet类的工作分为两部分:
-
根据url定位到能够处理这个请求的Controller组件
- 从url中提取ServletPath:/fruit.do——fruit
- 根据fruit找到对应的FruitController组件。具体通过applicationController.xml文件,并且使用DOM技术读取配置文件,在中央控制器中形成一个beanMap容器,存放所有的对应关系。
- 根据operator的值定位到FruitController需要调用的方法。
-
通过反射调用Controller组件中的方法(index、add、del等)
-
获取参数
获取即将要调用的方法的参数签名信息: Parameter[] parameters = method.getParameters(); 通过parameter.getName()获取参数的名称;准备了Object[] parameterValues 这个数组用来存放对应参数的参数值 另外,我们需要考虑参数的类型问题,需要做类型转化的工作。通过parameter.getType()获取参数的类型
-
执行方法
Object returnObj = method.invoke(controllerBean , parameterValues);
-
视图处理
String returnStr = (String)returnObj; if(returnStr.startWith("redirect:")){ .... }else if.....
-
JavaWeb_mvc01_controller:优化Controller中获取参数和重定向/转发的操作。
- 关于XML: 概念 HTML:超文本标记语言 XML:可扩展的标记语言 可以认为:HTML是XML的子集。
- XML的三个部分:
- XML声明 , 必须在文件的第一行。
- DTD 文档类型定义
- XML正文
- Java8新特性 Parameter[] parameters = method.getParameters(); String name = parameters[0].getName(); 默认获取名称为args0、1等。其实可以获取到属性名。 操作: IDEA下:文件——设置——构建、运行、部署——Java编译器——
常见错误:argument type mismatch 使用反射传入pageNo时,parameterValue获取的是字符串类型。所以错误。
Servlet
- Servlet生命周期:实例化、初始化、服务、销毁
Servlet中的初始化方法有两个:init() , init(config) 其中带参数的方法代码如下:
public void init(ServletConfig config) throws ServletException {
this.config = config ;
init();
}
//另外一个无参的init方法如下:
public void init() throws ServletException{
}
如果我们想要在Servlet初始化时做一些准备工作,那么我们可以重写init方法。
我们可以通过如下步骤去获取初始化设置的数据
- 获取config对象:ServletConfig config = getServletConfig();
- 获取初始化参数值: config.getInitParameter(key);
- 在web.xml文件中配置Servlet
<servlet>
<servlet-name>Demo01Servlet</servlet-name>
<servlet-class>com.atguigu.servlet.Demo01Servlet</servlet-class>
<init-param>
<param-name>hello</param-name>
<param-value>world</param-value>
</init-param>
<init-param>
<param-name>uname</param-name>
<param-value>jim</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo01Servlet</servlet-name>
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
也可以通过注解的方式进行配置:
@WebServlet(urlPatterns = {"/demo01"} ,
initParams = {
@WebInitParam(name="hello",value="world"),
@WebInitParam(name="uname",value="jim")
})
-
学习Servlet中的ServletContext(application)和
首先在配置文件中进行配置:
<!-- 配置上下文参数 --> <context-param> <param-name>view-prefix</param-name> <param-value>/</param-value> </context-param> <context-param> <param-name>view-suffix</param-name> <param-value>.html</param-value> </context-param>-
获取ServletContext,有很多方法。 可以在初始化方法中:
ServletContxt servletContext = getServletContext();也可以在服务方法中通过request对象获取,也可以通过session获取:request.getServletContext();、session.getServletContext()
- 获取初始化值:
servletContext.getInitParameter();
-
-
业务层
-
MVC:Model(模型)、View(视图)、Controller(控制器) 视图层:用于做数据展示以及和用户交互的一个界面 控制层:能够接受客户端的请求,具体的业务功能还是需要借助于模型组件来完成 模型层:模型分为很多种:有比较简单的pojo/vo(value object),有业务模型组件,有数据访问层组件
- pojo/vo : 值对象
- DAO : 数据访问对象
- BO : 业务对象
-
区分业务对象和数据访问对象: 1) DAO中的方法都是单精度方法(细粒度方法)。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作.... 2) BO中的方法属于业务方法,而实际的业务是比较复杂的,因此业务方法的粒度是比较粗的。
举例: 注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。 那么这个业务方法中包含了多个DAO方法。也就是说注册这个业务功能需要通过多个DAO方法的组合调用,从而完成注册功能的开发。 注册:
检查用户名是否已经被注册 - DAO中的select操作
向用户表新增一条新用户记录 - DAO中的insert操作
向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作等。
在库存系统中添加业务层组件。见
JavaWeb_mvc02_BO
- IOC
-
耦合/依赖 依赖指的是某某某离不开某某某。在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。我们设计的一个原则是: 高内聚低耦合。 即:层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)
-
IOC - 控制反转 / DI - 依赖注入
-
控制反转:
- 之前在Servlet中,我们创建service对象 , FruitService fruitService = new FruitServiceImpl(); 这句话如果出现在servlet中的某个方法内部,那么这个fruitService的作用域(生命周期)应该就是这个方法级别; 如果这句话出现在servlet的类中,也就是说fruitService是一个成员变量,那么这个fruitService的作用域(生命周期)应该就是这个servlet实例级别
- 之后我们在applicationContext.xml中定义了这个fruitService。然后通过解析XML,产生fruitService实例,存放在beanMap中,这个beanMap在一个BeanFactory中。 因此,我们转移(改变)了之前的service实例、dao实例等等他们的生命周期。控制权从程序员转移到BeanFactory。这个现象我们称之为控制反转
-
依赖注入:
- 之前我们在控制层出现代码:FruitService fruitService = new FruitServiceImpl(); 那么,控制层和service层存在耦合。
- 之后,我们将代码修改成FruitService fruitService = null ; 然后,在配置文件中配置:
<bean id="fruit" class="FruitController"> <property name="fruitService" ref="fruitService"/> </bean>
-
现在的项目架构: