Spring MappingJackson2JsonView的使用

本文介绍了如何使用MappingJackson2JsonView处理Spring MVC中的异常,特别是自定义验证异常。当接收到错误的请求数据时,通过全局异常处理器将异常信息转化为JSON并返回,避免了跳转到错误页面,提高了API的响应效率。同时,文章展示了前端如何通过Ajax处理这些错误信息。
摘要由CSDN通过智能技术生成

⭕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"));
	}
}

⚡五. 效果

在这里插入图片描述

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值