[TOC]

这一段时间一直在做Spring MVC方面的工作,也没有抽时间总结一下。今天可以好好总结一下了。


模型2和MVC模式

所有的Spring MVC的书籍都提到了web开发的两种设计模式,是模型1和模型2.模型1以页面为中心,适合小应用开发。模型2基于 MVC模式,是 Web的推荐架构。

模型1是通过 JSP去处理业务逻辑。 JSP是独立的,自主完成所有的任务。

模型2 是基于 MVC设计模式, 用户发送请求到 控制层Controller,控制层委托 模型层Model进行数据处理,处理完成后委托视图层View进行渲染。

Spring MVC执行流程

Spring MVC 框架是围绕 DispatcherServlet而工作的,它是一个 Servlet,他可以拦截 HTTP发送过来的请求,在 Servlet初始化时,Spring MVC会根据配置,获得配置信息,从而得到统一资源标识符和处理器之间的映射关系。

用户发送请求到DispatcherServlet,这是一个中央控制器。通过 处理器映射器(HandlerMapper)寻找执行类,并返回结果。DispatcherServlet请求执行 Action,通过处理器适配器去执行 Action并返回 ModelAndView,通过 视图解析器 ViewResolver解析出真正的物理视图,渲染之后返回给用户。

第一个Spring MVC程序

  1. 搭建一个java web工程,并导入Spring MVC需要的Jar包

  2. 配置 Web.xml,在其中配置 DispathcServlet

    <servlet>
      <servlet-name>springmvc</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- 默认加载方式
             默认加载必须规范:
             * 文件命名:servlet-name-servlet.xml====springmvc-servlet.xml
  -->
  <init-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:springmvc.xml</param-value>   
  </init-param>
 </servlet>

 <servlet-name>springmvc</servlet-name>
 <url-pattern>*.do</url-pattern>
 </servlet-mapping>

<br>

3. 在 项目路径下创建 `Spring MVC.xml` 

<!-- 配置处理器映射器,springmvc默认的处理器映射器

       BeanNameUrlHandlerMapping:根据bean(自定义Controler)的name属性的url去寻找hanler(Action:Controller),这是 DispatchServlet在请求到来之后,通过url去寻找执行类。
        -->
       <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
          
       <bean id="myController" name="/hello.do" class="cn.itcast.controller.MyController"></bean>
          

<!-- 配置sprigmvc视图解析器:解析逻辑试图

            后台返回逻辑试图:index
           视图解析器解析出真正物理视图:前缀+逻辑试图+后缀====/WEB-INF/jsps/index.jsp
       -->
       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="prefix" value="/WEB-INF/jsps/"></property>
       <property name="suffix" value=".jsp"></property>        
       </bean>
       

<br>

4. 自定义 Controller ,

public class MyController implements Controller{

   public ModelAndView handleRequest(HttpServletRequest arg0,
           HttpServletResponse arg1) throws Exception {
       // 接受请求,接受参数,验证参数
       //封装参数,调用业务方法
       //返回视图
       ModelAndView mv = new ModelAndView();
       //设置页面回显数据
       mv.addObject("hello", "欢迎学习springmvc!");
       //指定跳转的视图
       //返回物理视图
       //mv.setViewName("/WEB-INF/jsps/index.jsp");
       //返回逻辑视图
       mv.setViewName("index");
       return mv;
   }

}


<br>

5. 定义视图页面,通过 `${hello}`显示内容

<br>

#### 处理器映射器

这里配置的是 `BeanNameUrlHandlerMapping`,从名称中可以看出是通过 `URL`去寻找执行类,还有两种是: `SimpleUrlHandlerMapping`,这种是根据 URL集中配置。

形如:
<!-- 简单处理器映射器:

         把Url进行集中配置
     -->
     <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="mappings">
     <props>
     <prop key="/abc.do">myController</prop>
     <prop key="/ss.do">http</prop>
     <prop key="/mine.do">http</prop>
     </props>
     </property>
     
     </bean>

<br>

和 `ControllerClassNameHandlerMapping` ,这是根据 `类名`.do来访问
     <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"></bean>

<br>

#### 处理器适配器

这里用的是 `SimpleControllerHandlerAdapter`,功能是执行Controller,返回ModelAndView。还有一个是 `HttpRequestHandlerAdapter`,功能是执行Controller。

### 注解开发

1.  `web.xml`文件和上面的一样

2. 配置 `Springmvc.xml`文件 

<context:component-scan base-package="cn.itcast"></context:component-scan>

       
       <!-- 配置注解处理器映射器 
           功能:寻找执行类Controller
       -->
       <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
       
       <!-- 配置注解处理器适配器 
           功能:调用controller方法,执行controller
       -->
       <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
       
       
       <!-- 配置sprigmvc视图解析器:解析逻辑试图 
            后台返回逻辑试图:index
           视图解析器解析出真正物理视图:前缀+逻辑试图+后缀====/WEB-INF/jsps/index.jsp
       -->
       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="prefix" value="/WEB-INF/jsps/"></property>
       <property name="suffix" value=".jsp"></property>        
       </bean>
       </beans>

<br>

3. 自定义Controller类

@Controller//
@RequestMapping("/user")
public class UserController {

   
   
   @RequestMapping(value="/hello.do",method={RequestMethod.GET,RequestMethod.POST})
   public String hello(){
       
       return "index";
   }

}


<br>

### 封装参数和页面回显

HTTP请求中,所有的参数类型均为字符串。如果有多个参数的话,封装为 POJO类型即可。

表单标签用于渲染HTML表单,要使用渲染一个表单输入字段的任何其他标签,必须有一个form标签。form标签中最重要的属性或许是 `commandName`属性,如果该属性存在,则必须在返回包含该表单的视图的请求方法中添加响应的模型属性。默认为`command`。一般使用 `path`来绑定属性。如果有多个的话使用 `items`属性。

页面回显使用 `model.addAttribute()`方法

### restfull风格设计

如果请求路径中包含参数的话,使用 `@PathVariable`来获取参数。

------