SSM整合中的异常处理机制

1 异常映射

1.1 目标

使用异常映射对项目的异常错误提示进行统一管理。

1.2 思路

对于普通的页面请求,异常映射机制捕获到handler方法抛出的异常后会响应为一个错误页面,对于处理ajax请求的handler方法抛出的异常则响应一个json。

SpringMVC提供了基于xml和注解方式的异常映射机制,而且通过xml视图控制器<mvc:view-controller>进行的请求映射的异常只能通过xml的异常映射机制获取而通过@requestMapping注解进行的请求映射的异常既能通过xml也能通过注解方式的异常映射机制获取

1.3 代码

1.3.1 基于XML异常映射机制

classpath: spring-webmvc.xm

  <!--基于XML的异常映射-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
          id="simpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <!--       key指定异常的全类名         -->
                <!--       标签指定对应视图,会经过视图解析器添加前后缀         -->
                <prop key="java.lang.Exception">system-error</prop>
        </property>
    </bean>

1.3.2 基于注解的异常映射处理机制

 首先写一个判断请求是否是ajax请求

 /**
     * 判断请求类型
     * @param request
     * @return true=json请求;false=普通页面请求
     */
    public static boolean judgeRequestType(HttpServletRequest request){
        String accept = request.getHeader("Accept");
        String header = request.getHeader("X-Requested-With");
        return (accept != null && accept.contains("application/json"))
                ||
                (header != null && header.equals("XMLHttpRequest"));
    }

 编写基于注解的异常处理类

//注解标明该类是基于注解的异常处理器类
@ControllerAdvice
public class CrowdExceptionResolver {
    /**
     * 处理登录失败的异常
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = {LoginFailedException.class})
    public ModelAndView resolveloginFailedException(LoginFailedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
//        String viewName="admin-login";
        String viewName = "admin-login";
        return commonCode(exception, request, response, viewName);
    }

    //处理空指针异常
    @ExceptionHandler(value = {NullPointerException.class})
    public ModelAndView resolveNullPointerException(NullPointerException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        return commonCode(exception, request, response, "system-error");
    }


    //处理数学异常,这里如果内部操作相同,跳转页面也相同,其实可以放在上面一个方法中,此处只是为了演示
    @ExceptionHandler(value = {ArithmeticException.class})
    public ModelAndView resolveArithmeticException(ArithmeticException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        return commonCode(exception, request, response, "system-error");

    }

    //整理出的不同异常的可重用代码
    private ModelAndView commonCode(
            //触发的异常,此处借助多态
            Exception exception,
            //客户器端的请求
            HttpServletRequest request,
            //服务端的响应
            HttpServletResponse response,
            //指定普通页面请求时,去的错误页面
            String viewName) throws IOException {
        boolean judgeRequestType = CrowdUtil.judgeRequestType(request);
        if (judgeRequestType) {
            //if判断-是json请求
            ResultEntity<Object> failed = ResultEntity.failed(exception.getMessage());
            //创建Gson对象
            Gson gson = new Gson();
            //将ResultEntity对象转换成json格式
            String json = gson.toJson(failed);
            //通过原生servlet的response传回异常内容
            response.getWriter().write(json);
            //此时只需要返回null(因为是通过json格式返回数据)
            return null;
        } else {
            //if判断-是普通页面请求
            //创建ModelAndView对象
            ModelAndView modelAndView = new ModelAndView();
            //设置触发异常跳转的页面(会自动被视图解析器加上前后缀)
            modelAndView.setViewName(viewName);
            //将异常信息加入
            modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception);
            //返回设置完成的ModelAndView
            return modelAndView;
        }
    }

}

1.3.3 创建自定义异常类

① 以登录为例,创建一个自定义异常LoginFailedException

/**
 * 登录失败后抛出的异常
 */
public class LoginFailedException extends RuntimeException {

    public LoginFailedException() {
        super();
    }

    public LoginFailedException(String message) {
        super(message);
    }

    public LoginFailedException(String message, Throwable cause) {
        super(message, cause);
    }

    public LoginFailedException(Throwable cause) {
        super(cause);
    }

    protected LoginFailedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

继承自RuntimeException或者CompilerException这里都可以

② 在登录业务service中抛出自定义异常

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    AdminMapper adminMapper;
    @Override
    public Admin getAdminByLoginAcct(String loginAcct, String userPswd) {
        // 1。 通过数据库查询是否存在该用户
        // ①创建 AdminExample 对象
        AdminExample adminExample = new AdminExample();
        // ②创建 Criteria 对象
        AdminExample.Criteria criteria = adminExample.createCriteria();
        //③在 Criteria 对象中封装查询条件
        // criteria.andCreateTimeEqualTo(loginAcct);
        criteria.andLoginAcctEqualTo(loginAcct);
        //④调用 AdminMapper 的方法执行查询
        // 2。 判断admin是否存在
        List<Admin> admins = adminMapper.selectByExample(adminExample);
        if (admins == null || admins.size() == 0) {
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        if (admins.size() > 1) {
            throw new LoginFailedException(CrowdConstant.MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE);
        }
        Admin admin = admins.get(0);
        if (admin == null) {
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        // 3。 比对数据库中的用户密文密码
        String userPswdDB = admin.getUserPswd();
        String userPswdWeb = CrowdUtil.md5(userPswd);
        // 4。密码比对失败 抛出异常
        if (!Objects.equals(userPswdDB, userPswdWeb)) {
            throw new LoginFailedException(CrowdConstant.MESSAGE_LOGIN_FAILED);
        }
        // 5。 返回Admin对象
        return admin;
    }
}

③ 在异常处理类中捕获controller处理请求产生的异常

//注解标明该类是基于注解的异常处理器类
@ControllerAdvice
public class CrowdExceptionResolver {
    /**
     * 处理登录失败的异常
     *
     * @param exception
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = {LoginFailedException.class})
    public ModelAndView resolveloginFailedException(LoginFailedException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
//        String viewName="admin-login";
        String viewName = "admin-login";
        return commonCode(exception, request, response, viewName);
    }
)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卓@酌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值