前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC学习笔记

SpringMVC学习笔记

作者头像
玛卡bug卡
发布2022-09-20 11:04:07
9470
发布2022-09-20 11:04:07
举报
文章被收录于专栏:Java后端修炼

1、概述

在了解SpringMVC之前,我们需要知道MVC架构设计模式以及J2EE的三层架构设计,MVC模式如下图所示:

三层结构如下图所示:

SpringMVC则是基于 MVC 设计理念的 Web 框架,集成于SpringFramework中。SpringMVC也就是我们熟知的'SSM'中的'S',它通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口,并且支持REST风格URL,整体采用松散耦合、可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。

SpringMVC 基于 Servlet 规范实现,所以基于 SpringMVC 的项目,需要 Servlet 容器服务器支撑,比如常用的tomcat。

2、快速上手

1)环境准备

首先需要导入项目所需要的maven依赖,包括spring-web、spring-webmvc、servlet-api、jsp相关依赖、IoC相关依赖。基本环境为Spring5.1.3.RELEASE,tomcat8。

2)逻辑代码

①控制器类

首先需要创建一个用于分发请求的控制器类,在SpringMVC中只要给类标上@Controller 注解即表示这是个控制器类,之后使用@RequestMapping 注解在方法上标明请求路径,方法的返回值即是对应的视图页面(这里以jsp为例)。

代码语言:javascript
复制
package top.jtszt.controller;
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(){
        return "/WEB-INF/pages/hello.jsp";
    }
}
②配置相关

有了@Controller注解标注的控制器类之后,我们还需要将组件扫描加入IoC容器中:

代码语言:javascript
复制
<!-- SpringMVC-config.xml -->
<beans ...>
    <context:component-scan base-package="top.jtszt"/>
</beans>

SpringMVC 的核心控制器是一个 Servlet 叫 DispatcherServlet 。所以我们需要在 web.xml中配置它,并且需要配置对应的Spring配置文件指向与启动级别:

代码语言:javascript
复制
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:SpringMVC-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

这里如果不显式配置Spring配置文件路径,默认会按照classpath:{servlet-name}-servlet.xml去查找配置文件,并且需要注意的是这里servlet的拦截路径为/,如果拦截为/*则表示连同jsp页面都拦截,而jsp是我们用来展示的,不可以进行拦截。

之后是配置tomcat以及jsp页面

③测试

配置完毕,我们可以启动项目,在浏览器查看效果。

3、视图解析器

1)概述

SpringMVC中的视图解析器(ViewResolver)是前端控制器中九大组件之一,用于将逻辑视图转化为物理视图。SpringMVC会先将控制器类的 String/ModelAndView/View 类型的返回值都转化为ModelAndView 类型,之后视图解析器把它解析为具体的View 类型的视图对象。

ViewResolver接口中有几个主要的实现类,可以实现视图解析功能:

•BeanNameViewResolver:将视图名解析为一个Bean•InternalResourceViewResolver:将视图名解析为一个URL文件•jasperReportsViewResolver:将视图名解析为报表文件对应的URL

我们可以选择一种视图解析器或混用多种视图解析器,并且每个视图解析器都实现了 Ordered 接口并开放出一个 order 属性,可以通过 order 属性指定解析器的优先顺序,order 越小优先级越高

2)解析前后缀

在对jsp页面的解析中一般使用InternalResourceViewResolver ,最常见的是配置视图解析的前缀和后缀,对于xml配置来说直接配置bean即可:

代码语言:javascript
复制
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/"/>
    <property name="suffix" value=".jsp"/>
</bean>

其中 prefix 代表解析器拼串开头,suffix 代表解析器拼串结尾,这样配置之后,我们在控制器类的返回只需要返回hello即可。

代码语言:javascript
复制
/WEB-INF/pages/hello.jsp  --->  hello

3)拼串与否?

这里还涉及到一个返回值拼串与否的问题,正常来说返回值都是按照设定的前缀和后缀进行拼串之后返回视图,而如果出现以下两种情况,那么视图解析器将不会拼前后缀:

•返回值以forward: 开头,代表的是直接转发•返回值以redirect:开头,代表的是重定向

除了以上两种情况,其他的都会进行拼串处理。

4、数据传递与参数绑定

现在已经可以实现请求分发与响应功能了,那么如果页面的数据需要在请求时才渲染要怎么做,换句话说,数据传递要怎么办?这时可以将数据放置在request域中,在页面去取出对应的数据。传统的引入HttpServletRequest传递的方式就不介绍了,这里主要介绍SpringMVC中提供了数据传递功能。

1)ModelAndView

ModelAndView 能封装数据和返回跳转的视图信息,在其中存储的数据实际上是存储在request域中。可以在参数位置传入ModelAndView对象,之后调用 setViewName 设置视图名,调用addObject 设置放置的数据信息(键值对) 。

代码语言:javascript
复制
@RequestMapping("/hello")
public ModelAndView hello(ModelAndView mv) {
    mv.addObject("msg", "this is msg from modelAndView");
    mv.setViewName("hello");
    return mv;
}

也可以手动创建一个ModelAndView对象,传入的参数为要跳转的视图名,之后调用该对象的addObject方法设置数据信息。

代码语言:javascript
复制
@RequestMapping("/hello")
public ModelAndView hello(){
    ModelAndView modelAndView = new ModelAndView("hello");
    modelAndView.addObject("msg", "this is msg from modelAndView");
    return modelAndView;
}

之后在jsp页面 ${msg} 取出即可。

当然这里可传入的不只是简单信息,也可以传入Map、List等,在jsp页面通过c:foreach取出即可。

2)Map与Model

Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器,如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。

在方法体内,我们可以通过入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。

实际上传入无论是Model、Map还是ModelMap最终都会被转化为BindingAwareModelMap对象。

代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(ModelMap modelMap, 
                      Map<String,Object> map, 
                      Model model){
    modelMap.addAttribute("msg","hello modelMap");
    map.put("msg2", "hello map");
    model.addAttribute("msg3","hello model");
    return "hello";
}

3)参数收集

① 原生数据类型

这种类型的数据除了可以在入参位置声明 HttpServletRequest ,之后通过request.getParameter() 获取参数之外,还可以直接在入参位置传入需要获取的参数。

代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(HttpServletRequest request) {
    String name = request.getParameter("name");
    System.out.println("name is "+ name);
    return "result";
}
代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(String name) {
    System.out.println("name is "+ name);
    return "result";
}

当我们访问 /hello?name="test" 时就可以在控制器中成功打印结果。

②模型类型

假设有一个Employee对象,包含id和name属性,现在我们需要将参数中的name与id获取之后包装成Employee对象,这时我们不需要手动进行包装。在SpringMVC中,如果请求的参数名称,与模型类中的属性一一对应,那么SpringMVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值,支持级联属性。

代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(Employee employee) {
    System.out.println("Employee is "+ employee);
    return "result";
}

当我们访问 /hello?id=1&name="test" 时就可以在控制器中成功打印结果。

③使用注解

在SpringMVC中还可以通过 @RequestParam 注解获取参数,这种获取方式不要求用户传参与规定参数一一对应,可以指定参数名获取。

代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(@RequestParam("username")String name) {
    System.out.println("name is "+ name);
    return "result";
}

这时访问 /hello?username="test" 时也可以在控制器中成功打印结果。

现在我们解决了参数名不一致的获取问题,那么如果不带参数访问呢?实测会抛异常,因为默认是需要传入参数的。为此该注解还有一个属性:required ,它表示请求参数中是否必须携带指定的参数。默认值是 true 。还有一个属性 defaultValue,它可以指定参数不传递时的默认值。

代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(@RequestParam(value = "username",required = false,defaultValue = "default")String name) {
    System.out.println("name is "+ name);
    return "result";
}

这时访问 /hello 也不会抛异常,并且会打印default。

④其他注解

除了获取参数的注解,SpringMVC中还有用于获取header的某个属性值的注解 @RequestHeader,以及获取cookie中的某个属性值的注解 @CookieValue

代码语言:javascript
复制
@RequestMapping("/hello")
public String hello(@RequestHeader("User-Agent")String userAgent,
                    @CookieValue("JSESSIONID")String jid){}

4)乱码问题

在接收POST请求参数时,可能会出现中文乱码的问题,这是编码集不一致导致的。SpringMVC中提供了CharacterEncodingFilter 用于解决乱码问题,它有三个属性,encoding 代表编码格式, forceRequestEncoding 代表对请求设置编码, forceResponseEncoding 代表对响应设置编码。这里我们只需要在web.xml中配置好这个filter,并且设置拦截路径为 /* 即可。

代码语言:javascript
复制
<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>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

如果是GET请求出现乱码问题,那应该考虑的是Tomcat的编码设置问题。

5、请求映射

SpringMVC中使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求,这个注解可以标注在类上,也可以标注在方法上。如果@RequestMapping("/admin") 标注在类上,那么该类下的所有方法都须以 /admin 为前缀才可以访问。

代码语言:javascript
复制
//如:
@Controller
@RequestMapping("/admin")
public class MyController {}
代码语言:javascript
复制
@RequestMapping("/hello")
public String hello() {return "hello"}

那么如果要访问到hello.jsp页面必须通过 /admin/hello 访问。

此外 @RequestMapping 中也提供了对于请求头的一些限制属性,其中 value 表示请求URL,method 表示请求方法,params 代表请求参数,heads 表示请求头,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。

此外SpringMVC也提供了几个限定请求方式的注解:

•@GetMapping("xx") :限定get方式•@PostMapping("xx") :限定post方式•@PutMapping("xx"):限定put方式•@DeleteMapping("xx"):限定delete方式

6、RESTful风格

REST即Representational State Transfer(表现层状态转化),是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。

具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。而RESTful风格就是将这四种方式与资源的操作联系起来。

举个例子,假设现在要实现员工信息的增删改查,那RESTful风格的url就可以是下面这样的:

•员工列表:/emps get方法•员工添加:/emp post方法•员工修改:/emp/{id} put方法•员工删除:/emp/{id} delete方法•员工查询:/emp/{id} get方法

这里的{id}代表的是动态的id传入,在SpringMVC中可以使用@PathVariable("id")标注在Controller的参数位置来获取URL中的指定的值。

代码语言:javascript
复制
@RequestMapping(value = "/emp/{id}")
public String getEmp(@PathVariable("id")Integer id){...}

这样当我们以GET方式访问/emp/1 时,在getEmp方法中就可以拿到具体的id。

7、返回json数据

1)导包、配置

SpringMVC中整合了主流的json转换工具,默认使用 jackson 进行 json 格式转换。使用jackson需要先导入maven依赖,包括:jackson-core、jackson-annotations、jackson-databind。导入依赖之后还需要配置json转换器,一种比较简单的方法是在SpringMVC的配置文件中加入注解驱动配置,也可以手动配置。

代码语言:javascript
复制
<!-- 开启注解驱动 -->
<mvc:annotation-driven/>

2)@ResponseBody

此外还需要在Controller对应方法上标注 @ResponseBody ,表明方法返回信息作为响应体返回(由jackson包封装为json格式)。

代码语言:javascript
复制
//假数据做示例
Employee emp = new Employee(1, "test01", "123@163.com");
代码语言:javascript
复制
@ResponseBody
@RequestMapping("/getinfo")
public Employee getInfo(){
    return emp;
}

还可以将返回值类型设置成ResponseEntity<T> ,之后在方法中new该对象,以此方法可以设置响应体、响应头以及响应状态码。

代码语言:javascript
复制
@RequestMapping("/getinfo2")
public ResponseEntity<Employee> getInfo2(){
    return new ResponseEntity<>(emp,HttpStatus.OK);
}

3)@RestController

当一个Controller类中的所有映射方法都要返回json数据,那么在每个方法上都标注上@ResponseBody 注解就不太现实了。这时可以直接在类上标注@ResponseBody ,也可以使用@RestController注解标注在Controller类上,其相当于@Controller@ResponseBody

4)@RequestBody

@ResponseBody相对的还有 @RequestBody,它可以把请求体中json格式的数据封装成指定的对象。

代码语言:javascript
复制
@PostMapping("/saveinfo")
@ResponseBody
public void saveInfo(@RequestBody Employee employee) {
    System.out.println(employee);
}

当我们POST此路径并带上json格式的数据时,其会将请求体中的数据(如果存在配对)封装成Employee对象。

除此之外还可以将参数声明为 HttpEntity<T> ,这样声明的参数除了可以获得请求体还可以获得请求头。

代码语言:javascript
复制
@PostMapping("/saveinfo2")
@ResponseBody
public void saveInfo(HttpEntity<Employee> httpEntity) {
    Employee emp = httpEntity.getBody();
    System.out.println(emp);
}

8、静态资源配置

1)默认处理器

如果我们尝试引入项目路径下的js或者css,会发现并不能访问到。这个问题源于我们将SpringMVC中的DispatcherServlet 请求映射配置为 /,这时静态资源的请求也会被当成一个普通请求处理,因找不到对应处理器而导致错误。

这时可以在 SpringMVC 的配置文件中配置默认处理器解决静态资源的问题:

代码语言:javascript
复制
<mvc:default-servlet-handler/> 

起作用的是 SpringMVC 上下文中定义的 DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 WEB 应用服务器默认的 Servlet 处理;如果不是静态资源的请求,才由 DispatcherServlet 继续处理 一般 WEB 应用服务器默认的 Servlet 的名称都是 default。若所使用的 WEB 服务器的默认 Servlet 名称不是 default,则需要通过 default-servlet-name 属性显式指定

2)解析配置

除了使用默认处理器解析之外,还可以显式地配置上对于静态资源的解析。通过xml<mvc:resources>标签进行配置,其中cache-period 表示缓存时长。

代码语言:javascript
复制
<mvc:resources mapping="/js/**" location="/scripts/" />
<mvc:resources mapping="/css/**" location="/css/" cache-period="2592000" />

这时js文件的访问会解析到项目的scripts目录,css会解析到css目录。

9、文件上传与下载

1)文件上传

①导依赖

首先需要导入文件上传所需的依赖,包括commons-fileupload,commons-io,以及IoC、MVC相关依赖。

②写配置

在基于xml的配置中,需要先配置一个文件上传处理器(CommonsMultipartResolver),其中的defaultEncoding 可以用于设置文件的编码, maxUploadSize 可以用于设置文件大小的最大值,要注意的是配置的bean的id必须为multipartResolver,否则无法识别到。

代码语言:javascript
复制
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="maxUploadSize" value="#{1024*1024*20}"/>
</bean>
③接收文件

现在写一个jsp页面加上包含上传文件的表单,访问路径为项目下的/upload:

代码语言:javascript
复制
<form action="${ctp}/upload" method="post" enctype="multipart/form-data">
    文件上传:<input type="file" name="uploadFile"/>
    <input type="submit" value="提交"/>
</form>

在Controller层我们写一个用于处理/upload请求的方法,这里传入一个 MultipartFile 类型的参数用于接收上传的文件:

代码语言:javascript
复制
@Controller
public class UploadController {
    @PostMapping("/upload")
    public String upload(@RequestParam("uploadFile")MultipartFile file){...}
}
④保存文件

MultipartFile有一个 getOriginalFilename 方法可以用于获取文件原始文件名,如果将文件保存到本地可调用MultipartFile的 transferTo() ,传入new File(xx) 之后即可持久化到本地。如果想保存到数据库,可获取文件的字节码存入。

代码语言:javascript
复制
file.transferTo(new File("I:\\upload\\"+filename));
byte[] bytes = file.getBytes();

2)文件下载

文件的下载需要借助之前写到的ResponseEntity<> 将文件的byte[] 数据放置在其中,之后设置响应头然后返回这个对象,这里演示的是图片的展示。

代码语言:javascript
复制
@Controller
public class DownloadController {
    @RequestMapping("/getImg")
    public ResponseEntity<byte[]> getImg() throws IOException {
        String filename = "I:\\upload\\mvc.png";
        byte[] bytes = Files.readAllBytes(Paths.get(filename));
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", filename);
        return new ResponseEntity<>(bytes, headers, HttpStatus.CREATED);
    }

}

在jsp页面用一个img标签接收即可。

代码语言:javascript
复制
<img src="${pageContext.request.contextPath}/getImg">

10、异常处理器

到目前为止,我们所有的异常都是直接抛出去,当我们用get方法访问一个限制POST方法访问的路径时,得到的是Tomcat的异常页面,这对于用户体验十分不友好并且存在代码安全性问题。因此我们需要让DispatcherServlet(前端控制器),去对异常进行处理。

Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常,它有四个主要的实现类可以对异常进行处理:

•ExceptionHandlerExceptionResolver•ResponseStatusExceptionResolver•DefaultHandlerExceptionResolver•SimpleMappingExceptionResolver

1)ExceptionHandlerExceptionResolver

这个异常解析器主要是处理标明 @ExceptionHandle 注解的异常,而@ExceptionHandler 是SpringMVC提供的注解,用于声明式地捕获指定的异常。该注解的标注可分为两种类型:一种是在标明@controller的类中配置,也称为本类配置;一种是在单独的类中配置,也称为全局配置。

①本类配置

在类中创建一个方法标注上@ExceptionHandle(value="xx") 注解,value属性指明需要捕获的异常,该方法的返回值会被视图解析器解析,如果想获取异常信息可以在入参位置传入异常类型。

代码语言:javascript
复制
@ExceptionHandler(value = {NullPointerException.class} )
public ModelAndView exceptionHandle(NullPointerException npe){
    npe.printStackTrace();
    ModelAndView mv = new ModelAndView("error");
    mv.addObject("exception",npe.getMessage());
    return mv;
}
②全局配置

创建一个用于处理异常的类,在类上标注 @ControllerAdvice ,表明这个类用来集中处理异常;接下在定义异常处理的方法,步骤与本类配置一致。

代码语言:javascript
复制
@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(value = {NullPointerException.class})
    public ModelAndView exceptionHandle(NullPointerException npe){
        npe.printStackTrace();
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception",npe.getMessage());
        return mv;
    }
}

如果全局和本类都有配置异常处理,那么本类的优先;如果捕获异常的处理器有多个,那么精确的优先。

2)ResponseStatusExceptionResolver

其用于处理标明 @ResponseStatus 注解的异常,可以自定义错误代码和错误原因,其中reason属性为错误原因,value属性与code为HttpStatus类型的错误代码。该注解主要是标注在自定义异常类上,之后在代码逻辑异常处理处抛出该错误类型,SpringMVC捕获之后就会调用到这个处理器。

代码语言:javascript
复制
//自定义一个异常类
@ResponseStatus(reason = "用户访问异常", code = HttpStatus.NOT_ACCEPTABLE)
class UserNotFoundInAdminException extends RuntimeException{
    static final long serialVersionUID = 1L;
}
代码语言:javascript
复制
@RequestMapping("/admin")
public String loginAdmin(@RequestParam("user")String user){
    if(user!="admin"){
        throw new UserNotFoundInAdminException();
    }
    ....
}

3)SimpleMappingExceptionResolver

用于配置简单的异常解析,可以在SpringMVC的配置文件中配置。其中class为class为SimpleMappingExceptionResolver 的全类名,exceptionMappings 属性的key为要处理的异常全类名,value为异常后跳转的视图名;exceptionAttribute 属性的value值为异常信息存储在域的key。

代码语言:javascript
复制
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="java.lang.NullPointerException">error</prop>
        </props>
    </property>
    <property name="exceptionAttribute" value="ex"/>
</bean>

4)DefaultHandlerExceptionResolver

用于处理SpringMVC自带的异常,当没有找到其他的异常解析器时,就会来到这个异常解析器解析。

11、拦截器

1)概述

首先需要区分一些拦截器和过滤器的概念。拦截器是SpringMVC中的一个API设计,而过滤器是Servlet中的一个组件。所有经过Servlet容器的请求都可以被过滤器截获到,而拦截器只对经过DispatcherServlet 处理的请求有效。此外,拦截器通过IoC统一管理,所以可以进行任意注入。

2)配置

拦截器的核心接口是HandleInterceptor ,自定义的拦截规则要实现该接口,该接口中有三个主要方法,代表着三个执行时机:

•preHandle:目标方法运行前,返回true则代表放行;•postHandle:目标方法运行后;•afterCompletion:视图响应之后;

代码语言:javascript
复制
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, 
                             Object handler) throws Exception {
        System.out.println("preHandle.....");
        return true;
    }

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

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

接着我们需要将拦截器注册到IoC容器中,使用的是<mvc:interceptors>标签,这也说明可以注册多个拦截器;<mvc:interceptor> 标签体内有一个 <mvc:mapping> 用于配置拦截路径, <bean>用于配置拦截器:

代码语言:javascript
复制
<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/"/>
        <bean class="top.jtszt.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

3)拦截流程

从上面我们可以看到拦截器一共有三个运行的时机:目标方法运行前、目标方法运行后、视图响应之后。在配置了拦截器的请求流程大致为:

1.preHandle2.目标方法运行3.postHandle4.视图响应5.afterCompletion

4)多拦截器

假设配置了两个拦截器,按照配置顺序第一个记为interceptor1,第二个记为interceptor2。

12、跨域问题

跨域指的是当前发起请求的域与该请求指向的资源所在的域不一样,这里的域概念表示的是协议、域名、端口(同源策略)。只有当这三者都相同才属于同一个域。当这三个任一个不相同则会引发跨域问题。

SpringMVC中可以在允许跨域的方法上标注 @CrossOrigin 注解,该注解上可以指定跨域范围。这个注解实际上是给响应头中添加了一个 Access-Control-Allow-Origin:


参考资料:

•Spring Framework 5.1.3.RELEASE文档[1]•从 0 开始深入学习 Spring-掘金小册[2]•浅谈 MVC与三层架构-CSDN[3]•SpringMVC之视图解析器-CSDN[4]•Spring5 系统架构-CSDN[5]•雷丰阳Spring、Spring MVC、MyBatis课程-bilibili[6]

相关链接

[1] Spring Framework 5.1.3.RELEASE文档: https://docs.spring.io/spring-framework/docs/5.1.3.RELEASE/spring-framework-reference/ [2] 从 0 开始深入学习 Spring-掘金小册: https://juejin.cn/book/6857911863016390663/section [3] 浅谈 MVC与三层架构-CSDN: https://blog.csdn.net/weixin_42153410/article/details/90753696 [4] SpringMVC之视图解析器-CSDN: https://blog.csdn.net/u012369373/article/details/77529595?utm_source=tuicool&utm_medium=referral [5] Spring5 系统架构-CSDN: https://blog.csdn.net/lj1314ailj/article/details/80118372 [6] 雷丰阳Spring、Spring MVC、MyBatis课程-bilibili: https://www.bilibili.com/video/BV1d4411g7tv?p=256

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java后端修炼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、概述
  • 2、快速上手
    • 1)环境准备
      • 2)逻辑代码
        • ①控制器类
        • ②配置相关
        • ③测试
    • 3、视图解析器
      • 1)概述
        • 2)解析前后缀
          • 3)拼串与否?
          • 4、数据传递与参数绑定
            • 1)ModelAndView
              • 2)Map与Model
                • 3)参数收集
                  • ① 原生数据类型
                  • ②模型类型
                  • ③使用注解
                  • ④其他注解
                • 4)乱码问题
                • 5、请求映射
                • 6、RESTful风格
                • 7、返回json数据
                  • 1)导包、配置
                    • 2)@ResponseBody
                      • 3)@RestController
                        • 4)@RequestBody
                        • 8、静态资源配置
                          • 1)默认处理器
                            • 2)解析配置
                            • 9、文件上传与下载
                              • 1)文件上传
                                • ①导依赖
                                • ②写配置
                                • ③接收文件
                                • ④保存文件
                              • 2)文件下载
                              • 10、异常处理器
                                • 1)ExceptionHandlerExceptionResolver
                                  • ①本类配置
                                  • ②全局配置
                                • 2)ResponseStatusExceptionResolver
                                  • 3)SimpleMappingExceptionResolver
                                    • 4)DefaultHandlerExceptionResolver
                                    • 11、拦截器
                                      • 1)概述
                                        • 2)配置
                                          • 3)拦截流程
                                            • 4)多拦截器
                                            • 12、跨域问题
                                              • 相关链接
                                              相关产品与服务
                                              容器服务
                                              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                              领券
                                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档