javaweb异常提示信息统一处理(使用springmvc,附源码)

简介:

目录(?)[+]

一、前言

后台出现异常如何友好而又高效地回显到前端呢?直接将一堆的错误信息抛给用户界面,显然不合适。

先不考虑代码实现,我们希望是这样的:

(1)如果是页面跳转的请求,出现异常了,我们希望跳转到一个异常显示页面,如下:

这里写图片描述

当然,这里的界面不够美观,但是理论是这样的。

(2)如果是ajax请求,那么我们,希望后台将合理的错误显示返回到ajax的回调函数里面,如下:

$.ajax({ 
    type: "post", 
    url: "<%=request.getContextPath()%>" + "/businessException.json", 
    data: {}, 
    dataType: "json", 
    contentType : "application/json",
    success: function(data) { 
        if(data.success == false){
            alert(data.errorMsg);
        }else{
            alert("请求成功无异常"); 
        }
    },
    error: function(data) { 
        alert("调用失败...."); 
    }
});

   
   

    将回调函数的data.errorMsg打印出来:

    这里写图片描述

    下面,我们根据上面的思路我们来看看代码的实现。因此本文实例包含了异常自定义分装,为了无障碍阅读下文,请猿友移步先看完博主的另外一篇文章:Java异常封装(自己定义错误码和描述,附源码)

    二、实例详解

    本实例使用的环境 eclipse+maven,其中maven只是为了方便引入jar包。 
    使用的技术:springmvc

    spring MVC中,所有用于处理在请求映射和请求处理过程中抛出的异常的类,都要实现HandlerExceptionResolver接口。HandlerExceptionResolver接口有一个方法resolveException,当controller层出现异常之后就会进入到这个方法resolveException。

    下面我们直接实现HandlerExceptionResolver接口,代码如下:

    package com.luo.exceptionresolver;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.Map;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.web.servlet.ModelAndView;
    import com.alibaba.druid.support.json.JSONUtils;
    import com.luo.exception.BusinessException;
    import org.springframework.web.servlet.HandlerExceptionResolver;
    
    public class MySimpleMappingExceptionResolver implements
            HandlerExceptionResolver {
    
        public ModelAndView resolveException(HttpServletRequest request,
                HttpServletResponse response, Object object, Exception exception) {
            // 判断是否ajax请求
            if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
                    .getHeader("X-Requested-With") != null && request.getHeader(
                    "X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
                // 如果不是ajax,JSP格式返回
                // 为安全起见,只有业务异常我们对前端可见,否则否则统一归为系统异常
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("success", false);
                if (exception instanceof BusinessException) {
                    map.put("errorMsg", exception.getMessage());
                } else {
                    map.put("errorMsg", "系统异常!");
                }
                //这里需要手动将异常打印出来,由于没有配置log,实际生产环境应该打印到log里面
                exception.printStackTrace();
                //对于非ajax请求,我们都统一跳转到error.jsp页面
                return new ModelAndView("/error", map);
            } else {
                // 如果是ajax请求,JSON格式返回
                try {
                    response.setContentType("application/json;charset=UTF-8");
                    PrintWriter writer = response.getWriter();
                    Map<String, Object> map = new HashMap<String, Object>();
                    map.put("success", false);
                    // 为安全起见,只有业务异常我们对前端可见,否则统一归为系统异常
                    if (exception instanceof BusinessException) {
                        map.put("errorMsg", exception.getMessage());
                    } else {
                        map.put("errorMsg", "系统异常!");
                    }
                    writer.write(JSONUtils.toJSONString(map));
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    }
    
    
     
     

      上面的代码,归结为以下几点: 
      (1)判断如果不是ajax请求,那么统一跳转到error.jsp页面,否则返回json数据。 
      (2)如果是业务异常,我们直接打印异常信息,否则,我们统一归为系统异常,如果不明白这里的业务异常为何物,请阅读博主博客:Java异常封装(自己定义错误码和描述,附源码)

      另外,需要在springmvc配置文件添加如下配置:

      <!-- 框架异常处理Handler -->
      <bean id="exceptionResolver" class="com.luo.exceptionresolver.MySimpleMappingExceptionResolver"></bean>
      
       
       

        下面我们直接看controller代码:

        package com.luo.controller;
        
        import javax.servlet.http.HttpServletRequest;
        import org.springframework.stereotype.Controller;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.ResponseBody;
        import org.springframework.web.servlet.ModelAndView;
        import com.luo.errorcode.LuoErrorCode;
        import com.luo.exception.BusinessException;
        
        @Controller
        public class UserController {
        
            @RequestMapping("/index.jhtml")
            public ModelAndView getIndex(HttpServletRequest request) throws Exception {
                ModelAndView mav = new ModelAndView("index");
                return mav;
            }
        
            @RequestMapping("/exceptionForPageJumps.jhtml")
            public ModelAndView exceptionForPageJumps(HttpServletRequest request) throws Exception {
                throw new BusinessException(LuoErrorCode.NULL_OBJ);
            }
        
            @RequestMapping(value="/businessException.json", method=RequestMethod.POST)
            @ResponseBody  
            public String businessException(HttpServletRequest request) {
                throw new BusinessException(LuoErrorCode.NULL_OBJ);
            }
        
            @RequestMapping(value="/otherException.json", method=RequestMethod.POST)
            @ResponseBody  
            public String otherException(HttpServletRequest request) throws Exception {
                throw new Exception();
            }
        
        }
        
        
         
         

          关于controller代码没什么好解释的,下面我们直接看结果吧:

          (1)如果跳转页面过程中出现异常,访问http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml的结果:

          这里写图片描述

          (2)如果ajax请求过程中出现异常,访问http://localhost:8080/web_exception_project/index.jhtml,然后,点击业务异常按钮结果:

          这里写图片描述

          点击其他异常按钮结果:

          这里写图片描述

          (3)HandlerExceptionResolver接口并不能处理404错误,这种错误我们再web.xml里面添加如下配置:

          <!-- 错误跳转页面 -->
          <error-page>
              <!-- 路径不正确 -->
              <error-code>404</error-code>
              <location>/WEB-INF/view/404.jsp</location>
          </error-page>
          
           
           

            然后404.jsp代码如下:

            <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
            <taglib uri="http://java.sun.com /jsp/jstl/core" prefix="c" />
            <html>
            <head>
            <title>错误页面</title>
            </head>
            <body>
            页面被黑洞吸走了......
            </body>
            </html>
            
             
             

              然后访问一个不存在的连接:http://localhost:8080/web_exception_project/123456.jhtml,结果如下:

              这里写图片描述

              三、本工程源码下载

              http://download.csdn.net/detail/u013142781/9424969




















              相关文章
              |
              6月前
              |
              前端开发 Java 测试技术
              微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
              本文介绍了 `@RequestParam` 注解的使用方法及其与 `@PathVariable` 的区别。`@RequestParam` 用于从请求中获取参数值(如 GET 请求的 URL 参数或 POST 请求的表单数据),而 `@PathVariable` 用于从 URL 模板中提取参数。文章通过示例代码详细说明了 `@RequestParam` 的常用属性,如 `required` 和 `defaultValue`,并展示了如何用实体类封装大量表单参数以简化处理流程。最后,结合 Postman 测试工具验证了接口的功能。
              321 0
              微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestParam
              |
              6月前
              |
              JSON 前端开发 Java
              微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestBody
              `@RequestBody` 是 Spring 框架中的注解,用于将 HTTP 请求体中的 JSON 数据自动映射为 Java 对象。例如,前端通过 POST 请求发送包含 `username` 和 `password` 的 JSON 数据,后端可通过带有 `@RequestBody` 注解的方法参数接收并处理。此注解适用于传递复杂对象的场景,简化了数据解析过程。与表单提交不同,它主要用于接收 JSON 格式的实体数据。
              491 0
              |
              6月前
              |
              前端开发 Java 微服务
              微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@PathVariable
              `@PathVariable` 是 Spring Boot 中用于从 URL 中提取参数的注解,支持 RESTful 风格接口开发。例如,通过 `@GetMapping(&quot;/user/{id}&quot;)` 可以将 URL 中的 `{id}` 参数自动映射到方法参数中。若参数名不一致,可通过 `@PathVariable(&quot;自定义名&quot;)` 指定绑定关系。此外,还支持多参数占位符,如 `/user/{id}/{name}`,分别映射到方法中的多个参数。运行项目后,访问指定 URL 即可验证参数是否正确接收。
              303 0
              |
              6月前
              |
              JSON 前端开发 Java
              微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RequestMapping
              @RequestMapping 是 Spring MVC 中用于请求地址映射的注解,可作用于类或方法上。类级别定义控制器父路径,方法级别进一步指定处理逻辑。常用属性包括 value(请求地址)、method(请求类型,如 GET/POST 等,默认 GET)和 produces(返回内容类型)。例如:`@RequestMapping(value = &quot;/test&quot;, produces = &quot;application/json; charset=UTF-8&quot;)`。此外,针对不同请求方式还有简化注解,如 @GetMapping、@PostMapping 等。
              265 0
              |
              6月前
              |
              JSON 前端开发 Java
              微服务——SpringBoot使用归纳——Spring Boot中的MVC支持——@RestController
              本文主要介绍 Spring Boot 中 MVC 开发常用的几个注解及其使用方式,包括 `@RestController`、`@RequestMapping`、`@PathVariable`、`@RequestParam` 和 `@RequestBody`。其中重点讲解了 `@RestController` 注解的构成与特点:它是 `@Controller` 和 `@ResponseBody` 的结合体,适用于返回 JSON 数据的场景。文章还指出,在需要模板渲染(如 Thymeleaf)而非前后端分离的情况下,应使用 `@Controller` 而非 `@RestController`
              206 0
              |
              2月前
              |
              前端开发 Java API
              Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
              本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
              183 0
              |
              2月前
              |
              SQL Java 数据库连接
              Spring、SpringMVC 与 MyBatis 核心知识点解析
              我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
              112 0
              |
              2月前
              |
              JSON 前端开发 Java
              第05课:Spring Boot中的MVC支持
              第05课:Spring Boot中的MVC支持
              156 0
              |
              8月前
              |
              SQL Java 数据库连接
              对Spring、SpringMVC、MyBatis框架的介绍与解释
              Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
              363 29
              |
              9月前
              |
              设计模式 前端开发 Java
              步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
              通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
              201 4

              热门文章

              最新文章