动力节点 SpringMVC P54-61

哔哩哔哩视频链接
笔记链接参考

(一)请求转发和重定向

在这里插入图片描述
在这里插入图片描述

(二)项目准备

1、复制一份ch02的代码,重命名为ch08 forward-redirect,删掉target文件夹和.iml文件后,更改pom.xml文件中的项目名信息。
然后点击Project Structure,点击+,import Modules,选择Maven项目,点击ok,将刚刚这个ch08的项目引入。
2、修改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>当处理器方法返回ModelAndView实现forward</p>
    <form action="doFoward.do" method="post">
        姓名:<input type="text" name="name"/><br/>
        年龄:<input type="text" name="age"/><br/>
        <input type="submit" value="提交请求"/>
    </form>
</body>
</html>

(三)请求转发forward

1、视图解析器代码在springmvc.xml中:

<!--声明 springmvc框架中的视图解析器,帮助开发人员设置视图文件的路径-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:视图文件位置-->
        <property name="prefix" value="/WEB-INF/view/"/>
        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp"/>
    </bean>

在MyController文件中,可以省略文件名的前缀和后缀,但是这里指的当然只是前缀为/WEB-INF/view/目录的文件。一旦我们要访问webapp下的文件hello.jsp,是没有办法访问的。
2、修改MyController.java文件(注意method要改为POST的提交方式):

@Controller
public class MyController {

    //指定sme.do用GET请求获取
    @RequestMapping(value="/doForward.do",method= RequestMethod.POST)
    public ModelAndView doSome(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用springmvc做web开发");
        mv.addObject("fun","执行的是doSome方法");
        //mv.setViewName("show");
        //显示转发
        mv.setViewName("forward:/WEB-INF/view/show.jsp");
        return mv;
    }
}

3、成功运行:
在这里插入图片描述
在这里插入图片描述
4、复制一份show.jsp页面到webapp文件夹下改名为hello.jsp,这个时候使用视图解析器就无法访问到这个文件了(因为已经制定了文件路径的前缀是WEB/INF)。这时只要将MyController文件路径改成这个:

mv.setViewName("forward:/hello.jsp");

在这里插入图片描述
在这里插入图片描述

(四)重定向redirect

1、在index.jsp中增加一个表单:

    <p>当处理器方法返回ModelAndView实现redirect</p>
    <form action="doRedirect.do" method="post">
        姓名:<input type="text" name="name"><br/>
        年龄:<input type="text" name="age"><br/>
        <input type="submit" value="提交请求">
    </form>

2、在MyController类中增加doSome2方法:

@RequestMapping(value="/doRedirect.do",method= RequestMethod.POST)
    public ModelAndView doSome2(String name,Integer age){
        ModelAndView mv = new ModelAndView();
        //数据放入到request作用域
        mv.addObject("myname",name);
        mv.addObject("myage",age);
        //重定向
        mv.setViewName("redirect:/hello.jsp");
        //http://localhost:8080/ch08_forward_redirect/hello.jsp?myname=lisi&myage=22
        return mv;
    }

因为在@RequestMapping处发起了一次request请求,并传参给下面的name和age;但在重定向时又发起了一次request请求。所以在hello.jsp即展示界面中不能直接访问到“myname”和"myage"的值,因为是两次不同的request请求。
3、因此,还要修改hello.jsp界面,用${param.myname}获取请求信息。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>hello.jsp从request作用域获取数据</h3><br/>
    <h3>myname数据:${param.myname}</h3><br/>
    <h3>myage数据:${param.myage}</h3>
    <h3>取参数数据:<%=request.getParameter("myname")%></h3>
</body>
</html>

4、运行成功:
在这里插入图片描述
在这里插入图片描述

(五)总结

在这里插入图片描述

(六)集中统一处理异常

6.1 springmvc框架的异常处理机制

springmvc框架采用的是统一的、全局的异常处理。
把controller中的所有异常处理都集中到一个地方,即采用的是aop思想,把业务逻辑和异常处理代码分开,也叫解耦合。
使用两个注解:
1)@ExceptionHandler
2)@ControllerAdvice

6.2 异常处理的步骤

在这里插入图片描述

6.3 项目代码

1、项目准备及代码编写
(1)复制一份ch08的代码,重命名为ch09 exception-handler。
(2)删除webapp文件夹下的hello.jsp,只留下index.jsp。删除部分表单,修改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>

(3)接下来准备异常类:
在com.bjpowernode文件夹下新建exception文件夹,新建MyUserException类作为异常类,在该文件extends后面增加Exception,表示继承这个类Exception。然后按ctrl+O键重新方法,选择Exception0、Exception(message:String)两个方法进行重写(一般放在第一个和第二个)。
在这里插入图片描述
同样的方法准备AgeException类和NameException类,但它们的父类是MyUserException类(即extends MyUserException)。
(4)在MyController类中加异常代码(如果是加了try和catch,就是自己在处理异常;如果不加,就是交给框架处理),出现红色波浪线,选择Add Ex…抛出异常,但是NameException、AgeException两个异常都要抛出,所以将抛出的异常交给父类MyUserException。

@Controller
public class MyController {
    @RequestMapping(value="/some.do")
    public ModelAndView doSome(String name,Integer age) throws MyUserException {
        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;
    }
}

(5)创建一个普通类,作用全局异常处理类。
在com.bjpowernode包下新建package名为handler,在下面新建类GlobalExceptionHandler。

/**
 * @ControllerAdvice:控制器增强(也就是说给控制器类增加功能--异常处理功能)
 *              位置:在类的上面
 *   特点:必须让框架知道这个注解所在的包名,即需要在springmvcl配置文件中声明组件扫描器指定@ControllerAdvice所在的包名。
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    //定义方法,处理发生的异常
    /*
        形参:Exception,表示Controller中抛出的异常对象。通过形参可以获取发生的异常信息。
        @ExceptionHandler(异常的class):表示异常的类型,当发生此类型异常时,由当前方法处理。
     */
    //处理NameException
    @ExceptionHandler( value = NameException.class)
    public ModelAndView doNameException(Exception exception){
        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){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","你的年龄不能大于80");
        mv.addObject("ex",exception);
        mv.setViewName("ageError");
        return mv;
    }

    //处理其他异常,相当于else
    @ExceptionHandler
    public ModelAndView doOtherException(Exception exception){
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","出现其他异常");
        mv.addObject("ex",exception);
        mv.setViewName("defaultError");
        return mv;
    }
}

(6)检查springmvc.xml文件中是否声明了组件扫描器。
(7)删掉WEB-INF/view文件夹下的other.jsp,修改show.jsp:

<body>
    <h3>show.jsp从request作用域获取数据</h3><br/>
    <h3>myname数据:${myname}</h3>
    <h3>myage数据:${myage}</h3>
</body>

(8)然后在view文件夹下新建ageError.jsp。提示信息${msg}是来自于GlobalExceptionHandler类中"msg"的相关提示;
${“ex.message”}则对应于:在AgeException类中的构造方法中有super(message),这个message来自于MyController类中抛出异常时提示的信息throw new AgeException(“年龄比较大!!!”)。

<body>
    ageError.jsp<br/>
    提示信息:${msg}<br/>
    系统异常消息:${ex.message}
</body>

同理,在view文件夹下创建nameError.jsp、defaultError.jsp。
(8)修改springmvc的配置文件
增加两个注解(注意:增加注解驱动<mvc:annotation-driven时一定要选到后面是/mvc的才能按enter键)。

    <!--处理异常需要的两步-->
    <context:component-scan base-package="com.bjpowernode.handler" />
    <mvc:annotation-driven/>

2、项目运行结果在这里插入图片描述

(1)正常执行
在这里插入图片描述
在这里插入图片描述
(2)异常执行
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
(3)其他异常
在这里插入图片描述在这里插入图片描述
3、小结
(1)当用户输入完信息后,将形参提交请求到MyController类。如果中间出现异常,则根据异常跳转到GlobalExceptionHandler类,根据异常类型找到对应的@ExceptionHandler的value值,接下来走这个值下对应的方法。
方法中的msg就是最后显示在XXError.jsp界面的提示信息;XXError.jsp界面的系统异常信息则是MyController类文件中throw new NameException的值。
(2)controller是业务逻辑代码,发现了异常后统一交给handler文件夹下的GlobalExceptionHandler类文件出来,即handler是非业务逻辑代码,整体组成了AOP的思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值