Spring框架学习第六天

Spring异常处理

原有处理方式

  • try{}catch{}
  • 声明throws异常

SpringMVC处理方式

Controller处理可以将错误捕获并定位到一个错误页面jsp页面

全局异常处理

处理所有Controller异常

Spring-mvc.xml内容:

<!--配置全局异常处理-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <!--<prop key="异常类型">视图名</prop>-->
            <!--<prop key="java.lang.NumberFormatException">errorPage/500</prop>-->
            <!--<prop key="java.lang.NumberFormatException">errorPage/500</prop>-->
            <prop key="java.lang.Exception">errorPage/500</prop>
        </props>
    </property>
</bean>

CalculatorController.java内容:

package biuaxia.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * Class Describe:计算器
 *
 * @author biuaxia
 * @date 2018/11/17
 * @time 12:48
 */
@Controller
public class CalculatorController {
    @RequestMapping("calculator")
    public String showCalculator() {
        return "calculator";
    }

    @RequestMapping("add")
    public ModelAndView add(String a, String b) {
        ModelAndView view = new ModelAndView("calculator");
        view.getModel().put("result", Double.parseDouble(a) + Double.parseDouble(b));
        view.getModel().put("a", a);
        view.getModel().put("b", b);
        return view;
    }

    //@RequestMapping("add")
    public ModelAndView addTry(String a, String b) {
        ModelAndView view = new ModelAndView("calculator");
        try {
            view.getModel().put("result", Double.parseDouble(a) + Double.parseDouble(b));
            view.getModel().put("a", a);
            view.getModel().put("b", b);
            return view;
        } catch (NumberFormatException e) {
            view.setViewName("errorPage/500");
            view.getModel().put("errInfo", e.toString());
            return view;
        }
    }

    @RequestMapping("del")
    public ModelAndView del(String c, String d) {
        ModelAndView view = new ModelAndView("calculator");
        view.getModel().put("result", Double.parseDouble(c) - Double.parseDouble(d));
        view.getModel().put("c", c);
        view.getModel().put("d", d);
        return view;
    }
}

错误页面errorPage/500.jsp内容:

<%--
  Created by IntelliJ IDEA.
  User: biuaxia
  Date: 2018/11/17
  Time: 11:33
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
          content="width=device-width, initial-scale=1">
    <meta name="format-detection" content="telephone=no">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-siteapp"/>
    <title>错误 - biuaxia</title>
    <link href="https://cdn.bootcss.com/amazeui/2.7.2/css/amazeui.min.css" rel="stylesheet">
    <style>
        .get {
            background: #1E5B94;
            color: #fff;
            text-align: center;
            padding: 100px 0;
            height: 100%;
        }

        .get-title {
            font-size: 200%;
            border: 2px solid #fff;
            padding: 20px;
            display: inline-block;
        }

        .footer p {
            color: #7f8c8d;
            margin: 0;
            padding: 15px 0;
            text-align: center;
            background: #2d3e50;
        }

        .am-g {
            margin: 10% auto;
        }
    </style>
</head>
<body>

<div class="get">
    <div class="am-g">
        <div class="am-u-lg-12">
            <h1 class="get-title">不知道大佬您在玩什么,居然搞崩溃了我们的服务器!</h1>
        </div>
        <%--<div class="am-u-sm-12"><p>错误信息:<code>${errInfo}</code></p></div>--%>
        <div class="am-u-lg-12">
            <a href="index.do" class="am-btn am-btn-primary">返回首页</a>
        </div>
    </div>
</div>

<!--[if lt IE 9]>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script>
<![endif]-->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/amazeui/2.7.2/js/amazeui.min.js"></script>
</body>
</html>

计算器页面calculator.jsp内容:

<%--
  Created by IntelliJ IDEA.
  User: biuaxia
  Date: 2018/11/17
  Time: 11:33
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport"
          content="width=device-width, initial-scale=1">
    <meta name="format-detection" content="telephone=no">
    <meta name="renderer" content="webkit">
    <meta http-equiv="Cache-Control" content="no-siteapp"/>
    <title>计算器 - biuaxia</title>
    <link href="https://cdn.bootcss.com/amazeui/2.7.2/css/amazeui.min.css" rel="stylesheet">
    <style>
        .footer p {
            color: #7f8c8d;
            margin: 0;
            padding: 15px 0;
            text-align: center;
            background: #2d3e50;
        }
    </style>
</head>
<body>
<header class="am-topbar am-topbar-fixed-top">
    <div class="am-container">
        <h1 class="am-topbar-brand">biuaxia</h1>

        <button class="am-topbar-btn am-topbar-toggle am-btn am-btn-sm am-btn-secondary am-show-sm-only"
                data-am-collapse="{target: '#collapse-head'}"><span class="am-sr-only">导航切换</span> <span
                class="am-icon-bars"></span></button>

        <div class="am-collapse am-topbar-collapse" id="collapse-head">
            <ul class="am-nav am-nav-pills am-topbar-nav">
                <li><a href="index.do">首页</a></li>
                <li class="am-active"><a href="calculator.do">计算器</a></li>
            </ul>

            <div class="am-topbar-right">
                <button class="am-btn am-btn-secondary am-topbar-btn am-btn-sm"><span class="am-icon-pencil"></span> 注册
                </button>
            </div>

            <div class="am-topbar-right">
                <button class="am-btn am-btn-primary am-topbar-btn am-btn-sm"><span class="am-icon-user"></span> 登录
                </button>
            </div>
        </div>
    </div>
</header>

<div class="am-g am-container" style=" margin-top: 1rem;">
    <h2 class="am-text-center">加法运算</h2>
    <div class="am-u-lg-12 am-text-center">
        <form action="add.do" class="am-form-inline">
            <input type="text" class="am-form-field am-round" placeholder="${a}" name="a"/>
            +
            <input type="text" class="am-form-field am-round" placeholder="${b}" name="b"/>
            =${result}
            <input type="submit" value="计算">
        </form>
    </div>
    <h2 class="am-text-center">减法运算</h2>
    <div class="am-u-lg-12 am-text-center">
        <form action="del.do" class="am-form-inline">
            <input type="text" class="am-form-field am-round" placeholder="${c}" name="c"/>
            -
            <input type="text" class="am-form-field am-round" placeholder="${d}" name="d"/>
            =${result1}
            <input type="submit" value="计算">
        </form>
    </div>
    <div class="am-u-md-6">
        <div class="am-panel am-panel-primary">
            <div class="am-panel-hd"><h3 class="am-panel-title">第一次提交修改内容(2018年11月17日13:12:03)</h3></div>
            <div class="am-panel-bd">
                <h3>修改说明</h3>
                <p>两个文本输入框若有一个为空则会出现 <span class="am-text-danger">HTTP Status 400 – Bad Request</span> 错误</p>
                <h3>解决办法</h3>
                <p>添加全局异常处理</p>
                <h3>触发该bug说明</h3>
                <p>去除CalculatorController.java中的addTry方法标记,即可触发try错误处理</p>
            </div>
        </div>
    </div>
    <div class="am-u-md-6">
        <div class="am-panel am-panel-primary">
            <div class="am-panel-hd"><h3 class="am-panel-title">第二次提交修改内容(2018年11月17日13:12:03)</h3></div>
            <div class="am-panel-bd">
                <h3>修改说明</h3>
                <p>使用Spring MVC的<span class="am-text-danger">ExceptionHandlerExceptionResolver / SimpleMappingExceptionResolver</span>配置(spring-mvc.xml)全局异常处理
                </p>
                <h3>配置内容</h3>
                <p>
                <pre class="am-pre-scrollable">

</pre>
                </p>
                <h3>触发该bug说明</h3>
                <p>去除CalculatorController.java中的addTry方法标记,即可触发try错误处理</p>
            </div>
        </div>
    </div>
</div>
<footer class="footer">
    <p>© 2014 <a href="http://www.yunshipei.com" target="_blank">AllMobilize, Inc.</a> Licensed under <a
            href="http://opensource.org/licenses/MIT" target="_blank">MIT license</a>. by the AmazeUI Team.</p>
</footer>

<!--[if lt IE 9]>
<script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script>
<![endif]-->
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/amazeui/2.7.2/js/amazeui.min.js"></script>
</body>
</html>

运行效果图:

运算界面:

运算前

出错页面:

出错

我们只需配置一下就等价于各个try的捕获

局部异常处理

上面的处理只能是运行时异常,是处理不到类似于400之类的异常

那么处理某个单独的异常怎么做呢?
在对应的Controller下再新写一个@ExceptionHandler方法
例如我想要减法运算的异常跳转到计算器页面而不是500,并且还有提示

CalculatorController.java内容:

@ExceptionHandler
public ModelAndView exception(Exception e) {
    ModelAndView view = new ModelAndView("calculator");
    view.getModel().put("errInfo", "数据源有误");
    return view;
}

注意:方法参数必须有一个Exception,方法名随意,返回类型可以是ModelAndView或者String
如果全局和局部都存在,那么先走局部

流程:
DispatcherServlet->HandlerMapping->XxController->ExceptionResolver->ViewResolver

使用Spring框架提供的自定义异常

和拦截器性质差不多都得实现一个接口,这里我们实现HandlerExceptionResolver接口

例如自定义异常类的步骤
MyException.java内容

package biuaxia.mvc.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Class Describe:
 *
 * @author biuaxia
 * @date 2018/11/17
 * @time 16:04
 */
public class MyException implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        /**
         * 可以在这里对异常的单独处理
         * 例如写入log文件或者发送短信之类的
         */
        ModelAndView view = new ModelAndView();
        view.getModel().put("errInfo", e.toString());
        return view;
    }
}

spring-mvc.xml内容:

<!--配置自带的全局异常处理-->
<!--<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            &lt;!&ndash;<prop key="异常类型">视图名</prop>&ndash;&gt;
            &lt;!&ndash;<prop key="java.lang.NumberFormatException">errorPage/500</prop>&ndash;&gt;
            &lt;!&ndash;<prop key="java.lang.NumberFormatException">errorPage/500</prop>&ndash;&gt;
            <prop key="java.lang.Exception">errorPage/500</prop>
        </props>
    </property>
</bean>-->
<!--配置自定义的全局异常处理-->
<bean class="biuaxia.mvc.exception.MyException"></bean>

如果想要牛一点的自定义我们可以在自定义异常类添加属性
MyException.java内容(其余内容不变哈)

private String viewName;

public void setViewName(String viewName) {
    this.viewName = viewName;
}

spring-mvc.xml

<!--配置自定义的全局异常处理-->
<bean class="biuaxia.mvc.exception.MyException">
    <property name="viewName" value="errorPage/500"></property>
</bean>

异常的处理总结

  1. 全局异常则在spring-mvc.xml配置文件中的bean->class使用到了ExceptionHandlerExceptionResolver / SimpleMappingExceptionResolver
  2. 局部异常则需要在对应Controller新建方法,参数列表携带Exception,并且打上标记@ExceptionHandler
  3. 自定义异常首先实现HandlerExceptionResolver,然后使用时就在配置文件中追加定义

文件上传

逻辑流程:

/upload.do->CommonsMultipartResolver(commons-fileupload.jar|commons-io.jar)->Controller(File xxx)

使用步骤

  1. 导入commons-fileupload.jar/commons-io.jar
  2. 在Spring配置文件追加CommonsMultipartResolver组件的定义
  3. 文件上传的Controller配置
package biuaxia.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 * Class Describe:
 *
 * @author biuaxia
 * @date 2018/11/17
 * @time 16:34
 */
@Controller
public class UploadController {
    @RequestMapping("showUpload")
    private String showUpload() {
        return "showUpload";
    }

    @RequestMapping("upload")
    private ModelAndView upload(MultipartFile mf) {
        System.out.println("原始文件名:" + mf.getOriginalFilename());
        System.out.println("上传后文件名:" + mf.getName());
        System.out.println("文件类型:" + mf.getContentType());
        System.out.println("文件大小:" + mf.getSize());
        ModelAndView view = new ModelAndView("showUpload");
        view.getModel().put("msg", "上传成功");
        return view;
    }
}

注意,表单的name必须和上传的mf一致!否则收不到文件
当然你可以在需要接受的参数列表指定@RequestParam("mf") MultipartFile userUploadFile

上传界面:

上传路径:

做个小笔记

后面可以查看一下这个网址详细理解文件上传:文件上传那些事:多图上传、大文件上传、断点续传功能实现与分析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值