基于接口的控制器
2.5以前的的Spring MVC控制器需要实现
org.springframework.web.servlet.mvc.Controller
接口,实现其
ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse);
方法。这样的基于接口实现的控制器,每个只能处理一个Action,即每个实现类对应一个动作方法,因为需要在Spring MVC的配置文件中使用
<bean name="/URL" class="控制器类"/>
这样的形式去显式建立类和URL的映射关系。类似与Django中的路由配置。
在覆写的handleRequest
方法中,Servlet的请求对象和响应对象将直接通过参数传入该方法。该方法的返回值是一个ModelAndView
对象,其中至少有访问视图View,代表返回到哪个视图上,还可以有模型对象,用来存储页面上的数据。
常用的写法是
return new ModelAndView("/WEB-INF/...");//只返回视图
return new ModelAndView("/WEB-INF/...","模型对象key",模型对象);//返回视图和模型对象
注意模型对象和Form对象都是表单提交过来的信息组成的对象,但是Form对象里的字段都是字符串,模型对象则做过了必要的类型转换使其语义化。
当操作数据库时,使用的是模型对象;如果表单提交的信息验证不被通过,留在页面上的信息来自Form对象(显然使用Ajax可以免去Form对象)。
模型对象被作为handleRequest
处理方法的返回值ModelAndView
对象的可能组成部分,如果需要在所返回的视图上显示其中的信息,只要像使用request对象那样通过EL(表达式语言)来显示即可。
视图解析器
上篇学习的Spring MVC的配置文件中的internalResourceViewResolver
就是视图解析器,通过指明前缀和后缀,View字符串只给出中间的那一部分视图名称,既做了简化也做了规范化。
显式指明Spring MVC配置文件位置
通过在web.xml(部署描述符文件)中,为Spring MVC所配置的名为springmvc的<servlet>
标签内使用
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>配置文件位置</param-value>
</init-param>
可以显式指明Spring MVC配置文件的位置。其中<param-value>
可以有多种寻路方式:
常用/WEB-INF/
目录和classpath:
(指的是src/
目录)。
基于注解的控制器
上篇的例子就是基于注解的控制器,现在的Spring MVC控制器都使用这种具有优势的方式。一个控制器类可以实现多个动作,并且这种方式下请求映射不需要存储在配置文件中。
基于主键的控制器需要使用
org.springframework.stereotype.Controller;
并在Spring MVC配置文件根bean标签添加
xmlns:context="http://www.springframework.org/schema/context"
通过为类添加@Controller
主键,指示该类为一个控制器类。
@RequestMapping
Annotation注解可以具有若干属性,使用格式是:
@注解名(属性=属性值,属性=属性值,...)
@RequestMapping
的value
属性是其默认属性,当只有这一个属性时可以省去属性名称,该属性用来将URI映射到该注解修饰的类或者方法。
另一个常用的属性是method
,来指示只被哪些形式的HTTP方法所触发,如果不使用该属性,则接受所有形式的HTTP方法。
例如:
@RequestMapping(value = "/mvc",method = {RequestMethod.POST,RequestMethod.GET})
public class HelloWorldController{
//...
}
表示将访问/mvc
这个URI时的POST
和GET
形式的HTTP请求映射到这个类,它们也可以修饰方法。
请求处理方法
在基于注解的控制器中,请求处理方法的形参表中可以有下列参数类型,由Spring容器来做DI,以在方法中直接使用:
请求处理方法的返回值可以是以下参数类型:
Model对象的使用
注意,这里的Model对象指的就是org.springframework.ui.Model
类的对象,而前面说的模型对象是一个普通的Java类,里面存的是表单对象正确调整类型后的对象。
在请求处理方法的形参表中传入Model对象,并使用
Model对象.addAttribute("模型对象key",模型对象);
最后再返回视图字符串,就可以在返回的视图中用EL表达式语言使用这个模型对象了。
例如:
package org.test;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
//使用@Controller注解,在对应的方法上,视图解析器可以解析return的jsp/html页面,并跳转到相应页面
@Controller
//@RequestMapping是一个用来处理请求地址映射的注解
//用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径
@RequestMapping(value = "/mvc")
public class HelloWorldController {
//用于方法上,指明访问什么路径时要调用该方法
@RequestMapping(value = "/hello")
//请求处理方法要使用到Model对象,则在参数表中指明,Spring会将其传入
public String sayHello(Model model) {
Student stu = new Student();
stu.setName("lzh");
//添加到Model对象
model.addAttribute("sb", stu);
//根据dispatcher-servlet.xml的配置,这个字符串将被解析成视图/WEB-INF/jsp/hello.jsp
return "hello";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Spring MVC</title>
</head>
<body>
<h1>Hello ${sb.name}</h1>
</body>
</html>
mvc:resource元素
在部署描述符文件中配置Spring MVC的URL匹配往往可能过多,例如为/
时,所有URL请求都被Spring MVC的Dispatcher Servlet拦截处理。通过在Spring配置文件中配置mvc:resource
元素来配置那些静态资源,这些资源将不经过Spring MVC的Dispatcher Servlet拦截。
例如:
<mvc:resources mapping="/sttc/**" location="/static/"/>
将使web/static/
及其子目录下的所有文件都可见,其URI为/sttc/
。注意一般不映射web/WEB-INF/
目录,因为这个目录本来就是要保护不被浏览器直接访问的资源的。