1、返回值的设置
1.1、返回String
1.2、返回modelAndView
1.3、返回void
2、数据在域中的保存
2.1、Request对象中保存数据(不推荐)
2.2、Session域中保存数据
2.3、ServletContext域中保存数据
2.4、Map或Model或ModelMap形式保存数据在request域中
2.5、ModelAndView方式保存数据到request域中
2.6、@SessionAttributes保存数据到Session域中(不推荐使用)
2.7、@ModelAttribute注解
1、返回值的设置
1.1、返回String
1.1.1、返回String**默认情况**
@Controller
public class ReturnController {
@RequestMapping(value = "/return1")
public String return1() {
System.out.println("这是return1方法");
return "return";
}
}
默认情况下,返回return字符串。会经过视图解析器做字符串前后缀拼接的操作。
<!-- 配置Spring的视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- prefix配置返回的视图的前缀 -->
<property name="prefix" value="/jsp/"/>
<!-- suffix配置返回的视图的后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
通过做前后缀拼接操作得:/jsp/return.jsp。
最后做转发操作。
request.getRequestDispatcher(“/jsp/return.jsp”).forward(requst,response);
1.1.2、显示转发
注意:(下面都是)在控制器上面添加 :@RequestMapping(value="/p")进行区分相对与绝对路径
@RequestMapping(value = "/return2")
public String return2() {
System.out.println("这是return2方法");
// 在返回的字符串前面 显示的 标注 forward:表示显示的转发
// 使用显示的转发,视图解析器就不会工作了
return "forward:/jsp/return.jsp";
}
在返回的字符串前面 显示的 标注 forward/redirect:表示显示的转发
注: 使用显示的转发,视图解析器就不会工作了
1、return "forward:/jsp/return.jsp";
这是绝对路径转发
/ 表示绝对路径http://ip:port/工程名/
整个地址表示转发到http://ip:port/工程名/jsp/return.jsp
2、return "forward:jsp/return.jsp";
这是相对路径转发
先执行绝对路径再执行相对路径:
当前浏览器地址栏地址是:http://localhost:8080/mvc_hello/p/return2
相对路径是参数当前浏览器地址栏的地址
得到的转发路径是:http://localhost:8080/mvc_hello/p/jsp/return.jsp
1.1.3、显示重定向
@RequestMapping(value = "/return3")
public String return3() {
System.out.println("这是return3方法");
// 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向
// 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作
return "redirect:/jsp/return.jsp";
}
当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向
return "redirect:/jsp/return.jsp";
是绝对路径
前面这个斜杠表示到http://ip:port/工程名/
那么整个重定向的地址是:http://ip:port/工程名/jsp/return.jsp
return "redirect:jsp/return.jsp";
相对路径
需要参照浏览器地址栏当前的地址:http://localhost:8080/mvc_hello/p/return3
那么整个重定向的地址是:http://localhost:8080/mvc_hello/p/jsp/return.jsp
// 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向
// 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作
1.2、返回modelAndView
1.2.1、返回modelAndView的**默认情况**
@RequestMapping(value="/return4")
public ModelAndView return4() {
System.out.println("这是return4方法");
// ModelAndView 也可以设置返回的资源
ModelAndView modelAndView = new ModelAndView();
// 设置视图名
modelAndView.setViewName("return");
return modelAndView;
}
默认的情况我们在ModelAndView中设置的ViewName就是默认转发的视图名。这个视图名会经过视图解析器拼接这符串后再转发。
或直接ModelAndView modelAndView = new ModelAndView("return");
1.2.2、显示转发
@RequestMapping(value="/return5")
public ModelAndView return5() {
System.out.println("这是return5方法");
// ModelAndView 也可以设置返回的资源
ModelAndView modelAndView = new ModelAndView("forward:/jsp/return.jsp");
return modelAndView;
}
forward:/jsp/return.jsp
绝对路径
/ 表示绝对路径http://ip:port/工程名/
整个地址表示转发到http://ip:port/工程名/jsp/return.jsp
"forward:jsp/return.jsp";
这是相对路径转发
当前浏览器地址栏地址是:http://localhost:8080/mvc_hello/p/return5
相对路径是参数当前浏览器地址栏的地址
得到的转发路径是:http://localhost:8080/mvc_hello/p/jsp/return.jsp
1.2.3、显示重定向
@RequestMapping(value="/return6")
public ModelAndView return6() {
System.out.println("这是return6方法");
ModelAndView modelAndView = new ModelAndView("redirect:/jsp/return.jsp");
return modelAndView;
}
return "redirect:/jsp/return.jsp";
是绝对路径
前面这个斜杠表示到http://ip:port/工程名/
那么整个重定向的地址是:http://ip:port/工程名/jsp/return.jsp
return "redirect:jsp/return.jsp";
相对路径
需要参照浏览器地址栏当前的地址:http://localhost:8080/mvc_hello/p/return3
那么整个重定向的地址是:http://localhost:8080/mvc_hello/p/jsp/return.jsp
// 当我们在返回的字符串前面显示的加入redirect:表示强制使用重定向
// 只要是显示的声明使用转发或重定向,默认视图解析器将不在工作
1.3、返回void(不推荐在Controller中直接转发和重定向)
1.3.1、没有返回值的**默认情况**
一般在实际开发中。我们都是禁止使用如以上这种方式。使用默认的请求资源名做为默认转发的逻辑资源名。
如果有需要,都是使用String类型显示标明返回的逻辑名。也就是说以上代码应该写成为:
@RequestMapping(value="/return7")
public void return7() {
System.out.println("return7方法");
}
1.3.2、显示转发
@RequestMapping(value = "/return8")
public void return8(HttpServletRequest request, HttpServletResponse response) {
System.out.println("这是return8方法");
try {
request.getRequestDispatcher("/jsp/return.jsp").forward(request,
response);
} catch (Exception e) {
e.printStackTrace();
}
}
1.3.3、显示重定向
@RequestMapping(value="/return9")
public void return9(HttpServletRequest request, HttpServletResponse response) {
System.out.println("这是return9方法");
try {
response.sendRedirect(request.getContextPath() + "/jsp/return.jsp");
} catch (IOException e) {
e.printStackTrace();
}
}
7.3.4、直接输出响应数据
@RequestMapping(value="/return10")
public void return10(HttpServletResponse response) {
System.out.println("这是return10方法");
try {
response.getWriter().write("this is the content of response!");
} catch (IOException e) {
e.printStackTrace();
}
}
2、数据在域中的保存
2.1、Request对象中保存数据(不推荐)
先在Controller的方法中添加一个HttpServletRequest对象
@RequestMapping(value="/requestScope")
public ModelAndView requestScope(HttpServletRequest request) {
System.out.println("这是把数据保存到request域中---requestScope");
request.setAttribute("key1", "value1");
return new ModelAndView("scope");
}
注:
因为pageContext的作用域只在jsp页面中,所以这不考虑,request的域范围是当前请求,session是一个会话(即页面不关闭的情况下),sevletContext的域是整个web应用,即服务器只要不关闭就一直存在。
在页面中输出数据:
${ requestScope.key1 }<br/>
2.2、Session域中保存数据
在Controller方法中,添加HttpSession对象
@RequestMapping(value="/sessionScope")
public ModelAndView sessionScope(HttpSession session) {
System.out.println("这是把数据保存到session域中---sessionScope");
session.setAttribute("skey1", "svalue1");
return new ModelAndView("scope");
}
在页面中输出Session的数据:
${ sessionScope.skey1 }<br/>
2.3、ServletContext域中保存数据
在Controller中的代码。在Controller的中获取SerlvetContext对象有两种方法,
一种是@Autowired注入,
一种是通过Session获取。
是通过@Autowired自动注入ServletContext对象
@Controller
public class ScopeController {
@Autowired
private ServletContext context;
通过HttpSession获取ServletContext对象
@RequestMapping(value = "/applicationScope")
public ModelAndView applicationScope(HttpSession session) {
System.out.println("这是把数据保存到ServletContext域中---applicationScope");
session.getServletContext().setAttribute("appKey1", "appValue1");
return new ModelAndView("scope");
}
2.4、Map或Model或ModelMap形式保存数据在request域中
在四个域中,我们使用最频繁的域就是request对象。往request域对象中,保存数据,还在以下的几种形式。仅仅直接用request对象存储不推荐
我们可以在Controller的方法中,添加Map类型的参数,或者是Model类型的参数。或者是ModelMap类型的参数。都可以直接用来保存域数据到Request对象中。
Map全类名是: java.util.Map
Model全类名是: org.springframework.ui.Model
ModelMap全类名是: org.springframework.ui.ModelMap
保存到java.util.Map中,也会直接保存到request域中
@RequestMapping("/mapRequest")
public ModelAndView map(Map<String, Object> map) {
System.out.println("这是map方法保存到request域中");
//把数据保存到map中,SpringMVC会自动把这些数据保存到request域中
map.put("mapKey1", "mapValue1");
map.put("mapKey2", "mapValue2");
return new ModelAndView("scope");
}
保存到org.springframework.ui.Model中,SpringMVC也会自动保存数据到request域中
@RequestMapping("/modelRequest")
public ModelAndView model(Model model) {
System.out.println("这是model方法保存到request域中");
//把数据保存到Model中,SpringMVC会自动把这些数据保存到request域中
model.addAttribute("model1", "modelValue1");
model.addAttribute("model2", "modelValue2");
return new ModelAndView("scope");
}
保存到org.springframework.ui.ModelMap当中,SpringMVC也会自动的把这些数据保存到request域中
@RequestMapping("/modelMapRequest")
public ModelAndView modelMap(ModelMap modelMap) {
System.out.println("这是modelMap方法保存到request域中");
//把数据保存到ModelMap中,SpringMVC会自动把这些数据保存到request域中
modelMap.addAttribute("modelMap1", "modelMapValue1");
modelMap.addAttribute("modelMap2", "modelMapValue2");
return new ModelAndView("scope");
}
隐含模型 就是Map参数,Model参数和ModelMap参数。他们三其实都是接收同一个对象实例。
/**
* BindingAwareModelMap 它叫隐含模型
* /\
* ||
* ||
* ExtendedModelMap -----实现>>>>>>Model接口
* /\
* ||
* ||
* ModelMap
* /\
* ||
* ||
* LinkedHashMap
* /\
* ||
* HashMap ------实现>>>>>> Map接口
*/
@RequestMapping(value="/test")
public ModelAndView test(Map<String, Object> map,Model model,ModelMap modelMap) {
map.put("key1", "value1");
model.addAttribute("model1", "modelValue1");
modelMap.addAttribute("modelMap1", "modelMapValue1");
System.out.println("我反倒扣分");
System.out.println(map.getClass()+"我是map");
System.out.println(model.getClass()+"我是model");
System.out.println(modelMap.getClass()+"我是modelMap");
return new ModelAndView("scope");
}
测试结果:
从结果可以看出其实就是同一个对象:隐含模型 就是Map参数,Model参数和ModelMap参数。他们三其实都是接收同一个对象实例。
2.5、ModelAndView方式保存数据到request域中
把数据保存到ModelAndView中,springMVC保存到把数据保存到Request域中
@RequestMapping(value="/modelAndViewScope")
public ModelAndView modelAndViewScope() {
ModelAndView modelAndView = new ModelAndView("scope");
System.out.println("这是modelAndViewScope方法");
// 往ModelAndView中保存数据,同样SpringMVC也会保存到request域中
modelAndView.addObject("modelAndView1", "modelAndViewValue1");
modelAndView.addObject("modelAndView2", "modelAndViewValue2");
return modelAndView;
}
页面中输出数据:
<hr/>
${ requestScope.modelAndView1 }<br/>
${ requestScope.modelAndView2 }<br/>
2.6、@SessionAttributes保存数据到Session域中(不推荐使用)
@SessionAttributes 注解可以标注在类上。它的作用是指定哪些数据可以保存到Session域中。
@SessionAttributes(value = { "key1","key2" }, types = { String.class, Book.class })
value属性,它表示把request域中key为key1,key2的键值对信息,也保存到Session中
types属性,它表示把request域中value类型为String.class或Book.class类型的键值对,也保存到Session中
@RequestMapping(value="/testSessionAttributes")
public ModelAndView testSessionAttributes(Map<String, Object> map) {
System.out.println("这是testSessionAttributes方法");
// 往map中保存数据,就会自动保存到Request域中
map.put("key1", new Long(1234));
return new ModelAndView("scope");
}
2.7、@ModelAttribute注解
@ModelAttribute这个注解可以标注在方法和参数上。
@ModelAttribute三个常见作用:
1、被标注了@ModelAttribute的方法都会在Controller的目标方法之前执行。
2、目标方法的参数(JavaBean对象,book)会先从隐含模型中获取值传入。
3、@ModelAttribute被标注在目标的参数上(即取别名),参数值会按照指定的key从隐含模型中获取值。
@ModelAttribute
public void abc(Map<String, Object> map) {
System.out.println("我是@ModelAttribute标注的abc()方法");
map.put("book111", new Book("我是一个兵!", new BigDecimal(99999999)));
}
/**
* 目标方法中,如果有对象参数(非原生API,是那些pojo对象),它会先按照参数的类型取类名,然后首字母小写book,从隐含模型中取值注入。
*/
@RequestMapping(value="/targetMethod")
public ModelAndView targetMethod(@ModelAttribute("book111")Book book) {
System.out.println("targetMethod被调用了!");
System.out.println("目标方法中book的值是:" + book);
return new ModelAndView("scope");
}