现在我们要做个简单的基于servlet的MVC的模型,我们要有一个Product要从表单处获取。

MVC中的M是模型,V是视图,C是控制器。视图负责应用的展示,模型封装了数据和业务逻辑,控制器负责接收用户输入,改变模型以及调整视图是显示。

在现代框架中,servlet和filter都可以作为controller,也就是控制器。

MVC中的业务逻辑一般叫做action,每个HTTP请求发给控制器,请求中的URL标识出对应的action。action标识了一个操作。在数据库中添加一个product需要两个action:

1.显示一个添加产品的表单

2.保存表单信息到数据库

然后我们要通过url来告诉控制器执行相应的action    http://domain/appName/product_input   http://domain/appName/product_save

控制器回解析url并调用相应的action,然后将模型对象放在视图可以访问到的区域,最后利用RequestDispatcher来跳转视图。

先来看用servlet实现的mvc:

Product类

public class Product implements Serializable {
//实现了序列化接口,然后就可以安全地将数据保存在HttpSession中 private static final long serialVersionUID = 544546444654L;
private String name;
private String description;
private float price; public String getName() {
return name;
} public String getDescription() {
return descriptioin;
} public String getPrice() {
return price;
} public void setName(String name) {
this.name = name;
} public void setPrice(float price) {
this.price = price;
} public void setDescription(String description){
this.description = description;
}
}

ProductForm类(这里主要是考虑到校验等问题)

public class ProductForm {

    private String name;
private String description;
private float price; public String getName() {
return name;
} public String getDescription() {
return descriptioin;
} public String getPrice() {
return price;
} public void setName(String name) {
this.name = name;
} public void setPrice(float price) {
this.price = price;
} public void setDescription(String description){
this.description = description;
}
}

两个视图:ProductForm.jsp对应于输入表单操作,ProductDetials.jsp对应于保存表单操作。

自己写的Controller接口:

public interface Controller {
String handleRequest(HttpRequest req, HttpServletResponse resp);
}

InputProductController类

public class InputProductController implements Controller {
public String handleRequest(HttpRequest req, HttpServletResponse resp) {
return "WEB-INF/jsp/ProductForm.jsp";
}
}

SaveProductController类

public class InputProductController implements Controller {
public String handleRequest(HttpRequest req, HttpServletResponse resp) {
ProductFrom productFrom = new ProductFrom();
productFrom.setName(req.getParameter("name"));
productFrom.setPrice(req.getParameter("price"));
productFrom.setDescription(req.getParameter("description")); //create model
Product product = new Product();
product.setName(productFrom.getName());
product.setPrice(productFrom.getPrice());
product.setDescription(productFrom.getDescription()); requset.setAttribute("product",product);
return "WEB-INF/jsp/ProductDetails.jsp";
}
}

DispatcherServlet 分发器servlet:

public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 4654654L;
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {
process(req,resp);
} public void doPost(HttpServletRequest req, HttpServletResponse resp) throws Exception {
process(req,resp);
} public void process(HttpServletRequest req, HttpServletResponse resp) throws Exception {
String url = request.getRequestURl();
int lastIndex = url.lastIndexOf("/");//就是找出最后一个/的所在位置
String action = url.subString.substring(lastIndex+1); String dispatcherUrl = null;
if(action.equals("product_input.action")) {
InputProductController controller = new InputProductController();
dispatchUrl = controller.handleRequest(req,resp);
} else if(action.equals("product_save.action") {
SaveProductController controller = new SaveProductController();
dispatchUrl = controller.handleRequest(req,resp);
}//解析url,根据不同的action实例化不同的controller //跳转视图
if(dispatcherUrl != null) {
RequestDispatcher rd = request.getRequestDispather(dispatchUrl);
rd.forward(req,resp);
}
} }

然后这里顺便提提校验器,就是在后台校验表单内容,一般框架都支持声明式验证和编程式验证两种,前者需要提供包含校验规则的xml文档或者属性文件,后者则需要通过编码进行用户输入校验。

这就是一个简单的MVC模型的应用。

SpringMVC:

现在我们来开始介绍Spring MVC,这里我们讲的是“传统开发风格的”SpringMVC,另一种方式将是基于注解的。

首先,用Spring MVC有什么好处呢?首先一点就是,我们可以不用去写Disapatcher servlet,SpringMVC框架已经带有了这个,不用额外开发。也就是说,SpringMVC里面自带了一个DisapatcherServlet,它可以:

  1.根据url调用相应的action

  2.实例化正确的控制器类

  3.根据请求参数来构造表单bean

  4.调用控制器对象的相应方法

  5.转发到一个视图

也就是说,只要我们把该配置的配置好,SpringMVC自带的这个servlet就会帮我们去完成这些工作。

另外SpringMVC还有几个特点,像    可以自动绑定用户输入,并正确地转换数据类型;可以校验用户输入,若校验不通过,则重定向回输入表单,输入校验是可选的,支持编程以及声明方式……

SpringMVC的DispatcherServlet:

  要用这个自带的分发器,我们要在部署描述符也就是web.xml中配置好它。

  

<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DisaptcherServlet</servlet-class>
<load-on-startup>1<load-on-startup/>
<!-- 这个是可选的,如果存在,则在应用程序启动的时候就会装载这个servlet并调用它的init方法,如果不存在这个方法,则在这个servlet的第一个请求的时候加载 --> </servlet> <servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

好了,完成了这一步之后,现在Tomcat就知道我在用这个servlet,但这个servlet是来自SpringMVC的,所以显然它要读取到Spring的配置信息。所以这个servlet在初始化的时候,会在WEB-INF下找一个配置文件,该文件的命名规则如下:

  servletName-servlet.xml

这个servletName就是部署描述符中的那个DisaptcherServlet的名称,比如现在我们上面这个的文件名就应该为:

  springmvc-servlet.xml

当然,如果你不想这个配置文件放在着这,也不想用这个名字,那么你可以在部署描述符中使用servlet定义的init-param元素,以便servlet可以加载到这个元素,元素里面有一个值为<param-name>contextConfigLocation<param-name/>的param-name的元素,它的值param-value元素则包含配置文件的路径。

<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DisaptcherServlet</servlet-class>
<load-on-startup>1<load-on-startup/>
<!-- 这个是可选的,如果存在,则在应用程序启动的时候就会装载这个servlet并调用它的init方法,如果不存在这个方法,则在这个servlet的第一个请求的时候加载 --> <init-param>
<param-name>contextConfigLocation<param-name/>
<param-value>xxx/xxx/xxx/yourName.xml<param-name/>
<init-param/>
</servlet> <servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

 

Controller:

传统的开发方法就是去实现org.springframework.web.servlet.mvc.Controller

这个接口开放了一个handleRequest方法

  ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse);

这个ModelAndView可以包含视图路径或则同时包含视图路径和数据模型

Controller接口的实现类只能处理一个单一的动作Action,而一个基于注解的控制器可以同时支持多个请求处理动作,并且无须实现任何接口。

先来看spring配置文件,这里我们直接放在规定的位置和规定的命名——springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean name="/product_input.action" class="xxx.xxx.InputProductController"/>
<bean name="/product_save.action" class="xxx.xxx.SaveProductController"/>
</beans>

两个controller:

public class InputProductController implements Controller {
//这个controller就是spring框架那个要实现的controller
private static final Log logger = LogFactory.getLog(InputProductController.class); public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
logger.info("InputProductController caller");
return new ModelAndView("/WEB-INF/jsp/ProductForm.jsp");
}
}
public class SaveProductController implements Controller {
//这个controller就是spring框架那个要实现的controller
private static final Log logger = LogFactory.getLog(SaveProductController.class); public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception {
logger.info("SaveProductController caller"); ProductFrom productFrom = new ProductFrom();
productFrom.setName(req.getParameter("name"));
productFrom.setPrice(req.getParameter("price"));
productFrom.setDescription(req.getParameter("description")); //create model
Product product = new Product();
product.setName(productFrom.getName());
product.setPrice(productFrom.getPrice());
product.setDescription(productFrom.getDescription()); return new ModelAndView("/WEB-INF/jsp/ProductDetails.jsp","product",product);
}  
}

InputProductController的handelRequest只是返回一个包含视图的ModelAndView,

SaveProductController的handelRequest方法返回的ModelAndView包括了视图的路径、模型的名称及模型,该模型将提供给目标视图,用于展示。

ProductFrom.jsp中的form的action:

  action="product_save.action"

ProductDetials.jsp中

  Product Name: ${product.name} <br>

  Description: ${product.description}<br>

  Price: ${product.price}

  可以直接用EL表达式来访问传过来的product模型

SpringMVC的View Resolver:

SpringMVC的视图解析器负责解析视图,可以通过在Spring的配置文件来设置:

<bean id="viewResolver" class="org.springframewordk.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

上图的视图解析器设置了前缀和后缀两个属性,现在你只需要在ModelAndView里面返回"mainPage"就相当于

/WEB-INF/jsp/mainPage.jsp

MVC模式到传统风格的Spring MVC的更多相关文章

  1. Spring MVC 学习总结(八)——Spring MVC概要与环境配置(IDEA+Maven+Tomcat7+JDK8、示例与视频)

    一.MVC概要 MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范,用一种将业务逻辑.数据.显示分离的方法组织代码,MVC主要作用是降低了视图与业务 ...

  2. Spring MVC 学习总结(九)——Spring MVC实现RESTful与JSON(Spring MVC为前端提供服务)

    很多时候前端都需要调用后台服务实现交互功能,常见的数据交换格式多是JSON或XML,这里主要讲解Spring MVC为前端提供JSON格式的数据并实现与前台交互.RESTful则是一种软件架构风格.设 ...

  3. Spring MVC学习总结(2)——Spring MVC常用注解说明

        使用Spring MVC的注解及其用法和其它相关知识来实现控制器功能. 02     之前在使用Struts2实现MVC的注解时,是借助struts2-convention这个插件,如今我们使 ...

  4. Spring MVC学习总结(10)——Spring MVC使用Cors跨域

    跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求.比如说,域名A(http://domaina.examp ...

  5. Java Spring MVC项目搭建(一)——Spring MVC框架集成

    1.Java JDK及Tomcat安装 我这里安装的是JDK 1.8 及 Tomcat 8,安装步骤详见:http://www.cnblogs.com/eczhou/p/6285248.html 2. ...

  6. 【.NET特供-第三季】ASP.NET MVC系列:传统WebForm站点和MVC站点执行机制对照

    本文以图形化的方式,从'执行机制'方面对照传统WebForm站点和MVC站点. 请參看下面图形: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhb2 ...

  7. Spring MVC学习总结(1)——Spring MVC单元测试

    关于spring MVC单元测试常规的方法则是启动WEB服务器,测试出错 ,停掉WEB 改代码,重启WEB,测试,大量的时间都浪费在WEB服务器的启动上,下面介绍个实用的方法,spring MVC单元 ...

  8. Spring MVC学习总结(9)——Spring MVC整合swagger自动生成api接口文档

    Swagger 号称:世界最流行的API框架,官网:http://swagger.io/,Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总 ...

  9. Spring MVC URL的映射问题 ;Spring MVC 跳转与iframe包含地址问题

    /login/login.html 进行form提交,登录之后的页面位于/main/frame.jsp; 这样的controller中的地址需要映射成/main/login.do,然后在control ...

随机推荐

  1. compile java sources

    Information:javac 1.8.0_91 was used to compile java sources D:\myjdk\bin\java "-javaagent:C:\Pr ...

  2. Cats transport(codeforces311B)(斜率优化)

    \(Cats Transport\) 感觉这道题题面不好讲,就自翻了一个新的,希望有助于大家理解其思路: 大致题意: \(wch\) 的家里有 \(N\) 座山(山呈直线分布,第 \(i-1\) 座山 ...

  3. python 2: 解决python中的plot函数的图例legend不能显示中文问题

     问题: 图像标题.横纵坐标轴的标签都能显示中文名字,但是图例就是不能显示中文,怎么解决呢?  解决: plt.figure() plt.title(u'训练性能', fontproperties=f ...

  4. 北斗有 35 颗卫星,而 GPS 有 24 颗卫星,为什么二者数量不同?

    作者:知乎用户链接:https://www.zhihu.com/question/21092045/answer/17164418来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  5. python中的编码和解码

    计算机中常见的编码方式有多种,英文一般是ascii编码,其他有unicode,utf-8,gbk,utf-16等编码. 常见编码方式: ASCII编码:ASCII是早期的编码,包含英文字母.数字和 ...

  6. [Selenium] 如何使ChromeDriver 每次启动的端口不会随机变化

    ChromeDriver  在不指定任何参数的情况下,启动监听端口会随机变化.如果需要保证其端口固定不变,可通过ChromeDriverService 打的目的 public class testCh ...

  7. 嵌入式Linux学习方法——给那些彷徨者(上)

    要想学好嵌入式Linux,首先要解决两个重要问题: 1. 学什么? 2. 怎么学? 首先解决第一个问题. 嵌入式Linux的系统架构包括软件和硬件两个部分,如下图: 再来看看一个成熟的嵌入式产品的开发 ...

  8. Java Container ***

    Java Container ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,都允许直接序号索引元素,但是插入数据要设计到数组元素移动等内存 ...

  9. 6-7 adaboost分类器1

    如何利用特征来区分目标,进行阈值判决.adaboost分类器它的优点在于前一个基本分类器分出的样本,在下一个分类器中会得到加强.加强后全体的样本那么再次进行整个训练.加强后的全体样本再次被用来训练下一 ...

  10. 任务34:Cookie-based认证实现

    任务34:Cookie-based认证实现 用mvc来实现以下Cookie-Base的认证和授权的方式 新建一个web MVC的项目 在我的电脑的路径:D:\MyDemos\jesse Ctrl+鼠标 ...