一、HelloWorld
1,配置web.xml文件
配置DispatcherServlet:DispatcherServlet默认加载/WEB-INF/<servletName-servlet>.xml的Spring配置文件,启动WEB层的Spring容器。可以通过contextConfigLocation初始化参数自定义配置文件的位置和名称;
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup><!-- 该处的值必须时一个整数,如果没有配置该参数
或者配置为负数,则servlet被请求时才会被容器创建。如果配置是0或者整数,则容器在启动应用是就会加载该servlet
,数值表示容器加载的优先级,数值越小,优先级越高-->
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern><!-- "/表示拦截所有请求,单不拦截.jsp请求,"/*"表示拦截所有请求 -->
</servlet-mapping>
2,配置自动扫描的包
<context:component-scan base-package="com.cihi.handler"/>
3,配置内部资源视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
4,创建请求请求处理器类
@Controller
public class HelloController {
@RequestMapping("/helloWorld")
public String helloWorld() {
System.out.println("helloWorld");
return "success";
}
}
二、使用@RequestMapping映射请求
1,Spring MVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求;
2,在控制器的类定义及方法定义处都可以标注
- 类定义处:提供初步的请求映射信息。相对于WEB应用的根目录
- 方法处:提供进一步的细分映射信息。相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法标记的URL相对于WEB应用的根目录
3,DispatcherServlet截获请求后,就通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法;
4,@RequestMapping除了可以使用请求URl映射请求外,还可以使用请求方法,请求参数及请求头映射请求。
@RequestMapping的value、method、params、heads分别表示请求的URL,请求方法,请求参数及请求头的映射条件,他们之间的是与的关系,联合使用多个条件可让请求映射更加精细化。
params和headers支持简单的表达式:
- param1:表示请求必须包含名为param1的请求参数
- !param1:表示请求不能包含名为param1的请求参数
- param1!=value1:表示请求包含名为param1的请求参数,但其值不能为value1
- {"param1=value","param2"}:请求必须包含名为param1和param2的两个请求参数,且param1参数的值必须为value1
5,@RequestMapping还支持Ant风格的URL
Ant风格资源地址支持3中匹配符:
- ?:匹配文件名中的一个字符
- *:匹配文件名中的任意字符(一个或多个)
- **:匹配多层路径
-/user/*/createUser:匹配 /user/aaa/createUser、/user/bbb/createUser等URL
-/user/**/createUser:匹配 /user/createUser、/user/aaa/bbb/ccc/createUser等URL
-/user/createUser??:匹配/user/createUseraa、/user/createUserbb等Url
三、@PathVariable映射URL绑定占位符
通过@PathVariable可以将URL中的占位符参数绑定到控制器处理方法的入参中:URL中的{xxx}占位符可以通过@PathVariable("xxx")绑定到操作方法的入参中。
@RequestMapping("/testPath/{id}")
public String testPath(@PathVariable("id") String uid) {
System.out.println("testPath" + uid);
return SUCCESS;
}
四、Rest
HiddenHttpMethodFilter:
浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,Spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,似的支持GET、POST、PUT 与DELETE 请求。需要使用时,需要配置在web.xml文件中。
五、映射请求参数
Spring MVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应入参中。可以对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader等)
1,使用@RequestParam绑定请求参数值
在处理方法入参处使用@RequestParam可以把请求参数传递给请求方法
-value:参数名
-required:是否必须。默认是true,表示请求参数中必须包含对应的参数,若不存在,将抛出异常
2,使用@RequestHeader绑定请求报头的属性值
请求头包含了若干个属性,服务器可据此获知客户端的信息,通过@RequestHeader即可将请求头中的属性绑定到处理方法的入参中,其参数和@RequestParam相同
3,使用@CookieValue绑定请求中的Cookie值
@CookieValue可让处理方法入参绑定某个Cookie值,用法同@RequestParam
4,使用POJO对象绑定请求参数值
Spring MVC会按请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值。支持级联属性:dept.deptId、dept.address.tel
@RequestMapping("/handle8")
public String handle8(User user){
return "success";
}
/handle8.action?userName=zhangsan&dept.deptId=1&dept.address.tel=154346
5,使用Servlet API作为入参
MVC的Handler方法可以接受的的参数有:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
四,处理模型数据
Spring MVC 提供了以下几种途径输出模型数据:
- ModelAndView:处理方法返回值类型为ModelAndView时,方法体可通过该对象添加模型数据
- Map及Model:入参为Model,ModelMap或Map时,处理方法返回时,Map中的数据会自动添加到模型中。
- @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性
- @ModelAttribute:方法入参标注该注解后,入参的对象会放到数据模型中
入参的数据和模型数据都会保存在ModelAndView中,并放到request域中
1,ModelAndView
控制器处理方法的返回值如果为ModelAndView,则其既包含视图信息,也包含模型数据信息。
添加模型数据:
-ModelAndView addObject(String attributeName,Object attributeValue)
-ModelAndView addAllObject(Map<String,?> modelMap)
设置视图:
-void setView(View view)
-void setViewName(String viewName)
2,Map及Mode
Spring MVC在内部使用了一个org.springframework.ui.Model接口存储数据模型
具体步骤:
-SpringMVC在动用方法前会创建一个隐含的模型对象作为模型数据的存储容器;
-如果方法的入参为Map或Model类型,Spring MVC会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
3,@SessionAttributes
若希望在多个请求之间共用某个属性数据,则可以在控制器类上标注一个@SessionAttributes,SpringMVC将在模型中对应的属性暂存到HttpSession中
@SessionAttributes放在控制器类上,除了可以通过属性名指定需要放到会话的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
-@SessionAttributes(types=User.class)会将隐含模型中所有类型为User.class的属性添加到会话中。
-@SessionAttributes(value={"user1","user2"})
-@SessionAttributes(types={User.clsss,Dept.class})
-@SessionAttributes(value={"user1","user2"},types={Dept.class})
4,@ModelAttribute
在方法定义上使用@ModelAttribute注解:SpringMVC在调用目标方法前,会先逐个调用标注了@ModelAttribut的方法。
在方法的入参前使用@ModelAttribute注解
-可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数绑定到对象上,再传入入参(如果没有该注解,则会去数据模型中获取类型首字母小写的key的value。添加注解后可以指定key值,若找不到就去Session域中找,若存在该key,则找对应的value,若找不到value则报错,若session没有这个key,则新建一个对象)
-将方法入参对象添加到模型中
* SpringMVC 确定目标方法 POJO 类型入参的过程
* 1. 确定一个 key:
* 1). 若目标方法的 POJO 类型的参数木有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写
* 2). 若使用了 @ModelAttribute 来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值.
* 2. 在 implicitModel 中查找 key 对应的对象, 若存在, 则作为入参传入
* 1). 若在 @ModelAttribute 标记的方法中在 Map 中保存过, 且 key 和 1 确定的 key 一致, 则会获取到.
* 3. 若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰,
* 若使用了该注解, 且 @SessionAttributes 注解的 value 属性值中包含了 key, 则会从 HttpSession 中来获取 key 所
* 对应的 value 值, 若存在则直接传入到目标方法的入参中. 若不存在则将抛出异常.
* 4. 若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则
* 会通过反射来创建 POJO 类型的参数, 传入为目标方法的参数
* 5. SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中.
也就是说接受的POJO的信息会保存在request域中
5,@SessionAttributes引发的异常
如果再处理类定义处标注了@SessionAttributes("xxx"),则尝试从会话中获取该属性,并将其赋给该入参,然后再用请求消息填充该入参对象。如果在会话中找不到对应的属性,则抛出HttpSessionRequiredException异常;
如何避免@SessionAttributes引发的异常:
-添加@ModelAttribute(“user”)方法,该方法会往隐含模型中添加一个名为user的模型属性
五,视图和视图解析器
无论请求方法的返回值是String,ModelAndView或View,都会解析成ModelAndView,然后用视图解析器(viewResolver)进行解析,解析成相应的视图(JSP,Excel、JFreeChart等各种表现形式的视图);
常用的视图实现类有:InternalResourceView,JstlView,AbstractExcelView
视图解析器:
SpringMVC为逻辑视图的解析提供了不同的策略,可以在Spring WEB 上下文中配置一种或者多种解析策略,并指定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。
视图解析器的作用的作用:将逻辑视图解析为一个具体的视图对象
所有的视图解析器都必须实现ViewResolver
常用的视图解析器的实现类有:BeanNameViewResolver,InternalResourceViewResolver
每个视图解析器都实现了Ordered接口并开放出一个order属性,可以通过order属性指定解析器的优先顺序,order越小,优先级越高,SpringMVC会按照视图解析器顺序的先后顺序对逻辑视图名进行解析,直到解析成功并返回视图对象,否者将抛出ServletException异常;
1,InternalResourceViewResolver
JSP是最常见的视图技术,可以使用InternalResourceViewResolver作为视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
若项目使用了JSTL,则SpringMVC会自动把视图由InternalResourceView转为JstlView
若使用JSTL的fmt标签则需要在SpringMVC的配置文件中配置国际化资源文件
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="i18n"></property>
</bean>
若希望直接相应通过SpringMVC渲染的页面,可以使用mvc:view-controller标签实现
<mvc:view-controller path="/success" view-name="success"/>
使用后要添加<mvc:annotation-driven/>
Excel视图
若希望使用Excel展示数据列表,仅需要扩展SpringMVC提供的AbstracExcelView或AbstractJExcelView即可,实现buildExcelDocument()方法,在方法中使用模型数据对象构建Excel文档就可以了;
AbstractExcelView基于POI API,而AbstractJExcelView是基于JExcelAPI的。
视图对象需要配置IOC容器中的一个Bean,使用BeanNameViewResolver作为视图解析器即可
若希望直接在浏览器中直接下载Excel文档,则可以设置响应头Content-Disposition的值为attachement;filename=xxx.xls。
关于重定向
一般情况下,控制器方法返回的字符串类型的值会被当成逻辑视图名处理;
如果返回的字符串中带forward:或redirect:前缀时,SpringMVC会对他们进行特殊处理:将forword:和redirect:当成指示符,其后的字符串作为URL来处理
-redirect:success.jsp :会完成一个到success.jsp的重定向的操作
-forward:success.jsp :会完成到success.jsp的转发操作