SpringMVC中的处理器方法的返回值用来指定页面跳转到哪个视图,处理器的返回值可以为String
,void
,ModelAndView
对象.
String
对象: 转发到字符串指定的URL处理器方法返回字符串可以指定逻辑视图名,通过视图解析器解析为物理视图地址.
在本例中,因为我们在Spring容器配置文件bean.xml
中配置的视图解析器中注入prefix
和suffix
属性,所以视图解析器会把处理器返回的"字符串值"
解析为"/WEB-INF/pages/字符串值.jsp"
,再请求对应视图.这是一个请求转发过程,浏览器地址栏不会发生变化.
bean.xml
中配置的视图解析器如下:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/">property>
<property name="suffix" value=".jsp">property>
bean>
处理器方法如下:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testString")
public String testString(Model model) {
// 执行方法体...向隐式对象添加属性attribute_user,可以在jsp中通过 ${attribute_user} 获取到
model.addAttribute("attribute_user", new User("张三", "123"));
// 经过视图解析器的处理,SpringMVC会将请求转发到/WEB-INF/pages/succeess.jsp,但浏览器地址栏显示的一直是 项目域名/user/testString
return "success";
}
}
void
: 转发到当前URL若处理器返回void
,表示执行完处理器方法体内代码后,不进行请求转发,而直接转发到当前URL.若没有在web.xml
中配置当前对应的url-pattern
,则会返回404
错误.
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testVoid")
public void testVoid(Model model) {
// 执行方法体...向隐式对象添加属性attribute_user,可以在jsp中通过 ${attribute_user} 获取到
model.addAttribute("attribute_user", new User("张三", "123"));
// 处理器没有返回值,则会将请求转发到当前 项目域名/user/testVoid 路径
// 若在web.xml中没有配置 项目域名/user/testVoid 对应的url-pattern,则会返回404错误
return;
}
}
可以在返回语句之前执行请求转发,重定向或getWriter
方法指定视图,示例如下:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testVoid")
public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 执行方法体...向隐式对象添加属性attribute_user,可以在jsp中通过 ${attribute_user} 获取到
model.addAttribute("attribute_user", new User("张三", "123"));
// 通过下面三个方法之一,可以指定访问的视图
// 指定视图的方式1: 请求转发
request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
// 指定视图的方式2: 重定向
response.sendRedirect(request.getContextPath() + "/index.jsp");
// 指定视图的方式3: 通过Writer对象写入内容
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("你好");
return;
}
}
ModelAndView
对象: 更灵活地添加属性和指定返回视图ModelAndView
为我们提供了一种更灵活地为页面添加属性和指定返回视图的方法,其主要方法如下:
public ModelMap getModelMap()
: 返回当前页面的ModelMap
对象.public ModelAndView addObject(Object attributeValue)
: 向当前页面的ModelMap
对象中添加属性public void setViewName(@Nullable String viewName)
: 指定返回视图,viewName
会先被视图解析器处理解析成对应视图.@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
// 创建ModelAndView对象
ModelAndView mv = new ModelAndView();
// 向model中存入属性attribute_user
mv.addObject("attribute_user", new User("张三", "123"));
// 指定返回视图,视图解析器将"success"解析为视图URL /WEB-INF/pages/succeess.jsp
mv.setViewName("success");
return mv;
}
}
要使用SpringMVC框架提供的请求转发,只需要在处理器方法返回的viewName
字符串首加上forward:
即可,要注意的是,此时forward:
后的地址不能直接被视图解析器解析,因此要写完整的相对路径.示例如下:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testForward")
public String testForward() {
// 在forward:要写完整的相对路径
// return "forward:success" // 错误,会将请求转发到 /项目名/user/success
return "forward:/WEB-INF/pages/success.jsp";
}
}
要使用SpringMVC框架提供的请求重定向,只需要在处理器方法返回的viewName
字符串首加上redirect:
即可,要注意的是,此时redirect:
后的地址要写相对于ContextPath
的地址.示例如下:
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testRedirct")
public String testRedirct() {
// 在forward:要写完整的相对路径
// return "redirect:" + request.getContextPath() + "/index.jsp"; // 错误,会将请求转发到 /项目名/项目名/index.jsp
return "redirect:/index.jsp";
}
}
jsp在页面上引入jQuery以发送json数据,因此需要向服务器发起一个对jQuery的请求.像这种对静态资源的请求,不应当经过具体的某个处理器处理,而应当直接返回对应的静态资源.
因此我们需要在Spring容器配置bean.xml
中使用
标签声明该资源为静态资源,否则请求该资源会报404
错误.该标签的属性如下:
location
属性: 表示该资源在服务器上所在的位置,必须是一个有效的目录mapping
属性: 指定匹配的URL我们在bean.xml
中配置各静态文件的位置如下:
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
要将json字符串与JavaBean对象相互转换,我们需要引用jackson
的jar包,在pom.xml
中添加依赖坐标如下:
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.0version>
在jsp页面中编写代码发送json请求如下:
<script>
// 页面加载,绑定单击事件
$(function () {
$("#btn").click(function () {
// 发送ajax请求
$.ajax({
// 配置请求参数
url: "user/testAjax",
contentType: "application/json;charset=UTF-8",
dataType: "json",
type: "post",
// 请求的json数据
data: '{"username":"myname","password":"mypassowrd","age":30}',
// 回调函数,处理服务器返回的数据returnData
success: function (returnData) {
// 我们假定服务器返回的是一个user对象,将其输出在控制台上
console.log(returnData); }
});
});
});
script>
使用@RequestBody
注解将请求体绑定到控制器方法参数上,使用@ResponseBody
注解表示将该方法的返回值直接写回到HTTP响应中,而不是存入Model
或解析为视图名.
我们引入的jackson
包自动完成从Java实体类到json数据之间的相互转换.
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/testAjax")
@ResponseBody
public User testAjax(@RequestBody User user) {
System.out.println(user);
// 将user对象返回给前端页面
return user;
}
}