表现层数据封装
介绍
1. ModelAndView
ModelAndView
是Spring MVC提供的一个对象,用于封装模型数据和视图信息。当Controller处理完用户请求后,会返回一个ModelAndView
对象给DispatcherServlet,DispatcherServlet再解析这个对象,找到对应的视图,并将模型数据传递给视图进行渲染。
java
@RequestMapping("/hello")
public ModelAndView hello() {
ModelAndView mv = new ModelAndView();
mv.addObject("message", "Hello, World!");
mv.setViewName("hello");
return mv;
}
2. ModelMap
ModelMap
是一个实现了Map<String, Object>
接口的类,用于存储模型数据。Spring MVC会自动将ModelMap
中的数据添加到请求对象中,从而可以在视图中访问。
在Controller的方法中,可以通过添加ModelMap
类型的参数来接收模型数据,或者返回ModelAndView
时通过addObject
方法添加数据。
java
@RequestMapping("/hello")
public String hello(ModelMap model) {
model.addAttribute("message", "Hello, World!");
return "hello";
}
3. @ModelAttribute
@ModelAttribute
注解可以用在方法上或参数上。当用在方法上时,表示该方法的返回值会自动添加到模型中。当用在参数上时,表示该参数的值将从请求参数、路径变量、Session或Model中自动获取。
- 用在方法上
java
@ModelAttribute
public void populateModel(@RequestParam String userId, Model model) {
User user = userService.getUser(userId);
model.addAttribute("user", user);
}
- 用在参数上
java
@RequestMapping("/editUser")
public String editUser(@ModelAttribute("user") User user) {
// 这里user对象的属性已经根据请求参数被填充
return "editUser";
}
4. @RequestParam 和 @PathVariable
@RequestParam
用于将请求参数绑定到你的控制器处理方法的参数上。
java
@RequestMapping("/user")
public String getUser(@RequestParam("id") String userId) {
// 使用userId...
return "user";
}
@PathVariable
用于将URL模板变量绑定到你的控制器处理方法的参数上。
java
@RequestMapping("/user/{userId}")
public String getUser(@PathVariable("userId") String userId) {
// 使用userId...
return "user";
}
1 表现层响应数据的问题
问题:我们表现层增删改方法返回true或者false表示是否成功,getById()方法返回一个json对象,getAll()方法返回一个json对象数组,这里就出现了三种格式的响应结果,极其不利于前端解析。
解决:我们需要统一响应结果的格式
2 定义Result类封装响应结果
2.1 Result类封装响应结果
java
public class Result {
//描述统一格式中的数据
private Object data;
//描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
private Integer code;
//描述统一格式中的消息,可选属性
private String msg;
public Result() {
}
public Result(Integer code,Object data) {
this.data = data;
this.code = code;
}
public Result(Integer code, Object data, String msg) {
this.data = data;
this.code = code;
this.msg = msg;
}
//同学们自己添加getter、setter、toString()方法
}
注意事项:
Result类中的字段并不是固定的,可以根据需要自行增减
2.2 Code类封装响应码
java
//状态码
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer GET_ERR = 20040;
}
注意事项:
Code类的常量设计也不是固定的,可以根据需要自行增减,例如将查询再进行细分为GET_OK,GET_ALL_OK,GET_PAGE_OK
3 表现层数据封装返回Result对象
java
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@PostMapping
public Result save(@RequestBody Book book) {
boolean flag = bookService.save(book);
return new Result(flag ? Code.SAVE_OK:Code.SAVE_ERR,flag);
}
@PutMapping
public Result update(@RequestBody Book book) {
boolean flag = bookService.update(book);
return new Result(flag ? Code.UPDATE_OK:Code.UPDATE_ERR,flag);
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
boolean flag = bookService.delete(id);
return new Result(flag ? Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
Book book = bookService.getById(id);
Integer code = book != null ? Code.GET_OK : Code.GET_ERR;
String msg = book != null ? "" : "数据查询失败,请重试!";
return new Result(code,book,msg);
}
@GetMapping
public Result getAll() {
List<Book> bookList = bookService.getAll();
Integer code = bookList != null ? Code.GET_OK : Code.GET_ERR;
String msg = bookList != null ? "" : "数据查询失败,请重试!";
return new Result(code,bookList,msg);
}
}