接着上篇注解解析,我们继续完成对SpringMVC注解的学习。
使用Servlet原生API
尽管SpringMVC的注解注入十分强大,但在实际的开发过程中难免会用到Servlet的原生API。而实际上,SpringMVC可以在目标方法的参数中传入很多类型的Servlet原生API:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
看一个例子:
@RequestMapping("/springmvc")
@Controller
public class HelloWorld {
/**
* 可以使用Servlet原生API作为目标方法的参数
* @param request
* @param response
* @return
* @throws IOException
*/
@RequestMapping("/testServletApi")
public String testServletApi(HttpServletRequest request,HttpServletResponse response) throws IOException {
System.out.println("testServletApi, "+ request + ", " + response);
return "success";
}
}
访问http://localhost:8080/SpringMVC/springmvc/testServletApi
测试,结果为:
testServletApi, org.apache.catalina.connector.RequestFacade@12809813, org.apache.catalina.connector.ResponseFacade@5b9d0d97
处理模型数据
SpringMVC提供了以下几种方式输出模型数据:
- ModelAndView:处理方法返回值为ModelAndView时,方法体即可通过该对象添加模型数据
- Map及Model:方法参数为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map,处理方法返回时,Map中的数据会自动添加到模型中
- @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性
- @ModelAttributes:方法参数标注该注解后,参数的对象就会放到数据模型中
1.ModelAndView
看一个例子:
@RequestMapping("/springmvc")
@Controller
public class HelloWorld {
/**
* 目标方法的返回值可以是ModelAndView类型
* 其中可以包含视图和模型信息
* @return
*/
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
String viewName = "success";
ModelAndView modelAndView = new ModelAndView(viewName);
//添加模型数据到ModelAndView中
modelAndView.addObject("time",new Date());
return modelAndView;
}
}
这里将success和键值对放入ModelAndView中,然后返回该对象。
我们修改success.jsp的代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>Success Page</h4>
time:${
requestScope.time }
</body>
</html>
如果success.jsp页面能够获取到时间信息,说明ModelAndView能够将键值对信息存入请求域中。
访问http://localhost:8080/SpringMVC/springmvc/testModelAndView
测试,结果为:
2.Map及Model
SpringMVC在内部使用了一个org.springframework.ui.Model接口存储模型数据。
看一个例子:
@RequestMapping("/springmvc")
@Controller
public class HelloWorld {
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {
map.put("names",Arrays.asList("zhangsan","lisi","wangwu"));
return "success";
}
}
我们通过一个方法参数Map也可以实现请求域对象的数据存取。
修改success.jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>Success Page</h4>
names:${
requestScope.names }
</body>
</html>
访问http://localhost:8080/SpringMVC/springmvc/testMap
测试,结果为:
而事实上,方法参数不仅仅可以使用Map,还可以使用Model或者ModelMap类型,因为SpringMVC在最后传入的其实是一个ExtendedModelMap类型的对象,但通常情况下传入Map即可。
3.@SessionAttributes
若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes,SpringMVC则会将在模型中对应的属性暂存到HttpSession中。
@SessionAttributes除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中。
看一个例子:
@SessionAttributes({
"name","age"})
@RequestMapping("/springmvc")
@Controller
public class HelloWorld {
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map<String, Object> map) {
map.put("name", "zhangsan");
map.put("age",20);
return "success";
}
}
首先通过方法参数Map进行数据存储,在上一点已经说了,通过Map参数会将数据保存到请求域对象中,如果要将数据保存到session对象中,就需要在类上添加注解@SessionAttributes,注解中填入键值。
修改success.jsp文件:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>Success Page</h4>
<br> session-name:{
mathJaxContainer[0]}{
sessionScope.age }
</body>
</html>
访问http://localhost:8080/SpringMVC/springmvc/testSessionAttributes
测试,结果为:
@SessionAttributes同时还支持传入参数类型保存数据,SpringMVC会自动根据参数类型进行相应的保存操作。
例如@SessionAttributes(types = {String.class,Integer.class})
这样的一段
注解同样能够将刚才的参数保存至session。需要注意的是,该注解只能放在类的上面。
视图解析器
当请求处理方法执行完成后,最终返回一个ModelAndView对象,对于那些返回String、View或ModelMap等类型的处理方法,SpingMVC也会在内部将它们装配成一个ModelAndView对象,它包含了逻辑名和模型对象的视图。
SpringMVC借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP,也可以是Excel、JFreeChart等各种表现形式的视图。
对于最终究竟采用何种视图对象对模型数据进行渲染,处理器并不关心,处理器工作重点聚焦在生产模型数据的工作上,从而实现MVC的充分解耦。