1. MVC模式
什么是MVC?M:Model
(模型),V:Model
(视图),C:Controller
(控制器)。
在一个三层架构的Java Web项目中,Service、Dao层充当Model,jsp页面充当View,Controller(实质上就是一个Servlet)层充当控制器。
在没有框架的项目中,最典型的MVC架构通常是JavaBean
+ JSP
+ Servlet
。
2. SpringMVC快速入门
创建一个maven的web工程,web.xml文件配置如下(注意需要使用4.0版本的web.xml约束,2.3版本的JSP页面中不支持EL表达式):
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--指明SpringMVC配置文件的位置-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--1代表服务器一启动,该前端控制器(其实就是一个Servlet便会被创建)-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置监听器,服务器一启动便会加载Spring的配置文件-->
<!--在Spring与SpringMVC进行整合的时候需要,单独的使用SpringMVC不需要-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<!--指明Spring配置文件的位置-->
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--配置过滤器,防止中文乱码-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<!--这里要使用/*,不能使用/-->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
创建配置文件springMVC.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置注解扫描,让Controller包下的注解生效-->
<context:component-scan base-package="lm.controllor"/>
<!--配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--让SpringMVC不处理静态资源-->
<mvc:default-servlet-handler/>
<!--也可以使用这种方式,让SpringMVC不处理静态资源-->
<!--<mvc:resources location="/css/" mapping="/css/**" />-->
<!--<mvc:resources location="/images/" mapping="/images/**" />-->
<!--<mvc:resources location="/js/" mapping="/js/**" />-->
<!--配置这行代码Spring-MVC自动为我们创建 处理器映射器和 处理器适配器-->
<mvc:annotation-driven/>
</beans>
2.1 前端控制器DispatcherServlet
前端发出的所有的请求首先都会经过前端控制器,它负责将请求分发给不同的处理器。
2.2 SpringMVC三大组件及请求处理过程
- 处理器映射器 HandlerMapping
- 处理器适配器 HandlerAdapter
- 视图解析器 ViewResovler
请求处理过程:
-
发起请求到前端控制器(DispatcherServlet)
-
前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)。匹配条件包括:请求路径、请求方法、header信息等
-
处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
HandlerInterceptor是请求路径上的拦截器,需要自己实现这个接口以拦截请求,做一些对handler的前置和后置处理工作。
-
前端控制器调用处理器适配器去执行Handler
-
处理器适配器HandlerAdapter将会根据适配的结果去执行Handler
-
Handler执行完成给适配器返回ModelAndView
-
处理器适配器向前端控制器返回ModelAndView (ModelAndView是springmvc框架的一个底层对象,包括 Model和view)
-
前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图(jsp)),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可
-
视图解析器向前端控制器返回View
-
前端控制器进行视图渲染 (视图渲染将模型数据(在ModelAndView对象中)填充到request域)
-
前端控制器向用户响应结果
SpringMVC封装数据
可以使用三个对象来封装数据。
- ModelAndView
- Model
- ModelMap
Model
继承了ModelMap
,而ModelMap
继承了LinkedHashMap
。可以通过调用他们三个对象的addAttribute方法来存储一个对象。通常使用Model
来存储数据。实际上是存储到了Request域中。
SpringMVC跳转页面
如果想要跳转到success.jsp页面。可以有以下几种方式。
- 在Controller中直接返回字符串。视图解析器会将配置到视图解析器的prefix与Controller中返回的字符串和suffix进行拼接,得到视图的逻辑地址,将页面进行转发(转发)。
return "success";
- 返回一个ModelAndView对象。在Controller中返回一个ModelAndView,指定该ModelAndView的名字为想要跳转的地址(转发)。
ModelAndView mv = new ModelAndView();
mv.setViewName("success");
return mv;
-
return "forward:/success.jsp"
(转发) -
return "redirect:/success.jsp"
(重定向)其中3、4两种方法不需要配置视图解析器也可以,但是1、2必须要配置视图解析器
SpringMVC的一些注解
@PathVariable。通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中@PathVariable(“xxx“);
@RequestMapping("show5/{id}/{name}")
public ModelAndView test5(@PathVariable("id") Long ids ,@PathVariable("name") String names){
ModelAndView mv = new ModelAndView();
mv.addObject("msg","占位符映射:id:"+ids+";name:"+names);
mv.setViewName("hello2");
return mv;
}
@RequestParama。将前端的请求参数与控制器方法的参数进行绑定。
@RequestParam注解默认的属性值required为true,代表必须加参数。如果不加该注解,前端可以不传该参数。
@RequestMapping("/test")
public void test(@RequestParam("id") Integer testId){//前端必须传递name为id的参数
}
@ResponseBody。将前端的请求参数与控制器方法的参数进行绑定。
作用:将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。
@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML
数据,需要注意的呢,在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。
如果返回值是字符串,那么直接将字符串写到客户端;如果是一个对象,会将对象转化为json串,然后写到客户端。
注意编码如果返回对象,按utf-8编码。如果返回String,默认按iso8859-1编码,页面可能出现乱码。因此在注解中我们可以手动修改编码格式,例如
@RequestMapping(value="/cat/query",produces="text/html;charset=utf-8")
,前面是请
求的路径,后面是编码格式。