三 后台环境登搭建 - 10.异常映射

10. 异常映射

支点: git checkout -b 3.10.0_exception_mapping

10.1 目标和思路

10.1.1 目标
  • 使用异常映射机制将整个项目的异常和错误提示进行统一管理
10.1.2 思路

img

10.1.3 注意: SpringMVC 提供了 基于 XML 和 基于注解两种异常映射机制

img

10.2 基于 XML 的异常映射

10.2.1 XML 配置

img

    <!-- 配置基于 XML 的异常映射 -->
    <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 配置异常类型和具体视图页面的对应关系 -->
        <property name="exceptionMappings">
            <props>
                <!-- key 属性指定异常类全名 -->
                <!-- 标签体中写对应的视图 (这个值会拼前后缀得到具体路径) -->
                <prop key="java.lang.Exception">system-error</prop>
            </props>
        </property>
    </bean>
10.2.2 新建错误页面

img

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>错误</title>
</head>
<body>

<h1>出错了</h1>

<!-- 从请求域取出 Exception 对象, 再近一步访问 message 属性就能够显示错误信息 -->
${requestScope.exception.message}
</body>
</html>
10.2.3 测试
  • TestHandler.java
    @RequestMapping("/test/ssm.html")
    public String testSsm(ModelMap modelMap) {
        List<Admin> adminList = adminService.getAll();
        System.out.println(adminList);
        modelMap.addAttribute("adminList", adminList);
        modelMap.addAttribute("adminList2", adminList);
        modelMap.addAttribute("adminList4", adminList);

        System.out.println(10 / 0);

        return "/target";
    }
  • 显示错误信息

img

10.3 判断请求类型的工具方法

img

10.3.1 CrowdUtil.java

img

package com.atguigu.crowd.util;

import javax.servlet.http.HttpServletRequest;

public class CrowdUtil {

    /**
     * 判断当前请求是否为 Ajax 请求
     *
     * @param request 请求对象
     * @return true: 当前请求是 Ajax 请求
     * false: 当前请求不是 Ajax 请求
     */
    public static boolean judgeRequestType(HttpServletRequest request) {
        // 1. 获取请求消息头
        String acceptHeader = request.getHeader("Accept");
        String xRequestedWith = request.getHeader("X-Requested-With");

        // 2. 判断
        return (acceptHeader != null && acceptHeader.contains("application/json"))
                ||
                ("XMLHttpRequest".equals(xRequestedWith));
    }

}
  • 测试 判断请求类型的工具方法 - TestHandler.java

    • judgeResult: true
    @ResponseBody
    @RequestMapping("/send/compose/object2.json")
    public ResultEntity<Student> testReceiveComposeObject2(@RequestBody Student student, HttpServletRequest request) {
        boolean judgeResult = CrowdUtil.judgeRequestType(request);
        Logger logger = LoggerFactory.getLogger(TestHandler.class);
        logger.info("judgeResult: " + judgeResult);

        logger.info(student.toString());

        // 将"查询"到的 Student 对象封装到 ResultEntity 中返回
        return ResultEntity.successWithData(student);
    }
    • judgeResult: false
    @RequestMapping("/test/ssm.html")
    public String testSsm(ModelMap modelMap, HttpServletRequest request) {
        boolean judgeResult = CrowdUtil.judgeRequestType(request);
        Logger logger = LoggerFactory.getLogger(TestHandler.class);
        logger.info("judgeResult: " + judgeResult);

        List<Admin> adminList = adminService.getAll();
        System.out.println(adminList);
        modelMap.addAttribute("adminList", adminList);
        modelMap.addAttribute("adminList2", adminList);
        modelMap.addAttribute("adminList4", adminList);

//        System.out.println(10 / 0);

        return "/target";
    }
10.3.2 pom.xml 需要的依赖

atcrowdfunding05-common-util

<dependencies>
    <!-- 引入 Servlet 容器中相关依赖 -->
    <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

10.4 基于注解的异常映射

10.4.1 CrowdUtil.java

img

package com.atguigu.crowd.mvc.config;

import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ControllerAdvice: 表示当前类是一个基于注解的异常处理器类
 */
@ControllerAdvice
public class CrowdExceptionResolver {

    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView resolveNullPointerException(
            ArithmeticException exception,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {
        String viewName = "system-error";
        return commonExceptionResolver(viewName, exception, request, response);
    }

    /**
     * @ExceptionHandler: 将一个具体的异常类型和一个方法关联起来
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = NullPointerException.class)
    public ModelAndView resolveNullPointerException(
            NullPointerException exception,
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {
        String viewName = "system-error";
        return commonExceptionResolver(viewName, exception, request, response);
    }

    public static ModelAndView commonExceptionResolver(
            // 跳转的视图
            String viewName,
            // 实例捕获到的异常类型
            Exception exception,
            // 当前请求对象
            HttpServletRequest request,
            HttpServletResponse response
    ) throws IOException {
        // 1. 判断请求类型
        boolean judgeRequestType = CrowdUtil.judgeRequestType(request);

        // 2. 如果是 Ajax 请求
        if (judgeRequestType) {
            // 3. 创建 ResultEntity 对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());

            // 4. 创建 Gson 对象
            Gson gson = new Gson();

            // 5. 将 ResultEntity 对象转换为 JSON 对象
            String json = gson.toJson(resultEntity);

            // 6. 将 JSON 字符串作为响应体返回
            response.getWriter().write(json);

            // 7. 由于上面已经通过原生的 response 对象返回了响应, 所以不提供 ModelAndView 对象
            return null;
        }

        // 8. 如果不是 Ajax 请求则创建 ModelAndView 对象
        ModelAndView modelAndView = new ModelAndView();

        // 9. 将 Exception 对象存入模型
        modelAndView.addObject("exception", exception);

        // 10. 设置对应的视图名称
        modelAndView.setViewName(viewName);

        // 11. 返回 ModelAndView 对象
        return modelAndView;
    }

}
  • 测试非Ajax请求 - TestHandler.java
    @RequestMapping("/test/ssm.html")
    public String testSsm(ModelMap modelMap, HttpServletRequest request) {
        boolean judgeResult = CrowdUtil.judgeRequestType(request);
        Logger logger = LoggerFactory.getLogger(TestHandler.class);
        logger.info("judgeResult: " + judgeResult);

        List<Admin> adminList = adminService.getAll();
        System.out.println(adminList);
        modelMap.addAttribute("adminList", adminList);
        modelMap.addAttribute("adminList2", adminList);
        modelMap.addAttribute("adminList4", adminList);

//        System.out.println(10 / 0);

        String a = null;
        System.out.println(a.length());

        return "/target";
    }

img

  • 测试Ajax请求 - TestHandler.java
    @ResponseBody
    @RequestMapping("/send/compose/object2.json")
    public ResultEntity<Student> testReceiveComposeObject2(@RequestBody Student student, HttpServletRequest request) {
        String a = null;
        System.out.println(a.length());
        
        boolean judgeResult = CrowdUtil.judgeRequestType(request);
        Logger logger = LoggerFactory.getLogger(TestHandler.class);
        logger.info("judgeResult: " + judgeResult);

        logger.info(student.toString());

        // 将"查询"到的 Student 对象封装到 ResultEntity 中返回
        return ResultEntity.successWithData(student);
    }

img

10.5 Push

img

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值