ssm整合 表现层与前端数据传输协议
表现层数据封装
演示:
要返回统一格式Result,则定义一个类用来封装返回数据:
多定义几个构造方法,方便返回对象时造对象。
再将UserController类里面的方法的返回值都设置为Result,将结果封装(其中三元运算符使用的妙):
package com.example.controller;
import com.example.domain.User;
import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController //@Controller+@ResponseBody
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@PostMapping
public Result save(@RequestBody User user) {
Boolean flag = userService.save(user);
return new Result(flag? Code.SAVE_OK:Code.SAVE_ERR,flag);
}
@PutMapping
public Result update(@RequestBody User user) {
Boolean flag = userService.update(user);
return new Result(flag?Code.UPDATE_OK:Code.UPDATE_ERR,flag);
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
Boolean flag = userService.delete(id);
return new Result(flag?Code.DELETE_OK:Code.DELETE_ERR,flag);
}
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
User user = userService.getById(id);
Integer code=user!=null? Code.GET_OK:Code.GET_ERR;
String msg=user!=null? "":"数据查询失败,请重试!";
return new Result(code,user,msg);
}
@GetMapping
public Result getAll() {
List<User> users = userService.getAll();
Integer code=users!=null? Code.GET_OK:Code.GET_ERR;
String msg=users!=null? "":"数据查询失败,请重试!";
return new Result(code,users,msg);
}
}
最后使用postman测试接口:
修改数据:
查询数据:
查询不存在的数据:
新增数据:
返回的数据类型统一。
ssm整合 异常处理器
异常处理器用的是AOP编程,在不改变原代码的基础上,增添新的异常处理机制。不论在哪一层发生异常,都往上抛,最后到表现层统一处理。
演示:在controller包下新建一个异常处理类ProjectExceptAdvice
package com.example.controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class)
public Result doException(Exception ex){
System.out.println("");
return new Result(888,null,"发生异常!"); //数据直接返回前端。
}
}
两个注解意义:
通过@ExceptiponHandler指定处理的异常,可以定义多个方法用来根据不同的异常返回不同的结果。
演示:
我们在Get查询内写出一个异常:
再用postman来测试这个接口:
结果返回的为ProjectExceptionAdvice内设定的Result,异常处理成功!
ssm整合 项目异常处理方案
演示:
添加异常码:
定义SystemException异常:
package com.example.exception;
public class SystemException extends RuntimeException{
private Integer code;
public SystemException() {
}
public SystemException( Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code,String message, Throwable cause) {
super(message, cause);
this.code = code;
}
/**
* 获取
* @return code
*/
public Integer getCode() {
return code;
}
/**
* 设置
* @param code
*/
public void setCode(Integer code) {
this.code = code;
}
public String toString() {
return "SystemException{code = " + code + "}";
}
}
BusinessException异常与其内容一致,区别在于名字不同。
修改异常处理器里面内容,将SystemException异常与BusinessException异常的处理加上
package com.example.controller;
import com.example.exception.BusinessException;
import com.example.exception.SystemException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(SystemException.class) //处理SystemException异常
public Result doSystemException(SystemException ex) {
//记录日志
//通知运维
//发送邮件给开发人员
return new Result(ex.getCode(), null, ex.getMessage()); //数据直接返回前端。
}
@ExceptionHandler(BusinessException.class) //处理BusinessException异常
public Result doBusinessException(BusinessException ex) {
return new Result(ex.getCode(), null, ex.getMessage());
}
@ExceptionHandler(Exception.class) //处理所有的Exception异常
public Result doException(Exception ex) {
//记录日志
//通知运维
//发送邮件给开发人员
return new Result(Code.SYSTEM_UNKNOW_ERR, null, "系统繁忙,请稍后再试!"); //数据直接返回前端。
}
}
在UserServiceimpl中刻意触发异常,测试返回结果是否达到预期:
运行并用postman测试:
ssm整合 前后台协议联调
列表功能
先将黑马资料中的web资料拷贝到webapp目录下:
再在config包下新建一个类,用来加载web网页(让springMvc放行):
package com.example.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
启动项目,到浏览器打开:
将启动的钩子方法与查询全部的方法绑定:
最终效果:
(我的数据是先前的用户数据,而不是图书数据,不要紧不要紧)
OK ,花费了一些时间,找到了老师的tbl_book表,将数据传上去了。
添加功能
要想点击新建后,将有新建功能的表单显示出来,则需设置点击后绑定方法。
新建按钮绑定的为handleCreate方法。
新增标签弹窗可视化绑定的是dialogFormVisible变量,默认为不可见。
点击后可见。
弹出的表单:
找到“确定”按钮绑定的方法:
post为新增操作,操作成功,关闭弹层,并查询全部(动态更新)。
结果演示:
新增数据后,自动关闭弹层且查询全部。
添加功能状态处理
添加成功,会执行上面的操作,倘若添加失败呢?
先判断添加成功还是失败:
this.$message.success() 为成功的弹窗,.error()则为失败的弹窗。
先前的service代码中,添加,更新,删除操作返回的无论如何都是true,无法判断操作到底失败还是成功。现在改返回值为影响到的行数,通过行数来判断,影响的行数大于0,则成功,否则失败。
(保存,更新,删除的sql语句操作都是默认返回影响的行数)
其中,res.data.code是达不到20010的,因为添加失败都会是sql语句有问题,会走“其他异常”这条路。返回的是msg。
修改功能
要想修改,首先应该让点击编辑后修改的表单能弹出,与先前添加操作类似。
不过修改操作弹出的表单应该是有数据在里面的,所以应该先进行查询操作,根据id查询。前端代码已经能够获得点击行的id(row.id),我们只需要执行查询操作即可。
记得将先前在查询那里刻意制造的异常删去,不然弹窗将不会弹出。
查询完后,执行更新操作。
更新操作与新增操作几乎无区别,将post改成put,将状态码修改后,再将弹出的语句修改即可。
(修改完后还需将编辑的弹窗关闭)
删除功能
删除操作与先前的最大不同就是删除还要再次确认是否删除。
首先,弹出确认提示框:
按下确定后,执行删除操作:
与先前的更新类似。
如若按取消,则弹出提示取消删除。
完整代码即为:
// 删除
handleDelete(row) {
//1.弹出提示框
this.$confirm("此操作永久删除当前数据,是否继续?", "提示", {
type: 'info'
}).then(() => {
//2.删除
axios.delete("/books/" + row.id).then((res) => {
if (res.data.code == 20021) { //删除成功
this.$message.success("删除成功");
} else {
this.$message.error("删除失败");
}
}).finally(() => {
this.getAll();
});
}).catch(() => {
//3.取消删除
this.$message.info("取消删除操作");
});
}
ssm整合确实挺不错,将先前学的东西整合到一起,不至于说学的东西还是不知道有什么用,怎么用。与前端的通信这部分也应适当掌握。
以上内容均学自B站黑马ssm教程