JSP页面的转发和重定向
Spring MVC 默认以转发的形式响应 JSP,可以⼿动进⾏修改。
⭐重定向
@RequestMapping("/restful/{id}/{name}")
public String restful(@PathVariable("id") Integer id,@PathVariable("name")
String name){
System.out.println(id+"-"+name);
return "redirect:/index.jsp";
}
设置重定向的时候不能写逻辑视图,必须写明资源的物理路径,如“redirect:/index.jsp”
⭐转发
@RequestMapping("/restful/{id}/{name}")
public String restful(@PathVariable("id") Integer id,@PathVariable("name")
String name){
System.out.println(id+"-"+name);
return "forward:/index.jsp";
}
等同于
@RequestMapping("/restful/{id}/{name}")
public String restful(@PathVariable("id") Integer id,@PathVariable("name")
String name){
System.out.println(id+"-"+name);
return "index";
}
Spring MVC 数据绑定
数据绑定:在后台业务⽅法中,直接获取前端 HTTP 请求中的参数。
HTTP 请求传输的参数都是 String 类型的,Handler 业务⽅法中的参数是开发者指定的数据类型,int、Integer、Object,因此需要进⾏数据类型的转换。
Spring MVC 的 HandlerAdapter 组件会在执⾏ Handler 业务⽅法之前,完成参数的绑定,开发者直接使⽤即可。
- ⭐基本数据类型
@RequestMapping("/baseType")
@ResponseBody
public String baseType(int id){
return "id:"+id;
}
客户端 HTTP 请求中必须包含 id 参数,否则抛出 500 异常,因为 id 不能为 null。
同时 id 的值必须为数值且必须为整数,否则抛出 400 异常。
- ⭐包装类
@RequestMapping("/packageType")
@ResponseBody
public String packageType(Integer id){
return "id:"+id;
}
如果 HTTP 请求中没有包含 id 参数,不会报错,id 的值就是 null,会直接返回 id:null 给客户端。但是如果 id = a 或者 id = 1.5,同样会抛出 400 异常,因为数据类型⽆法匹配。
可以给参数列表添加 @RequestParam 注解,可以对参数进⾏相关设置。
@RequestMapping("/packageType")
@ResponseBody
public String packageType(@RequestParam(value = "id",required =
true,defaultValue = "0") Integer id){
return "id:"+id;
}
- ⭐value = “id”:将 HTTP 请求中名为 id 的参数与 Handler 业务⽅法中的形参进⾏映射。
- ⭐required:ture 表示 id 参数必填,false 表示⾮必填。
- ⭐defaultValue = “0”:表示当 HTTP 请求中没有 id 参数时,形参的默认值为 0。
数组
@RequestMapping("/arrayType")
@ResponseBody
public String arrayType(String[] names){
StringBuffer stringBuffer = new StringBuffer();
for (String str:names){
stringBuffer.append(str).append(" ");
}
return "names:"+stringBuffer.toString();
}
POJO
package com.southwind.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private Address address;
}
package com.southwind.entity;
import lombok.Data;
@Data
public class Address {
private Integer code;
private String value;
}
<%--
Created by IntelliJ IDEA.
User: southwind
Date: 2020-02-07
Time: 16:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head> <body>
<form action="/hello/add" method="post">
<table>
<tr>
<td>编号:</td>
<td>
<input type="text" name="id"/>
</td>
</tr>
<tr>
<td>姓名:</td>
<td>
<input type="text" name="name"/>
</td>
</tr>
<tr>
<td>地址编号:</td>
<td>
<input type="text" name="address.code"/>
</td>
</tr>
<tr>
<td>地址信息:</td>
<td>
<input type="text" name="address.value"/>
</td>
</tr>
<tr>
<td>
<input type="submit" value="提交"/>
</td>
</tr>
</table>
</form>
</body>
</html>
@RequestMapping(value = "/add",method = RequestMethod.POST)
@ResponseBody
public String add(User user){
return user.toString();
}
解决响应时乱码问题,springmvc.xml 中配置转换器即可。
<mvc:annotation-driven>
<!-- 消息转换器 -->
<mvc:message-converters>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-
8"></property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
List
Spring MVC 不⽀持 List 类型的直接转换,需要包装成 Object。
List 的⾃定义包装类
package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class UserList {
private List<User> users;
}
业务方法
@RequestMapping("/listType")
@ResponseBody
public String listType(UserList users){
StringBuffer stringBuffer = new StringBuffer();
for(User user:users.getUsers()){
stringBuffer.append(user);
}
return "⽤户:"+stringBuffer.toString();
}
JSP
<%--
Created by IntelliJ IDEA.
User: southwind
Date: 2020-02-08
Time: 15:16
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html> <head>
<title>Title</title>
</head> <body>
<form action="/hello/listType" method="post">
⽤户1ID:<input type="text" name="users[0].id"/><br/>
⽤户1姓名:<input type="text" name="users[0].name"/><br/>
⽤户2ID:<input type="text" name="users[1].id"/><br/>
⽤户2姓名:<input type="text" name="users[1].name"/><br/>
⽤户3ID:<input type="text" name="users[2].id"/><br/>
⽤户3姓名:<input type="text" name="users[2].name"/><br/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
需要注意的是 User 类⼀定要有⽆参构造函数,否则抛出异常。
JSON
JSP
<%--
Created by IntelliJ IDEA.
User: southwind
Date: 2020-02-08
Time: 15:25
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html> <head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script type="text/javascript">
$(function(){
var user = {
"id":1,
"name":"张三"
};
$.ajax({
url:"/hello/jsonType",
data:JSON.stringify(user),
type:"POST",
contentType:"application/json;charset=UTF-8",
dataType:"JSON",
success:function(data){
alert(data.id)
alert(data.name)
}
})
})
</script>
</head> <body>
</body>
</html>
注意
- ⭐JSON 数据必须⽤ JSON.stringify() ⽅法转换成字符串
- ⭐contentType:“application/json;charset=UTF-8” 不能省略
业务方法
@RequestMapping("/jsonType")
@ResponseBody
public User jsonType(@RequestBody User user){
System.out.println(user);
user.setId(2);
return user;
}
@RequestBody 注解
读取 HTTP 请求参数,通过 Spring MVC 提供的 HttpMessageConverter 接⼝将读取的参数转为
JSON、XML 格式的数据,绑定到业务⽅法的形参。
@ResponseBody 注解
将业务⽅法返回的对象,通过 HttpMessageConverter 接⼝转为指定格式的数据,JSON、XML 等,响应给客户端。
需要使⽤组件结合 @RequestBody 注解将 JSON 转为 Java Bean,这⾥使⽤ FastJson,其优势时候如果属性为空就不会将其转为 JSON。
如何使⽤ FastJson
- pom.xml 中添加 FastJson 相关依赖。
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
- springmvc.xml 中配置 FastJson。
<mvc:annotation-driven>
<!-- 消息转换器 -->
<mvc:message-converters>
<bean
class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-
8"></property>
</bean>
<!-- fastjson -->
<bean
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4">
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
Spring MVC 视图层解析
调⽤ Web 资源给域对象传值
page
request
session
application
业务数据的绑定是指将业务数据绑定给 JSP 域对象,业务数据的绑定是由 ViewResolver 来完成的,开
发时,我们先添加业务数据,再交给 ViewResolver 来绑定,因此学习的重点在于如何添加业务数据,
Spring MVC 提供了以下⼏种⽅式来添加业务数据:
- ⭐Map
- ⭐Model
- ⭐ModelAndView
- ⭐@SessionAttribute
- ⭐@ModelAttribute
- ⭐Servlet API
业务数据绑定到 request 域对象
Map
Spring MVC 在调⽤业务⽅法之前会创建⼀个隐含对象作为业务数据的存储容器,设置业务⽅法的⼊参为 Map 类型,Spring MVC 会将隐含对象的引⽤传递给⼊参。
@RequestMapping("/map")
public String map(Map<String,Object> map){
User user = new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
return "show";
}
<%--
Created by IntelliJ IDEA.
User: southwind
Date: 2020-02-08
Time: 18:05
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html> <head>
<title>Title</title>
</head> <body>
${requestScope.user}
</body>
</html>
Model
Model 与 Map 类似,业务⽅法通过⼊参来完成业务数据的绑定。
@RequestMapping("/model")
public String model(Model model){
User user = new User();
user.setId(1);
user.setName("张三");
model.addAttribute("user",user);
return "show";
}
ModelAndView
与 Map 或者 Model 不同的是,ModelAndView 不但包含业务数据,同时也封装了视图信息,如果使⽤
ModelAndView 来处理业务数据,业务⽅法的返回值必须是 ModelAndView 对象。
业务⽅法中对 ModelAndView 进⾏两个操作:
- 填充业务数据
- 绑定视图信息
@RequestMapping("/mav1")
public ModelAndView modelAndView1(){
ModelAndView modelAndView = new ModelAndView();
User user = new User();
user.setId(1);
user.setName("张三");
//填充业务数据
modelAndView.addObject("user",user);
//绑定视图信息
modelAndView.setViewName("show");
return modelAndView; }
@RequestMapping("/mav2")
public ModelAndView modelAndView2(){
ModelAndView modelAndView = new ModelAndView();
User user = new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
View view = new InternalResourceView("/show.jsp");
modelAndView.setView(view);
return modelAndView; }
@RequestMapping("/mav3")
public ModelAndView modelAndView3(){
ModelAndView modelAndView = new ModelAndView("show");
User user = new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
return modelAndView; }
@RequestMapping("/mav4")
public ModelAndView modelAndView4(){
View view = new InternalResourceView("/show.jsp");
ModelAndView modelAndView = new ModelAndView(view);
User user = new User();
user.setId(1);
user.setName("张三");
modelAndView.addObject("user",user);
return modelAndView; }
@RequestMapping("/mav5")
public ModelAndView modelAndView5(){
Map<String,Object> map = new HashMap<>();
User user = new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
ModelAndView modelAndView = new ModelAndView("show",map);
return modelAndView; }
@RequestMapping("/mav6")
public ModelAndView modelAndView6(){
Map<String,Object> map = new HashMap<>();
User user = new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
View view = new InternalResourceView("/show.jsp");
ModelAndView modelAndView = new ModelAndView(view,map);
return modelAndView; }
@RequestMapping("/mav7")
public ModelAndView modelAndView7(){
User user = new User();
user.setId(1);
user.setName("张三");
ModelAndView modelAndView = new ModelAndView("show","user",user);
return modelAndView; }
@RequestMapping("/mav8")
public ModelAndView modelAndView8(){
User user = new User();
user.setId(1);
user.setName("张三");
View view = new InternalResourceView("/show.jsp");
ModelAndView modelAndView = new ModelAndView(view,"user",user);
return modelAndView; }