SpringMVC是模型-视图-控制器的缩写,整个框架是围绕DispatcherServlet而设计的,DispatcherServlet继承了Httpservlet,是一个真实的Servlet,因此可以在web.xml文件中生命。另外需要使用url匹配元件制定DispatcherServlet处理的请求,例如:
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>/example/*</url-pattern>
</servlet-mapping>
</web-app>
在上述的配置中,所有以/example开始的请求都会被名为example的DispatcherServlet所处理。
DispatcherServlet在初始化时,SpringMVC会查找web应用下WEB_INF目录下的[servlet-name]-servlet.xml并创建在此文件定义的bean。
DispatcherServlet使用了其专有的bean来处理请求和渲染视图。
DispatcherServlet支持的初始化参数:
contextClass :webApplicationContext的实现类,负责初始化Servlet所使用的上下文,默认使用XmlWebApplicationContext
contextConfigLocation :传给上下文contextClass使用的路径参数,用来说明在哪里查找上下文(配置文件)。支持以,分隔的多个路径参数。当路径参数出现重复时,近者优先。
namespace :WebApplicationContext命名规则,默认是[servlet-name]-servlet
Controller实现:
@Controller :表明了被注解的类的服务角色——控制器。
@RequestMapping :在类或指定的handler方法上映射URL。在类上添加@RequestMapping不是必须的,如果没有在类上添加,handler方法上的所有路径都是绝对路径,而不是相对路径。
URI(统一资源标识符)模板模式:URI模板是一个类似于URI的字符串,其中包含了一个或多个变量。当你将这些变量替换掉时,就变回了URI。
可以在方法的输入参数上使用注解@PathVariable绑定URI的模板参数:
@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}
URI模板“/owners/{ownerId}”指定了参数ownerId,当控制器处理这个请求时,会将URI中相匹配的部分赋值给ownerId变量。例如:当传入 /owners/fred
请求时,owernId
的值就是 fred
。
当在Map<String,String>参数使用@PathVarable注解时,map会填充所有URI模板变量。
在URI模板上使用正则表达式:@RequestMapping注解支持在URI模板变量中使用正则表达式。语法为{变量名:正则表达式},
例如"/spring-web/spring-web-3.0.5.jar"
这样的URI,该如何拆分成多个部分?
@RequestMapping("/spring-web/{symbolicName:[a-z-]}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]}")
public void handle(@PathVariable String version, @PathVariable String extension) {
// ...
}
}
当一个URL与多个模板模式匹配时,会设法找出最具体的那一个路径。
当一个 URL 与多个模式匹配时,会设法找出最具体的那一个路径。
当模式中的 URI 模版变量和通配符的数量相对较少,会认为其相对具体。如:/hotels/{hotel}/*
相对 /hotels/{hotel}/**
更加合适,因为 /hotels/{hotel}/*
只有一个URI 模版变量和一个通配符,而 hotels/{hotel}/**` 有一个 URI 模版变量和两个通配符。
当两个模式中的 URI 模版变量和通配符数量相同时,更详细的那一个会认为相对适合。如 /foo/bar*
比 /foo/*
更为详细。
当两个模式中变量个数详细程度相同时,使用更少通配符的那一个会相对具体。
定义@RequestMapping处理方法:
支持的方法参数类型:
1、request或response对象,选择任意指定的request或response类型,如ServletRequest或HttpServletRequest。
2、Session对象,需要是HttpSession类型。
3、InputStream和OutputStream
等。
可支持的返回值类型:
1、ModelAndView
2、Model
3、Map
4、View
5、String
6、void
等。
参数绑定:
使用@RequestParam将请求参数绑定到方法参数中。
@Controller
@RequestMapping("/pets")
@SessionAttributes("pet")
public class EditPetForm {
// ...
@RequestMapping(method = RequestMethod.GET)
public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
}
// ...
}
@RequestParam的参数默认是必须提供的,可以将其指定为可选的,将 @RequestParam
的 reqired
属性设置 false
即可。(如, @RequestParam(value="id", required=false)
).
如果将 @RequestParam
用于 Map<String, String>
或 MultiValueMap<String, String>
参数,此参数 map 会填充所有的请求参数。
使用@RequestBody映射请求对象
@RequestBody注解表示将该参数与Http请求对象相绑定。
@RequestMapping(value = "/something", method = RequestMethod.PUT) public void handle(@RequestBody String body, Writer writer) throws IOException { writer.write(body); }
@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
writer.write(body);
}
使用@ResponseBody映射响应对象
此注解用在方法上,用来表示直接将返回数据写到 HTTP 响应体里。
使用@RestController创建REST控制器
如果控制器实现REST API,就只会返回JSON 、XML或其他的自定义媒体类型。可以在控制器上添加 @RestController
注解
在方法上使用@ModelAttribute。@ModelAttribute
用来将常用属性填充到模型里。如:填充下拉框陈述、宠物类型、或命令对象(如 Account,用于表示 HTML 表单数据)。
@ModelAttribute
方法的两种使用方式。第一种,在方法里隐式添加一个属性并返回;第二种,方法里接收 Model
参数,并将任意个属性添加到 Model
中。你可以根据自身需要选择其中一种使用方式。
一个控制器可以有多个 @ModelAttribute
方法。在同一个控制器中,所有 @ModelAttribute
方法都会在 @RequestMapping
方法之前调用。
在方法参数上使用 @ModelAttribute:
@ModelAttribute
注解的方法参数,表示该参数会从模型中检索。如果该参数不在模型中,此参数会先执行初始化或后添加到模型里;如果参数存在模型里,此参数字段会填充所有匹配其名称的请求参数。
视图解析
ViewResolver和view是spring处理视图的两个重要的接口,ViewResolver提供了视图名称和真实视图之间的映射,View是负责解决某个视图的技术的请求预处理和请求的后续处理。
SpringMVC中的所有handler方法都需要解析某一个逻辑视图名称,可以是显示的,例如返回String,View,ModelAndView实例。也可以是隐式的。spring中视图通过逻辑视图名称进行定位,并使用视图解析器进行解析。
例如,解析JSP视图技术,可以使用UrlBasedViewResolver解析器,此解析器将视图名称转换成为url,并将请求传递到
RequestDispatcher,以便渲染视图。
视图解析器链:Spring中提供了多种视图技术,因此可以定义解析器链,用于解析不同的视图。
重定向到视图
文件上传
SpringMVC配置文件讲解:
在web.xml中配置前端控制器DispatcherServlet。
<web-app>
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>*.form</url-pattern>
</servlet-mapping>
</web-app>
<load-on-startup>1</load-on-startup>是启动顺序,让这个Servlet随Servletp容器一起启动。
<url-pattern>*.form</url-pattern> 会拦截*.form结尾的请求。
在没有配置<init-param>的时候:
在DispatcherServlet的初始化过程中,框架会在web应用的 WEB-INF文件夹下寻找名为[servlet-name]-servlet.xml 的配置文件,生成文件中定义的bean。
<servlet>
<servlet-name>springMVC</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>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
指明了配置文件的文件名,不使用默认配置文件名,而使用springMVC.xml配置文件。
其中<param-value>**.xml</param-value> 这里可以使用多种写法
1、不写,使用默认值:/WEB-INF/<servlet-name>-servlet.xml
2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
3、<param-value>classpath*:springMVC-mvc.xml</param-value>
4、多个值用逗号分隔
servlet拦截匹配规则:
1、拦截*.do、*.htm, 例如:/user/add.do
这是最传统的方式,最简单也最实用。不会导致静态文件(jpg,js,css)被拦截。
2、拦截/,例如:/user/add
可以实现现在很流行的REST风格。很多互联网类型的应用很喜欢这种风格的URL。
弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。想实现REST风格,事情就是麻烦一些。后面有解决办法还算简单。
3、拦截/*,这是一个错误的方式,请求可以走到Action中,但转到jsp时再次被拦截,不能访问到jsp。