springmvc

 

第一章:SpringMVC简介与执行过程

  1. SpringMVC简介

1) Spring Web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。

(1) 模型(Model)封装了应用程序数据,通常它们将由POJO类组成。

(2) 视图(View)负责展示数据,一般来说它生成客户端浏览器可以解释HTML输出。

(3) 控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行解析展示。

2) SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示。

 

  1. SpringMVC处理请求的流程

 

  1. SpringMVC的核心组件

1) DispatcherServlet:

DispatcherServlet就是所谓的SpringMVC前端控制器,作为整个SpringMVC的控制中心;

2) HandlerMapping:

HandlerMapping主要用来解析请求url,解析出控制器,从而映射控制器;

3) HandlerAdapter:

HandlerAdapter主要是调度Controller来处理业务逻辑等;

4) ViewResolver:

ViewResolver接口主要作用是解析DispatcherServlet传递的逻辑视图名,并将解析结果传回给DispatcherServlet;

第二章:SpringMVC配置

 

  1. SpringMVC的配置过程

1) 新建一个Maven项目,然后选择maven-webapp模板

2) 等待项目创建完毕,如果项目没有构建完毕,使用手动创建文件夹的话,系统构建完毕后,会覆盖pom.xml和web.xml文件,所以需要重新配置这两个文件。

 

3) 项目完毕后,创建了resources文件夹和webapp文件夹,之后需要手动创建src下的java文件夹,并将不需要的配置文件删除,webapp下的WEB-INF下只留web.xml文件即可。

 

4) Module中,添加web单元,选择src下的webapp文件夹

 

5) 配置web.xml文件,springmvc-config.xml文件和pom.xml文件

6) Pom.xml文件设置依赖项,并import changes

7) src下新建包,并在springmvc-config.xml中,配置自动扫描的包。

8) 配置tomcat运行项,

 

 

在发布页面上配置

 

9) webapp下新建index.html文件,并运行tomcat,测试是否能显示页面

10) 部署时容易出的问题

(1) 没有在项目结构的module中,设置web模块

(2) 在运行配置tomcat时,没有在发布选项卡设置发布的artificts

(3) 如果项目没有构建完毕,已经配置好的pom文件和web.xml文件可能被覆盖,所有需要再次配置这两个文件。

第三章:SpringMVC乱码

乱码的解决,在web.xml文件中添加

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<!--过滤-->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <!-- Servlet容器跳springMVC的框架容器 -->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- contextConfigLocation配置springmvc的配置文件(配置理器映射器、适配器等等)
                         如果不配置contextConfigLocation,默的是/WEB-INF/servlet-name-servlet.xml
     -->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc-config.xml</param-value>
    </init-param>
  </servlet>
  <!-- DispatcherServlet理所有-->
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

 

第四章:SpringMVC常用注解

  1. 注意事项:

1) 采用return字符串进行重定向时,有可能会影响System.out.println的输出。

  1. @Controller:用于定义控制器类
  2. @RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射,主要属性为value属性和method属性,value属性为默认属性,表示映射的前端请求地址,method为请求方式,可以为get,post或其他,比如:

@RequestMapping(value = "/",method = RequestMethod.GET)

value:指定请求的实际地址;

1) method: 指定请求的类型—— GET、POST、PUT、DELETE等。

2) 值为:RequestMethod.XXX

l @ RequestMapping注解在类上

@Controller
@RequestMapping("books")
public class BookController {
    @RequestMapping("/book01")

 

  1. @GetMapping:是@RequestMapping(method = RequestMethod.GET)的缩写。
  2. @PostMapping:是@RequestMapping(method = RequestMethod.POST)的缩写。
  3. @PathVariable:映射URL绑定的占位符,用户获取路径参数,用在方法参数前面。

前端页面请求:

<a href="delete/5">URL中的占位符</a>

 

Controller中:

@RequestMapping("delete/{id}")
public String delete(@PathVariable("id") String u_id) {
    System.out.println("id=" + u_id);
    return "delete";
}

 

 

  1. @RequestParam:用于将请求参数区数据映射到功能处理方法的参数上,用在方法的参数前面。

1) 如果前端的上传数据和Controller的参数名称相同,能自动赋值,并能自动根据Controller参数类型自动转成相应的数据类型

前端页面:

<li><a href="books/book01?bName=&price=56.9&pageNum=100">传递和Controller参数相同名称的数据</a></li>

Controller:

@Controller
@RequestMapping("books")
public class BookController {
    @RequestMapping("/book01")
    public String book01(String bName,Double price,int pageNum){
        System.out.println(bName+","+price+","+pageNum);
        return "welcome";
    }
}

 

2) 上传的参数名和Controller中的接收的参数名称不一致时。

前端页面:

<li><a href="books/book01?bName=&price=56.9&pageNum=100">传递和Controller参数相同名称的数据</a></li>

Controller:

@RequestMapping("/book01")
    public void book01(@RequestParam("bName") String name, Double price, int pageNum, boolean isNew){
        System.out.println(name+","+price+","+pageNum+","+isNew);
//         注意定向会导致控制台不能出信息
//        return "welcome";
    }

 

3) 如果前端传递的文本框的value值,和后端的实体类属性名称一致时,可以自动映射到对象中。

前端请求:

<form action="doLogin" method="post">
<input type="text" name="uName"><br>
<input type="text" name="uPwd"><br>
<input type="submit" value="login">
</form>

实体类:

public class User implements Serializable {
    private String uId;
    private String uName;
    private String uPwd;

    public User() {
    }

Controller:

@RequestMapping("doLogin")
public String login(User user){
    //如果前端传递的文本框的value,和后端的类属性名一致,可以自映射到象中
    System.out.println("user="+user);
    return "welcome";
}

 

  1. @DateTimeFormat使用,注意前端的数据和后端的格式要对应

前端:

<li><a href="books/book02?addDate=2020-03-21 19:00:00">时间类型的传递</a></li>

后端:

@RequestMapping("/book02")
public String book01(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date addDate){
    System.out.println(addDate);
    return "login";
}

 

  1. @JsonFormat:设置Json序列化格式

当参数为Date类型,或默认返回为时间戳(毫秒数)

@RequestMapping("doLogin")
@ResponseBody
public Date login(User user){
    //如果前端传递的文本框的value,和后端的类属性名一致,可以自映射到象中
    System.out.println("user="+user);
    return user.getUaddDate();
}

显示结果:

 

如果在实体类有日期,并且需要通过参数构造实体类,并自动注入的情况下,需要处理Date类型的数据,这时,我们需要在实体类的属性上添加如下注解

@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MMdd")
private Date uaddDate;

前端:

 

 

  1. @RequestBody:允许request的参数在request体中,而不是在直接链接在地址后面。此注解放在参数前。

a) 常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,而是如application/json, application/xml等;如果Controller方法的参数需要映射为集合,该注解非常有用!

b) 注意:使用该注解,提交json格式数据,一定是json格式字符串,而不是js对象或者数组!

  1. @ResponseBody:用于将Controller的方法返回的对象转换为指定格式后,写入到Response对象的body数据区。

使用:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用。

    public Map<String,Object> book03(@RequestParam("bName") String name, Double price, int pageNum, boolean isNew){
        System.out.println(name+","+price+","+pageNum+","+isNew);
//         注意定向会导致控制台不能出信息
        Map<String,Object> map = new HashMap<String, Object>();
        map.put("errorCode",1);
        map.put("message","成功");
        return map;
    }

表单登录:

前端:

login:
<form action="doLogin" method="post">
<input type="text" name="uName"><br>
<input type="text" name="uPwd"><br>
    <input type="text" value="2000-01-10" name="uaddDate"><br>
    <input type="radio" checked="checked" name="gender" value="male">男<input type="radio"  name="gender" value="female">女<br>
    <select name="city" >
        <option value="天津">天津</option>
        <option value="北京">北京</option>
        <option value="河北">河北</option>
    </select>
    <input type="checkbox" name="favorites" value="">篮球
    <input type="checkbox" name="favorites" value="足球">足球
    <input type="checkbox" name="favorites" value="排球">排球
<input type="submit" value="login">
</form>

后端:

public User login(User user){
    //如果前端传递的文本框的value,和后端的类属性名一致,可以自映射到象中
    System.out.println("user="+user);
    return user;
}

 

  1. @RestController:是@Controller和@ResponseBody的合集
  2. @ExceptionHandler:用在方法上表示遇到这个异常就执行以下方法。Controller层的全局异常统一处理。
  3. @ControllerAdvice:控制器增强,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。
  4. @CrossOrigin :允许跨域请求
  5. @SessionAtrriBute
  6. ModelAndView类用于html页,只能设置setViewName,不能设置model数据

章:ModelAndView

@RequestMapping("testModel")
public ModelAndView testModel(){
    ModelAndView mv = new ModelAndView();
    mv.setViewName("calc");
    return mv;
}

 

 

  1. jsp页中,可以测试model数据的传递

@RequestMapping("testModel")
public ModelAndView testModel(){
    ModelAndView mv = new ModelAndView();
    mv.addObject("test","abc");
    mv.setViewName("testmodelandview");
    return mv;
}

 

JSP页面:

<body>
<h3>testmodelandview</h3>
<%=request.getAttribute("test")%>

</body>

 

 

章:拦截器

  1. 拦截器定义

@Component

public class AuthorityInterceptor implements HandlerInterceptor {

    @Override//在一个请求进入Controller层方法执行前执行这个方法

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //在这里可以对参数做一些预处理和做一些验证

        return true;//方法给予执行,就是允许controller的方法进行执行

        //false 不允许,可以在这之前在reponse中编写返回的结果

    }

    //返回model前

    @Override

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        //Controller执行完毕后,返回之前,可以对request和reponse进行处理

        //如果是前后端没有分离,在进入View层中前执行

    }

 

    //返回model后

    @Override

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        //在一个请求处理完毕,即将销毁的时候,执行,可以做一些资源释放之类的工作

    }

}

 

  1. 拦截器和Filter的区别

拦截器和过滤器(Filter)的区别

1) 拦截器是基于反射机器,Filter是基于函数回调

2) 拦截器不依赖servlet容器,Filter依赖

3) 拦截器只对action其作用,Filter对几乎所有请求都起作用

4) 拦截器可以访问action的上下文,或者值栈里的对象,Filter不行

5) action的生命周期中,拦截器可以多次被调用,Filter只在容器初期化时被调用一次

6) 拦截器可以获取IOC容器中的各个bean,但是Filter不行

  1. 拦截器的顺序:在xml文件中的顺序就是拦截器执行的顺序

<mvc:interceptors>
    <!--        该拦截器拦截所有请求-->
    <mvc:interceptor>
        <mvc:mapping path="/login/**"/>
        <bean class="com.iss.interceptor.SecondInterceptor"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/books/**"/>
        <bean class="com.iss.interceptor.FirstInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

  1. 拦截器的方法的返回值:如果preHandle方法返回为false,那么会拦截该拦截器的postHandle和afterCompletion方法,以及其后的拦截器。
  2. 拦截器设置mapping过滤要拦截的路径

<mvc:interceptors>
    <!--        该拦截器拦截所有请求-->
    <mvc:interceptor>
        <mvc:mapping path="/books/**"/>
        <bean class="com.iss.interceptor.FirstInterceptor"></bean>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/login/**"/>
        <bean class="com.iss.interceptor.SecondInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

 

  1. 通过拦截器实现权限校验

登录的session操作:

@RequestMapping("/doLogin")
@ResponseBody
public User login(User user, HttpSession session){
    //如果前端传递的文本框的value,和后端的类属性名一致,可以自映射到象中
    System.out.println("user="+user);
    System.out.println("model1="+session);
    session.setAttribute("user",user);
    return user;
}

拦截器类:

如果没有HTTPSession类,可以手动键入import javax.servlet.http.HttpSession,然后报错地方帮助,选择javaEE6导入:

 

 

 

public class AuthInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        System.out.println("preHandle");
        if (session.getAttribute("user") == null) {
            System.out.println("user");
            response.sendRedirect(request.getContextPath()+"/pages/login.html");
            return false;
        }
        return true;

    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle");

        super.postHandle(request, response, handler, modelAndView);
    }
}

 

拦截器配置:

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/books/**"/>--路径必须加斜杠,表示从主路径开始
            <mvc:exclude-mapping path="/login/**"/>
            <bean class="com.iss.interceptor.AuthInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

操作步骤:先测试没有登录是能不能访问books下的链接,然在在登录状态上,访问books下的链接。

静态文件不拦截,配置文件中添加:

    <!-- 将静态资源的请求,转给Web应用服务器默认的Servlet处理 -->

    <mvc:default-servlet-handler />

 

章:文件上传与下载

第一节:文件上传

  1. 文件上传

Pom添加上传需要的依赖:

<!-- 文件上传 -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.2</version>
</dependency>
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.5</version>
</dependency>

前端:

单个文件上传
<form action="/books/douploadone" method="post" enctype="multipart/form-data">
    <input type="text" name="bookname">
    <input type="file" name="bookimage">
    <input type="submit" value="确定">
</form>

Springmvc-config中配置CommMultipartReslover

<!-- multipartResolver名字不能改,和后台DispatcherServlet中的常量保持一致,自注入 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="utf-8"></property>
    <property name="maxUploadSize" value="1024000"></property>
    <property name="maxInMemorySize" value="4096"></property>
</bean>

Controller:

@RequestMapping("/douploadone")
@ResponseBody
public Map<String ,Object> doUploadOne(@RequestParam("bookimage")CommonsMultipartFile file, @RequestParam("bookname") String name, HttpServletRequest request){

    Map<String,Object> map = new HashMap<String, Object>();
    System.out.println("name="+name);
    System.out.println(file.getOriginalFilename());
    //设置路径
    String spath = request.getServletContext().getRealPath("uploads");
    System.out.println("path="+spath);
    File path = new File(spath);
    if(!path.exists()){
        path.mkdirs();
    }
    File  newFile  = new File(path,System.currentTimeMillis()+"_"+file.getOriginalFilename());
    //保存文件
    try {
        FileOutputStream fos = new FileOutputStream(newFile);
        InputStream is = file.getInputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len = is.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
        fos.close();
        is.close();
        map.put("error",0);
        map.put("status","ok");
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return map;
}

结果:存储在tomcat路径下:

 

  1. 多文件上传,配置和单文件一样

前端页面:

<form action="douploadmore" method="post" enctype="multipart/form-data">
    <input type="text" name="text"><br>


    <input type="file" name="files"><br>
    <input type="file" name="files"><br>
    <input type="submit" value="确定"><br>
</form>

Controller:

@RequestMapping("douploadmore")
@ResponseBody
public Map<String,Object> doUploadMore(@RequestParam("text") String text, @RequestParam("files") CommonsMultipartFile[] files, HttpServletRequest request){
    Map<String,Object> map = new HashMap<String, Object>();
    if(files == null ||files.length == 0){
        return map;
    }
    String spath = request.getServletContext().getRealPath("uploadsmore");
    System.out.println("path="+spath);
    File path = new File(spath);
    if(!path.exists()){
        path.mkdirs();
    }
    //循环处理文件
    for(int i=0;i<files.length;i++){
        File newFile = new File(path,System.currentTimeMillis()+"_"+files[i].getOriginalFilename());
        //保存文件
        byte[] buffer = new byte[1024];
        int len = 0;
        try {
            FileOutputStream fos = new FileOutputStream(newFile);
            InputStream is = files[i].getInputStream();

            while((len = is.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
            fos.close();
            is.close();
            map.put("error",0);
            map.put("status","ok");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return map;
}

第二节:文件下载

  1. 文件下载

首先,在tomcat路径下添加文件夹及文件:

 

前端页面:

<h3>文件下载</h3>
<form action="dodownload">
    <input type="submit" value="文件">
</form>

Controller:

@RequestMapping("dodownload")
    @ResponseBody
    public Map<String, Object> doDownlaod(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> map = new HashMap<String, Object>();
        String downLoadPath = "file";
        /*
            如果文件名是从客户端获取,则需要对文件名进行处理,避免乱码
      fileName = new String(fileName.getBytes("iso-8859-1"),"utf-8");//设置文件名编码格式,否则资源请求中有中文会乱码
             */
        // 根据id获取文件名,测试假设下载文件
        String fileName = "测试封面.jpg";
        //获取下载绝对路径,
        String filePath = request.getServletContext().getRealPath("file");
        System.out.println("filepath = " + filePath);
        File file = new File(filePath, fileName);

        //查看请求头"User-Agent"以获取浏览器类型,并设置链接的编码方式
        String header = request.getHeader("User-Agent");
        byte[] buffer = new byte[1024];
        int len = 0;
        try {
            if (header.contains("firefox")) {
                BASE64Encoder base64Encoder = new BASE64Encoder();
                fileName = "=?utf-8" + base64Encoder.encode(fileName.getBytes("utf-8")) + "?=";
            } else {
                fileName = URLEncoder.encode(fileName,"utf-8");
            }

        //通知浏览器以下载的方式响应请求资源
        //a.Content-Type 设置文件媒体格式     response.setContentType(request.getServletContext().getMimeType(fileName));
            //b.Content-Disposition 设置要被下载的文件名
            response.setHeader("Content-Disposition","file;filename="+fileName);
            //获取输入流
            FileInputStream fis = new FileInputStream(file);
//            获取输出流
            ServletOutputStream fos = response.getOutputStream();

            while((len=fis.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
            fis.close();
            fos.close();
            map.put("error", 0);
            map.put("status", "ok");
        } catch (UnsupportedEncodingException e
        ) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
  }

测试结果:

 

 

章:异常处理

  1. 异常处理的目的是,不在前端页面显示后端服务器的500错误信息,通过异常处理可以实现不同的异常产生时,跳转相应的错误提示页面去。
  2. 使用自带的简单的异常处理器

SimpleMappingExceptionResolverHandlerExceptionResolver的子类

SpringMVC-config文件中配置异常处理器:

<!--   SrpingMVC提供简单异理器-->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!--        -->
        <property name="defaultErrorView" value="error/error"></property>
<!--        义异面用来获常信息的量名,也可以不定,默Exception-->
        <property name="exceptionAttribute" value="ex"></property>
<!--        需要特殊理的,重点-->
                  <property name="exceptionMappings">
                      <props>
                          <prop key="com.iss.exception.DivZeroException">error/error_div</prop>
                      </props>
                  </property>
    </bean>

自定义异常类:

public class DivZeroException extends Exception{
    private String message;

    public DivZeroException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

前端页面:

 

<form action="calc/div">
    <input type="text" name="num1">/
    <input type="text" name="num2">
    <input type="submit" value="ok">
</form>

设置异常后要跳转的页面

<body>
不能进行除0操作,请重新输入数据
</body>

 

Controller:

@RestController
@RequestMapping("calc")
public class CalcController {
    @RequestMapping("div")
    public Map<String ,Double> div(Double num1, Double num2) throws DivZeroException {
        Map<String ,Double> map = new HashMap<String, Double>();
        if(num2 == 0){
            throw new DivZeroException("不能行除0操作!");
        }
        map.put("result",num1/num2);
        return map;
    }
}

 

  1. 定义全局异常处理器,控制器里必须要把异常throws,不能用try-catch,如果try-catch的话,就在Controller中处理了,就不能抛给异常处理器了。

自定义一个除0的异常类:

public class DivZeroException extends Exception{
    private String message;

    public DivZeroException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

自定义另一个异常类:

public class DefaultException extends Exception{
    private String message;

    public DefaultException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

 

自定义异常处理类继承HandlerExceptionResolver

 

public class MyHanderExceptionResolver implements HandlerExceptionResolver {
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView modelAndView = new ModelAndView();
        Exception exception = null;
        if(ex instanceof DivZeroException){
            System.out.println("if");
            exception = (DivZeroException) ex;
            modelAndView.setViewName("/error/error_div");
        }else{
            System.out.println("else");
            exception = new DefaultException("认错误");
            modelAndView.setViewName("/error/error");
        }

        return modelAndView;
    }
}

 

SpringMVC-config文件中配置自定义异常处理器:

<bean class="com.iss.exception.MyHanderExceptionResolver"></bean>

Controller:

@RestController
@RequestMapping("calc")
public class CalcController {
    @RequestMapping("div")
    public Map<String ,Double> div(String num1, String num2) throws Exception {
        double n1 = Integer.parseInt(num1);
        double  n2 = Integer.parseInt(num2);
        Map<String ,Double> map = new HashMap<String, Double>();
        if(n2 == 0){
            throw new DivZeroException("不能行除0操作!");
        }
        map.put("result",n1/n2);
        return map;
    }
}

前端页面和跳转的错误页面同上。

执行结果

  1. 除0时:

结果:

  1. 输入为非数字时:

 

结果:

 

 

 

posted @ 2021-05-17 17:47  YangYuJia  阅读(13)  评论(0)    收藏  举报