SpringMVC学习笔记

本文详细介绍了SpringMVC框架的基本概念、配置方法及其实战应用,包括注解使用、请求参数绑定、数据类型转换等内容,并探讨了文件上传、异常处理及拦截器等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

补充待整理

Spring中的注解       JAX-RS自身的注解

@RequestParam    @QueryParam                 

@PathVariable       @PathParam

 

 

Restful风格:

使用复数名词,不要使用单数名词

详细的说:

SpringMVC的框架

处理器映射器:根据url找到对应的handler

 

入门程序:

1)需求:

2)搭建配置(构建一个maven的项目):

创建两个文件

配置POM文件:

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.0</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>

配置前端控制(前端控制器就是一个Servet):

编写JSP

编写Controller

让一个类的方法执行,首先将这个类变为对象

开启注解扫描:

加载springmvc.xml文件

配置试图解析器:

在Controller中返回"success",就在上面的路径下,找.jsp后缀的文件。

过程说明:

前端控制器DispatcherServlet:

用户请求到达前端控制器,它相当于mvc模式中的c,dispatcherServlet是整个流程控制中心,由它调用其他组件处理用户的请求,dispacherServlet的存在降低了组件间的耦合性。

处理器映射器:发过来的请求可以使用Controller中的哪个方法去执行

处理器适配器:处理器是Controller中的方法,采用的是适配器模式。任何Controller,任何类中的任何方法都可以使用适配器去执行

试图解析器:跳转到XX页面

有这个注解自动加载:处理器映射器和助力器适配器

 

将版本单独提取出来了。

清晰的角色划分,模块化开发,请求在一个一个模块键执行,每个模块都能指定一个功能。

前端控制器(DispatcherServlet)

请求处理器映射(HandlerMapping)

处理器适配器(HandlerAdapter)

视图解析器(ViewResolver)

处理器或页面控制器(Controller)

验证器(Validator)

命令对象(Command 请求绑定到的对象就叫)

表现层的框架一般使用MVC的模型做架构,

控制器:将请求接收到,用JavaBean将接收到的数据封装起来,JavaBean中的数据和持久层中的数据进行映射,业务层的返回数据也可以封装到JavaBean中,最终将数据返回到JSP,在JSP中显示成果。

 

 

请求参数的绑定:

在方法上加username和password参数,参数名字和传入值名字一致,MVC自动将传入值赋值到参数上。

支持类型

1)基本数据类型和字符串类型

2)实体类型

3)集合数据类型

1)RequestMapping注解:

RequestMapping注解的作用:用于建立请求URL和处理方法之间的对应关系。

参数绑定示例一:

jsp文件(超链接方式):

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>

<body>
    <%--请求参数绑定--%>
    <a href="param/testParam?username=hehe&password=123">请求参数绑定</a>
</body>
</html>

Controller文件:

@Controller
@RequestMapping("/param")
@ResponseBody
public class HelloController
{
    @RequestMapping(name="/testParam")
    public String testParam(String username,String password){
        System.out.println("执行了.....");
        System.out.println("用户名:"+username+"密码:"+password);
        return "successController";
    }
}

输出:

执行了.....
用户名:hehe密码:123

说明:

1)第一个属性path:

@RequestMapping(value="/test")
这里的value也可以换成path,也可以不写

2)第二个属性method

指定POST,GET等方式

3)第三个属性params

params指定后,必须有这个参数。

现在没有传入username

补充:@RequestParam(value="username")注解。

参数绑定示例二(表单方式):

如果传入的Bean的方式,此时name要与类中的属性对应。

name="username" 中的username和Account类中username对应,如果Account类中还有一个User类,此时在name中使用

name="user.name"的方式。

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
    <title>Title</title>
</head>

<body>
    <%--请求参数绑定--%>
    <%--表单方式--%>
    <form action="param/saveAccount" method="post">
        姓名:<input type="text" name="username"/><br/>
        密码:<input type="text" name="password"/><br/>
        金额:<input type="text" name="money"/><br/>
        用户姓名:<input type="text" name="user.name"/><br/>
        用户年龄:<input type="text" name="user.age"/><br/>
        <input type="submit" name="提交"/>
    </form>
</body>
</html>

Controller文件:

@Controller
@RequestMapping("/param")
@ResponseBody
public class HelloController
{
//    请求参数绑定把数据封装到javaBean的类中
    @RequestMapping(value="/saveAccount",method = RequestMethod.POST)
    public String saveAccount(Account account){
        System.out.println("执行了....");
        System.out.println(account);
        return "successAccount";
    }
}

输出:

执行了....
Account{username='1', password='2', money=3.0, user=User{username='null', age=5}}

如果 @RequestMapping(value="/saveAccount",method = RequestMethod.GET)此时会失败

参数绑定示例三:

绑定参数演示:

<form action="param/saveAccountAndList" method="post">
    姓名:<input type="text" name="username"/><br/>
    密码:<input type="text" name="password"/><br/>
    金额:<input type="text" name="money"/><br/>
    用户姓名:<input type="text" name="list[0].username"/><br/>
    用户年龄:<input type="text" name="list[0].age"/><br/>
    用户姓名:<input type="text" name="map['one'].username"/><br/>
    用户年龄:<input type="text" name="map['one'].age"/><br/>
    <input type="submit" name="提交"/>
</form>
    @RequestMapping(value="/saveAccountAndList",method = RequestMethod.POST)
    @ResponseBody
    public String saveAccountAndList(AccountContainsList account){
        System.out.println("执行了....");
        System.out.println(account);
        return "successAccount";
    }

输出:

AccountContainsList{username='123', password='123', money=13.0, list=[User{username='13', age=1}], map={one=User{username='2', age=3}}}

自定义类型转换器:

背景:前端界面输入的数据都是字符串格式的,但是后台的类可能是Integer类型的,springmvc框架进行了自动数据类型转换。

例如:2019/11/11可以自动转换为时间类型,但是2019-11-11不能自动转换为时间类型。

public class UserTestTrans {
    String username;
    String password;
    Date date;
....}
    //自定义转换器
    @RequestMapping(path="/testTranDate")
    public String testTranDate(UserTestTrans userTestTrans){
        System.out.println(userTestTrans.toString());
        return "success";
    }
    <%--自定义类型转换--%>
    <form action="param/testTranDate" method="post">
        姓名:<input type="text" name="username"/><br/>
        密码:<input type="text" name="password"/><br/>
        时间:<input type="text" name="date"/><br/>
        <input type="submit" name="提交"/>
    </form>

输出:

此时无法自动转换。

编写转换器类:

public class StringToDateConverter implements Converter<String,Date> {

    @Override
    public Date convert(String s) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try{
            Date date = simpleDateFormat.parse(s);
            return  date;
        }catch (Exception e){

        }
        return null;
    }
}

注册类型转换器:

测试:

控制台打印:

因为字符串转时间使用的是DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");,所以输入2019/12/12时,无法成功转换,如下所式。

测试示例三:Servlet原生的API:

JSP:

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
    <title>Title</title>
</head>

<body>
    <a href="param/testServlet">Servlet原生的API</a>
</body>
</html>

Controller文件:

    @RequestMapping("/testServlet")
    public String testServlet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("执行了.....");
        System.out.println(request);
        HttpSession session = request.getSession();
        System.out.println(session);
        ServletContext servletContext = session.getServletContext();
        System.out.println(servletContext);
        System.out.println(response);
        return "success";
    }

输出:

执行了.....
org.apache.catalina.connector.RequestFacade@6ba0df5f
org.apache.catalina.session.StandardSessionFacade@70c64b69
org.apache.catalina.core.ApplicationContextFacade@3dbea878
org.apache.catalina.connector.ResponseFacade@774e143

常用注解

1)@RequestParam

表单提供的属性和后台方法中的参数的名称不同,此时后台无法接收到数据,这时候可以使用@RequestParam。

    //测试testRequestParam注解
    @GetMapping(path="/testRequestParam")
    public String testRequstParam(String username){
        System.out.println("执行了......");
        System.out.println(username);
        return "success";
    }

如果这里的参数不是username,而是name,此时就jsp中属性和参数就无法绑定,此时就要使用@RequestParam注解。

2)@RequesBody

RequestBody:用于获取请求体内容,直接使用得到的是key=value&key=value.....结构的数据(简单说就是获取请求报文的body中的内容

get请求方式不适用。

jsp文件:

    <%--测试RequestBody注解--%>
    <form action="param/testRequestBody" method="post">
        用户姓名:<input type="text" name="username"/><br/>
        用户年龄:<input type="text" name="age"/><br/>
        <input type="submit" name="提交"/>
    </form>

Controller:

    /**
     * 获取到请求体的内容
     * @return
     */
    @RequestMapping("/testRequestBody")
    public String testRequtstBody(@RequestBody String body){
        System.out.println("执行了.....");
        System.out.println(body);
        return "success";
    }

疑问:这里@ResponseBody注解的作用,这里要加吗

3)@PathVariable注解

作用:用于绑定URL中的占位符。例如,请求url中的/delete/{id},这个id就是url中的占位符。

Restful编程风格:

简述:请求地址都一样,根据不同的请求方法让不同的方法去执行。

如果localhost:8080/user/get         执行的findAll方法

如果localhost:8080/user/10 get    此时执行的是findById方法

测试示例5:PathVarabile注解获取id

    <%--测试PathVariable注解--%>
    <br>
    <a href="param/testPathVariable/10">testPathVariable</a>

Controller:

    /**
     * 测试testPathVariable注解
     */
    @RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable String id){
        System.out.println("执行了.....");
        System.out.println(id);
        return "success";
    }

输出:

执行了.....
10

注意:/testPathVariable/{id},这里要写括号

4)RequestHead注解

作用:用于获取请求消息头

    <%--同时测试获取请求头的值--%>
    <br>
    <a href="param/requestHead">testPathVariable</a>
    /**
     * 测试RequestHead
     */
    @RequestMapping("/requestHead")
    @ResponseBody
    public String requestHead(@RequestHeader(value="Accept") String header){
        System.out.println("执行了.....");
        System.out.println(header);
        return "success";
    }

 输出(获取请求头的值):

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

关于accept的说明:

https://www.jianshu.com/p/908e51e9ccd2

GET(请求的方式) /newcoder/hello.html(请求的目标资源) HTTP/1.1(请求采用的协议和版本号)
Accept: /(客户端能接收的资源类型)
Accept-Language: en-us(客户端接收的语言类型)
Connection: Keep-Alive(维护客户端和服务端的连接关系)
Host: localhost:8080(连接的目标主机和端口号)
Referer: http://localhost/links.jsp(告诉服务器我来自于哪里)
User-Agent: Mozilla/4.0(客户端版本号的名字)
Accept-Encoding: gzip, deflate(客户端能接收的压缩数据的类型)
If-Modified-Since: Tue, 11 Jul 2017 18:23:51 GMT(缓存时间)
Cookie(客户端暂存服务端的信息)
Date: Tue, 18 Jul 12:15:02 GMT(客户端请求服务端的时间)

5)测试CookieValue注解

作用:用于将指定cookie名称的值传入控制器方法参数。

浏览器访问服务,服务端会有一个session对象,会通过cookie的形式将session返回回来,以cookie形式写回一个id为JESSIONID .

    <%--测试CookieValue注解--%>
    <a href="param/testCookieValue">testCookieValue</a>
    <br>
    //测试CookieValue
    @RequestMapping(path = "/testCookieValue")
    public String testCookieValue(@CookieValue(value="JSESSIONID") String cookieValue){
        System.out.println("cookieValue: "+cookieValue);
        return "success";
    }


输出:

cookieValue: 19599835B394834BA455B2DF3BC7076E

第二天课程

1)搭建环境

SpringMVC提供了多种相应的方式

响应数据和结果视图:

方法执行完需要跳转到指定的页面,最终给用户来做一个响应,SpringMVC提供了很多种响应的方式

第一种方式:跳转返回String

    <%--测试返回组字符串--%>
    <a href="param/testString">testString</a>
    /**
     * 返回String类型
     */
    @RequestMapping("/testString")
    public String testString(Model model){
        System.out.println("testString方法执行了");
        //模拟从数据库中查询出User对象
        User user = new User();
        user.setUsername("小美");
        user.setId(10);
        model.addAttribute("user",user);
        return "success";
    }

返回"success"字符串,所以向success.jsp跳转

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入门成功了</h3>
    ${user.username}
    ${user.age}
</body>
</html>

在response.jsp文件中:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <a href="param/testReturnUser">testReturnUser</a>
    <br>
</body>
</html>

输出:

视图解析器:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解扫描 -->
    <context:component-scan base-package="cn.itcast"/>

    <!-- 视图解析器对象 -->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <mvc:annotation-driven />

</beans>

输出:

返回void

    <%--测试页面返回值是void类型--%>
    <a href="param/testReturnVoid">testReturnVoid</a>
    <br>
    @RequestMapping(path="/testReturnVoid")
    public void testReturnVoid(){
        System.out.println("执行了....");
        return;
    }

如果没有返回,此时会默认去找方法名.jsp即testReturnVoid.jsp,此时可以自己编写请求转发的程序

这里又分为三种情况:

1)转发

    //1.转发
    @RequestMapping("/testVoid")
    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("testVoid方法执行了...");
        // 编写请求转发的程序
      request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
        return;
    }

每当客户端给Web服务器发送一个http请求时,web服务器就会针对每个请求,分别创建一个用于代表请求的request对象和代表响应的response对象。我们可以通过request对象获得请求相关的数据和操作。通过response对象获取响应相关的数据封装和一些操作

2)重定向

    //2.重定向
    @RequestMapping("/testVoid1")
    public void testVoid1(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("testVoid方法执行了...");
        // 重定向
        response.sendRedirect(request.getContextPath()+"/index.jsp");
        return;
    }

这里为什么不能写response.sendRedirect(request.getContextPath()+"WEB-INF/pages/success.jsp");

3)直接响应

    //3.直接响应
    @RequestMapping("/testVoid2")
    public void testVoid2(HttpServletRequest request, HttpServletResponse response) throws Exception {
        System.out.println("testVoid方法执行了...");
        // 设置中文乱码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        // 直接会进行响应
        response.getWriter().print("你好");

        return;
    }

说明:

请求转发和重定向的区别:
   请求转发一次请求,请求路径处不用编写项目名称(转发的时候不会调用试图解析器,所以不会能直接写success,而要写完整的目录"/WEB-INF/pages/success.jsp")
   转发和重定向都是先跳转到JSP,由TOMCAT服务器生成HTML,最终响应给用户
   直接响应:控制台控制器直接通过响应流响应给浏览器

第三种方式ModelAndView

    //测试ModelAndView
    @RequestMapping(path="/testModelAndView")
    public ModelAndView testModelAndView(){
        System.out.println("执行了....");
        ModelAndView mv = new ModelAndView();
        User user = new User();
        user.setUsername("小美");
        user.setAge(12);
        //把user对象存储到mv对象中,也会把user对象存储到request对象
        mv.addObject(user);
        //跳转到对应的页面
        mv.setViewName("success");
        return mv;
    }

ModeAndView方式和Model方式差不多,该方式使用视图解析器,不太理解

ResponseBody响应json数据

将jquery引入jsp中

    <!--前端控制器,哪些静态资源不拦截-->
    <!--样式不拦截-->
    <mvc:resources location="/css/" mapping="/css/**"/>
    <!--图片不拦截-->
    <mvc:resources location="/images/" mapping="/images/**"/>
    <!--js下的任何文件都不拦截-->
    <mvc:resources location="/js/" mapping="/js/**"/>

发出Ajax请求

    <script>
        // 页面加载,绑定单击事件
        $(function(){
            $("#btn").click(function(){
                alert("hello btn");
                // 发送ajax请求
                $.ajax({
                    // 编写json格式,设置属性和值
                    url:"user/testAjax",
                    //
                    contentType:"application/json;charset=UTF-8",
                    data:'{"username":"hehe","password":"123","age":30}',
                    // 预期服务器返回的数据值
                    dataType:"json",
                    //请求方式
                    type:"post",
                    success:function(data){
                        // data服务器端响应的json的数据,进行解析
                        alert(data);
                        alert(data.username);
                        alert(data.password);
                        alert(data.age);
                    }
                });

            });
        });
    </script>

后台输出

    @RequestMapping("/testAjax")
    public @ResponseBody User testAjax(@RequestBody User user){
        System.out.println("testAjax方法执行了...");
        // 客户端发送ajax的请求,传的是json字符串,后端把json字符串封装到user对象中
        System.out.println(user);
        // 做响应,模拟查询数据库
        user.setUsername("haha");
        user.setAge(40);
        // 做响应,后端返回的是一个对象,而前端要获取JOSN数据,这里使用的ResponseBody
        return user;
    }

这里重点学习两个注解,@RequestBody和@ResonseBody两个注解,@RequestBody注解将前端传过来的JSON数据放到User对象中@ResonseBoyd将对象以JSON格式送到前端

 

文件上传部分

????multipart/form-data是什么意思   默认是application/x-www-form-urlencoded,此时是键值对

如下图所示,选择multipart/form-data,此时使用分隔符的方式,将表单分割成多个部分。

解析:使用Common-fileupload组件实现上传

导入jar包:

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.4</version>
    </dependency>

提交表单,所有的内容将会被封装在request对象中

1)使用Common-fileupload组件上传(传统上传)

    @RequestMapping("/fileupload1")
    public String fileuoload1(HttpServletRequest request) throws Exception {
        System.out.println("文件上传...");

        // 使用fileupload组件完成文件上传
        // 上传的位置                                                       绝对路径
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        // 判断,该路径是否存在
        File file = new File(path);
        if(!file.exists()){
            // 创建该文件夹
            file.mkdirs();
        }

        // 解析request对象,获取上传文件项
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 解析request
        List<FileItem> items = upload.parseRequest(request);
        // 遍历
        for(FileItem item:items){
            // 进行判断,当前item对象是否是上传文件项
            if(item.isFormField()){
                // 说明普通表单向
            }else{// 说明上传文件项
                // 获取上传文件的名称
                String filename = item.getName();
                // 下面两行把文件的名称设置唯一值,uuid        原先有"-",换成""
                String uuid = UUID.randomUUID().toString().replace("-", "");
                filename = uuid+"_"+filename;
                // 完成文件上传
                item.write(new File(path,filename));
                // 删除临时文件,上传会产生临时文件,上传临时文件的大小大于10KB,就会在内存中生成内存文件
                item.delete();
            }
        }

        return "success";
    }

 

2)SpringMVC的上传原理(对比于传统的上传方式)

前端选择提交,所有的内容还是会封装到request域中,配置文件解析器,文件解析器帮解析request,解析完后返回上传文件项upload,这个upload和fileupload2(MutipartFile upload)中的参数进行绑定。

步骤1)配置文件的解析器(名称必须是multipartResolver)

 <!--配置文件解析器对象-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="10485760" />
    </bean>
    @RequestMapping("/fileupload2")
    public String fileuoload2(HttpServletRequest request, MultipartFile upload) throws Exception {
        System.out.println("springmvc文件上传...");

        // 使用fileupload组件完成文件上传
        // 上传的位置
        String path = request.getSession().getServletContext().getRealPath("/uploads/");
        // 判断,该路径是否存在
        File file = new File(path);
        if(!file.exists()){
            // 创建该文件夹
            file.mkdirs();
        }

        // 说明上传文件项
        // 获取上传文件的名称
        String filename = upload.getOriginalFilename();
        // 把文件的名称设置唯一值,uuid
        String uuid = UUID.randomUUID().toString().replace("-", "");
        filename = uuid+"_"+filename;
        // 完成文件上传
        upload.transferTo(new File(path,filename));

        return "success";
    }

直接拿到了upload,就不需要自己解析了

SpringMVC跨服务器方式的文件上传

分服务器的目的:

 

SpringMVC异常处理器:

    <%--异常处理--%>
    <a href="param/testException">testException</a>
    <br>

编写Controller:

    //测试异常
    @RequestMapping(path = "/testException")
    public String testException() throws Exception{  //判处异常
        System.out.println("执行了方法");
        int i = 10/0;
        return "success";
    }

此时controller(web)会将异常抛给前端控制器

处理方式:

自定义异常:

public class MyException extends Exception {
    String message;

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

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

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

编写异常处理器:

public class SysExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        MyException ex = null;
        if(e instanceof MyException){
            ex = (MyException)e;
        }else{
            ex = new MyException("系统维护");
        }
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMessage",ex.getMessage());
        mv.setViewName("error");
        return mv;
    }
}

配置异常处理器:

 <!--配置异常处理器-->
        <bean id="sysExceptionResolver" class="cn.itcast.MyException.SysExceptionResolver"/>

补充:Ctrl+Alt+T:生成捕捉异常语句。

拦截器:

这里的处理器指的是Controller类。

过滤器什么都能拦,任何项目都能用,而拦截器只拦Controller的方法,只能使用在springmvc项目中

使用拦截器的步骤:

编写拦截器:

/**
 * 预处理:controller方法执行前
 * return  true放行,执行下一个拦截器,如果没有,执行controller方法
 * return false不放行
 */
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行了.....");
        return true;
    }
}

Ctrl+O选择preHandle方法。如果return true就会直接放行,执行controller方法,如果返回false不放行,此时可以通过request和response两个对象跳转到你要去的页面去

配置拦截器:

拦截一级目录时/param的所有请求。

        <!--配置拦截器-->
        <mvc:interceptors>
            <mvc:interceptor>
                <!--要拦截的方法-->
                <mvc:mapping path="/param/*"/>
                <!--不要拦截的方法-->
                <!--<mvc:exclude-mapping path=""-->
                <bean class="cn.itcast.interceptor.MyInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

<mvc:mapping :要拦截的方法

<mvc:exclude-mapping:不要拦截的方法

测试拦截器:

​
    //测试拦截器
    @RequestMapping(path="/testIntercepter")
    public String testIntercepter(){
        System.out.println("执行了....");
        return "success";
    }

​

输出:

拦截器接口中的其他方法:

1)预处理代码

不放行(Controller不会执行)并且跳转到错误页面

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("执行了.....");
        //拦截器第二种方式拒绝并跳转
        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
        return false;
    }
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>错误页面</h3>
</body>
</html>

输出:

2)后处理的方法

当controller执行后,往某个页面跳转之前(success执行之前)执行的方法。

    //后处理的方法
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor执行了.....后");
    }

3)最后执行的方法

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor执行了....最后");
    }

使用场景:

预处理:在controller没有执行前,就执行,可以做一些逻辑的判断,例如可以判断有没有登录,没有登录就跳转到登录页面

最后执行方法可以用来释放一些资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值