⭕MappingJackson2JsonView作用
原本ModelAndView会返回视图,并且可以携带数据展示到视图中
MappingJackson2JsonView
可以让ModelAndView不返回视图,仅仅返回JSON数据,
⏹一. 前台
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MappingJackson2JsonView的使用</title>
</head>
<body>
<button id="btn">点击发送请求</button>
</body>
<script src="/js/public/jquery-3.6.0.min.js"></script>
<script th:inline="javascript">
function doAjax(url, data, callback) {
$.ajax({
url: url,
type: 'POST',
data: JSON.stringify(data),
contentType : 'application/json;charset=utf-8',
dataType: 'json',
success: function (data, status, xhr) {
if (!!callback) {
callback(data);
}
},
error: function (xhr, textStatus, errorMessage) {
if (xhr.status !== 400) {
location.href = "系统错误页面URL";
}
// 获取错误信息,根据错误ID将画面上的错误信息标记红色
const data = xhr.responseJSON;
console.log(data.errors);
}
});
}
$("#btn").click(() => {
const url = "http://localhost:8080/test3/check";
// 错误的数据,from的值不应该比to还要大
const info = {
from: 100,
to: 10
};
doAjax(url, info, function (data) {
if (!data.result) {
return;
}
console.log(data);
});
});
</script>
</html>
⏹二. 后台业务层
@Controller
@RequestMapping("/test3")
public class Test3Controller {
@Autowired
private Test3Service service;
@PostMapping("/check")
public void check(@RequestBody Test3Form form) {
service.check(form);
}
}
// ------------------------------------------------------
@Service
public class Test3Service {
public void check(Test3Form form) {
// 如果from的值比to还要大的话,就抛出自定义异常
if (form.getFrom() > form.getTo()) {
List<ErrorItemEntity> errors = Collections.singletonList(ErrorItemEntity.of("大小不对", "id名称"));
throw new ValidationException(errors);
}
}
}
⏹三. 后台自定义校验异常
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.ArrayList;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class ValidationException extends RuntimeException {
// 错误信息
private List<ErrorItemEntity> errors;
/**
* 生成ValidationException异常对象
*
* @param errors 业务异常信息
*/
public ValidationException(List<ErrorItemEntity> errors) {
super();
this.errors = errors;
}
}
⏹四. 后台全局异常捕获
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ControllerAdvice
public class GlobalExceptionHandler {
// 捕获我们自定义的校验异常
@ExceptionHandler(ValidationException.class)
public ModelAndView handleException(ValidationException ex, HttpServletRequest request, HttpServletResponse response) {
// 自定义结果封装类
ResultEntity resultEntity = ResultEntity.ng();
// 校验失败,返回400的状态码
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
if (ex.getErrors() != null) {
resultEntity.setErrors(ex.getErrors());
}
// 如果是Ajax请求的话
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
// 🥳MappingJackson2JsonView的作用是把model转换为json
MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
/*
🧐避免返回给前台的json数据多套一层key
如果我们不加.setExtractValueFromSingleKeyModel(true)的话
前台得到的json数据如下,或者为空
{
jsonKey: {
具体的json数据
}
}
🧐如果我们添加了.setExtractValueFromSingleKeyModel(true)的话
前台得到的json数据为
{
具体的json数据
}
*/
jsonView.setExtractValueFromSingleKeyModel(true);
// 👌ModelAndView是通过MappingJackson2JsonView构成的,因此并不定位到视图,而是返回json数据
ModelAndView mv = new ModelAndView(jsonView);
mv.addObject("jsonKey", resultEntity);
return mv;
}
// 重定向到错误页面
return new ModelAndView(new RedirectView(request.getContextPath() + "/systemError"));
}
}