SpringMVC学习记录

注意:以下内容是学习 北京动力节点 的SpringMVC视频后所记录的笔记、源码以及个人的理解等,记录下来仅供学习

第4章 SpringMVC 核心技术

4.2异常处理

 SpringMVC框架处理异常的常用方式:使用@ExceptionHandler注解处理异常。

异常处理步骤:

  1. 新建maven web项目
  2. 加入依赖
  3. 新建一个自定义异常类 MyUserException , 再定义它的子类NameException ,AgeException
  4. 在controller抛出NameException , AgeException
  5. 创建一个普通类,作用全局异常处理类

    (1). 在类的上面加入@ControllerAdvice

    (2). 在类中定义方法,方法的上面加入@ExceptionHandler
  6. 创建处理异常的视图页面
  7. .创建springmvc的配置文件

    (1).组件扫描器 ,扫描@Controller注解

    (2).组件扫描器,扫描@ControllerAdvice所在的包名

    (3).声明注解驱动

项目结构:

4.2.1 @ExceptionHandler 注解

 使用注解@ExceptionHandler可以将一个方法指定为异常处理方法。该注解只有一个可 选属性value,为一个Class<?>数组,用于指定该注解的方法所要处理的异常类,即所要匹 配的异常。

 而被注解的方法,其返回值可以是ModelAndView、String,或void,方法名随意,方法 参数可以是 Exception 及其子类对象、HttpServletRequest、HttpServletResponse 等。系统会 自动为这些方法参数赋值。

对于异常处理注解的用法,也可以直接将异常处理方法注解于Controller之中。

(1) 自定义异常类

 定义三个异常类:NameException、AgeException、MyUserException。其中 MyUserException 是另外两个异常的父类。

MyUserException.java

package com.bjpowernode.exception;
public class MyUserException extends Exception {
public MyUserException() {
super();
} public MyUserException(String message) {
super(message);
}
}

AgeException.java

package com.bjpowernode.exception;

//当年龄有问题时,抛出的异常
public class AgeException extends MyUserException {
public AgeException() {
super();
} public AgeException(String message) {
super(message);
}
}

NameException.java

package com.bjpowernode.exception;
//表示当用户的姓名有异常,抛出NameException
public class NameException extends MyUserException {
public NameException() {
super();
}
public NameException(String message) {
super(message);
}
}

(2) 修改 Controller 抛出异常

MyController.java

package com.bjpowernode.controller;

import com.bjpowernode.exception.AgeException;
import com.bjpowernode.exception.MyUserException;
import com.bjpowernode.exception.NameException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.ws.RequestWrapper; /**
* @RequestMapping:
* value : 所有请求地址的公共部分,叫做模块名称
* 位置: 放在类的上面
*/
@Controller
public class MyController {
@RequestMapping(value = "/some.do")
public ModelAndView doSome(String name,Integer age) throws MyUserException {
//处理some.do请求了。 相当于service调用处理完成了。
ModelAndView mv = new ModelAndView(); //try {
//根据请求参数抛出异常
if (!"zs".equals(name)) {
throw new NameException("姓名不正确!!!");
} if (age == null || age > 80) {
throw new AgeException("年龄比较大!!!");
} //}catch(Exception e){
// e.printStackTrace();
//}
mv.addObject("myname",name);
mv.addObject("myage",age);
mv.setViewName("show");
return mv;
}
}

(3) 定义异常请求以及响应页面

请求页面:

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath = request.getScheme() + "://" +
request.getServerName() + ":" + request.getServerPort() +
request.getContextPath() + "/";
%>
<html>
<head>
<title>Title</title>
<base href="<%=basePath%>" />
</head>
<body>
<p>处理异常的,全局异常处理</p>
<form action="some.do" method="post">
姓名:<input type="text" name="name"> <br/>
年龄:<input type="text" name="age"> <br/>
<input type="submit" value="提交请求">
</form>
</body>
</html>

响应页面

ageError.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
ageError.jsp <br/>
提示信息:${msg} <br/>
系统异常消息:${ex.message} </body>
</html>

defaultError.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
defaultError.jsp <br/>
提示信息:${msg} <br/>
系统异常消息:${ex.message} </body>
</html>

nameError.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
nameError.jsp <br/>
提示信息:${msg} <br/>
系统异常消息:${ex.message} </body>
</html>

(4) 定义全局异常处理类

不过,一般不这样使用。而是将异常处理方法专门定义在一个类中,作为全局的异常处理类。需要使用注解@ControllerAdvice,字面理解就是“控制器增强”,是给控制器对象增强功能的。使用@ControllerAdvice 修饰的类中可以使用@ExceptionHandler。当使用@RequestMapping 注解修饰的方法抛出异常时,会执行@ControllerAdvice 修饰的类中的异常处理方法。@ControllerAdvice 是使用@Component 注解修饰的,可以context:component-scan扫描到@ControllerAdvice 所在的类路径(包名),创建对象。

GlobalExceptionHandler.java

package com.bjpowernode.handler;

import com.bjpowernode.exception.AgeException;
import com.bjpowernode.exception.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView; /**
* @ControllerAdvice : 控制器增强(也就是说给控制器类增加功能--异常处理功能)
* 位置:在类的上面。
* 特点:必须让框架知道这个注解所在的包名,需要在springmvc配置文件声明组件扫描器。
* 指定@ControllerAdvice所在的包名
*/
@ControllerAdvice
public class GlobalExceptionHandler {
//定义方法,处理发生的异常
/*
处理异常的方法和控制器方法的定义一样, 可以有多个参数,可以有ModelAndView,
String, void,对象类型的返回值 形参:Exception,表示Controller中抛出的异常对象。
通过形参可以获取发生的异常信息。 @ExceptionHandler(异常的class):表示异常的类型,当发生此类型异常时,
由当前方法处理
*/ @ExceptionHandler(value = NameException.class)
public ModelAndView doNameException(Exception exception){
//处理NameException的异常。
/*
异常发生处理逻辑:
1.需要把异常记录下来, 记录到数据库,日志文件。
记录日志发生的时间,哪个方法发生的,异常错误内容。
2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。
3.给用户友好的提示。
*/
ModelAndView mv = new ModelAndView();
mv.addObject("msg","姓名必须是zs,其它用户不能访问");
mv.addObject("ex",exception);
mv.setViewName("nameError");
return mv;
} //处理AgeException
@ExceptionHandler(value = AgeException.class)
public ModelAndView doAgeException(Exception exception){
//处理AgeException的异常。
/*
异常发生处理逻辑:
1.需要把异常记录下来, 记录到数据库,日志文件。
记录日志发生的时间,哪个方法发生的,异常错误内容。
2.发送通知,把异常的信息通过邮件,短信,微信发送给相关人员。
3.给用户友好的提示。
*/
ModelAndView mv = new ModelAndView();
mv.addObject("msg","你的年龄不能大于80");
mv.addObject("ex",exception);
mv.setViewName("ageError");
return mv;
} //处理其它异常, NameException, AgeException以外,不知类型的异常
@ExceptionHandler
public ModelAndView doOtherException(Exception exception){
//处理其它异常
ModelAndView mv = new ModelAndView();
mv.addObject("msg","你的年龄不能大于80");
mv.addObject("ex",exception);
mv.setViewName("defaultError");
return mv;
}
}

@ControllerAdvice 是使用@Component 注解修饰的

这句话看了源码是这样的,ControllerAdvice类是用@Component 注解的,

  @Component 作用:把普通pojo类实例化到spring容器中,相当于配置文件中的 <bean id="" class=""/>

  @Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。

(5) 定义 Spring 配置文件

springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--声明组件扫描器-->
<context:component-scan base-package="com.bjpowernode.controller" /> <!--声明 springmvc框架中的视图解析器, 帮助开发人员设置视图文件的路径-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前缀:视图文件的路径-->
<property name="prefix" value="/WEB-INF/view/" />
<!--后缀:视图文件的扩展名-->
<property name="suffix" value=".jsp" />
</bean> <!--处理需要的两步-->
<context:component-scan base-package="com.bjpowernode.handler" />
<mvc:annotation-driven />
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"> <!--声明,注册springmvc的核心对象DispatcherServlet
需要在tomcat服务器启动后,创建DispatcherServlet对象的实例。
为什么要创建DispatcherServlet对象的实例呢?
因为DispatcherServlet在他的创建过程中, 会同时创建springmvc容器对象,
读取springmvc的配置文件,把这个配置文件中的对象都创建好, 当用户发起
请求时就可以直接使用对象了。 servlet的初始化会执行init()方法。 DispatcherServlet在init()中{
//创建容器,读取配置文件
WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
//把容器对象放入到ServletContext中
getServletContext().setAttribute(key, ctx);
} 启动tomcat报错,读取这个文件 /WEB-INF/springmvc-servlet.xml(/WEB-INF/myweb-servlet.xml)
springmvc创建容器对象时,读取的配置文件默认是/WEB-INF/<servlet-name>-servlet.xml .
-->
<servlet>
<servlet-name>myweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!--自定义springmvc读取的配置文件的位置-->
<init-param>
<!--springmvc的配置文件的位置的属性-->
<param-name>contextConfigLocation</param-name>
<!--指定自定义文件的位置-->
<param-value>classpath:springmvc.xml</param-value>
</init-param> <!--在tomcat启动后,创建Servlet对象
load-on-startup:表示tomcat启动后创建对象的顺序。它的值是整数,数值越小,
tomcat创建对象的时间越早。 大于等于0的整数。
-->
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>myweb</servlet-name>
<!--
使用框架的时候, url-pattern可以使用两种值
1. 使用扩展名方式, 语法 *.xxxx , xxxx是自定义的扩展名。 常用的方式 *.do, *.action, *.mvc等等
不能使用 *.jsp
http://localhost:8080/myweb/some.do
http://localhost:8080/myweb/other.do 2.使用斜杠 "/"
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>

【SpringMVC】 4.2 异常处理的更多相关文章

  1. SpringMVC 三种异常处理方式

    SpringMVC 三种异常处理方式 在 SpringMVC, SpringBoot 处理 web 请求时, 若遇到错误或者异常,返回给用户一个良好的错误信息比 Whitelabel Error Pa ...

  2. SpringMVC 中的异常处理

    目录 1.搭建编码分析 2.编写异常类 3.编写自定义异常处理器 4.在springmvc.xml中配置异常处理器 5.编写Error.jsp.index.jsp页面 6.编写collector代码模 ...

  3. SpringMVC中的异常处理集锦

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  4. SpringMVC中的异常处理

    springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1. 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeExc ...

  5. SpringMVC 控制器统一异常处理

    摘要介绍spring mvc控制器中统一处理异常的两种方式:HandlerExceptionResolver以及@ExceptionHandler:以及使用@ControllerAdvice将@Exc ...

  6. SpringMVC的全局异常处理

    @ControllerAdvice的使用 我们都知道做项目一般都会有全局异常统一处理的类,那么这个类在Spring中可以用@ControllerAdvice来实现. @ControllerAdvice ...

  7. springmvc中的异常处理方法

    //1.自定义异常处理类       2.编写异常处理器    3.配置异常处理器 package com.hope.exception;/** * 异常处理类 * @author newcityma ...

  8. springmvc请求参数异常处理

    接着上一篇<springmvc 通过异常增强返回给客户端统一格式>讲通过spring ControllerAdvice对各种异常进行拦截处理,统一格式返回给客户端. 接下来我们更精细的讲, ...

  9. springMVC全局Exception异常处理SimpleMappingExceptionResolver

    继承了SimpleMappingExceptionResolver 贴上代码 /** * 对controller异常进行全局处理 * 区分了对普通请求和ajax请求的异常处理,普通请求返回到配置的er ...

  10. <SpringMvc>入门六 异常处理

    如果不做异常处理,那么一直将错误向上抛出,则会最后在页面上显示错误代码 服务启动后,访问test1方法,页面会报500 为了提示友好的错误页面,所以需要做异常处理 1.编写自定义异常类(做提示信息的) ...

随机推荐

  1. 用RabbitMQ了好几年之后,我总结出来5点RabbitMQ的使用心得

    大概从 2013 年开始,我就开始了自己和 RabbitMQ 的接触,到现在已经有七年多了. 在这七年中,既有一些对 RabbitMQ 的深度体验,更有无数的血泪史. 而根据我这么多年的使用经验,我将 ...

  2. HBase二级索引、读写流程

    HBase二级索引.读写流程 一.HBse二级索引方案 1.1 基于Coprocessor方案 1.2 Phoenix二级索引特点 1.3 Phoenix 二级索引方案 二.HBase读写流程 2.1 ...

  3. dedecms万能SQL标签使用方法大全

    注意:dede_archives这是系统默认的数据库表,如果你修改过表前缀dede_,请自行更改表名.在以下示例的标签中,有一部分只写出了SQL语句,具体的完整标签写法请参考:织梦SQL标签调用方法. ...

  4. phpstorm如何设置字体

    最近上手了一款轻量级IDE phpStorm,可是就在调整编辑器字体大小时却遇到问题了, 发现字体大小无法调整,另外还有字体大小往左还有个"√",始终无法去掉,这个勾限制了字体系列 ...

  5. Flink-v1.12官方网站翻译-P026-State Backends

    状态后台 Flink提供了不同的状态后端,指定状态的存储方式和位置. 状态可以位于Java的堆上或离堆.根据你的状态后端,Flink还可以为应用程序管理状态,这意味着Flink处理内存管理(必要时可能 ...

  6. CSS开发过程中的20个快速提升技巧

    摘要:本文涵盖了20个CSS技巧,可以解决许多工作中常见的问题, 让你也成为一个CSS高手. 1.使用CSS重置(reset) css重置库如normalize.css已经被使用很多年了,它们可以为你 ...

  7. 一文弄懂-BIO,NIO,AIO

    目录 一文弄懂-BIO,NIO,AIO 1. BIO: 同步阻塞IO模型 2. NIO: 同步非阻塞IO模型(多路复用) 3.Epoll函数详解 4.Redis线程模型 5. AIO: 异步非阻塞IO ...

  8. 【noi 2.6_7624】山区建小学(DP)

    题意:在m个村庄建n个小学,求所有村到最近小学的距离总的最小值. 解法:由于题目是求"离最近的学校",而不是前一个学校,所以枚举学校的具体位置不方便,可转化成区间(学校居区间中间) ...

  9. Codeforces Round #481 (Div. 3) F. Mentors (模拟,排序)

    题意:有一个长度为\(n\)的序列\(a\),求这个序列中有多少比\(a_{i}\)小的数,如果某两个位置上的数有矛盾,则不能算小. 题解:用\(pair\)来记录序列中元素的位置和大小,将他们升序排 ...

  10. Codeforces Round #479 (Div. 3) E. Cyclic Components (思维,DFS)

    题意:给你\(n\)个顶点和\(m\)条边,问它们有多少个单环(无杂环),例如图中第二个就是一个杂环. 题解:不难发现,如果某几个点能够构成单环,那么每个点一定只能连两条边.所以我们先构建邻接表,然后 ...