SpringMVC很难?一篇文章学会全部知识点

一.Spring集成环境

1.1 集成Jar包

pom.xml

    <groupId>me.dddz</groupId>
    <artifactId>SpringMVC</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--serlvet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <!--jstl-->
        <dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--jsp-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.3.1</version>
            <scope>provided</scope>
        </dependency>
        <!--Spring-Web-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <!--Spring mvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <!--Spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <!--Spring-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.2.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.8</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.3</version>
        </dependency>
    </dependencies>

1.2 配置ContextLoaderListener监听器

web.xml

<!--Spring-->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

1.2.1 获取ctx

ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
app.getBean("userService");

二.SpringMVC开发步骤

2.1.配置SpringMVC核心控制器DispatchrServlet

web.xml

<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

2.2.创建Controller类和视图页面

2.2.1.Controller类

配置Controller注解和业务方法映射

@Controller
public class UserController {

    @RequestMapping("/quick")//注解配置业务方法的映射地址
    public String save() {
        System.out.println("Controller save running...");
        return "success.jsp";
    }
}

2.2.2 视图页面

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

2.3.配置SpringMVC核心文件spring-mvc.xml

注解扫描

spring-mvc.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"
       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">

    <context:component-scan base-package="me.dddz.controller"/>

</beans>

三.SpringMVC组件解析

3.1.SpringMVC执行流程

在这里插入图片描述

①用户发送请求至前端控制器DispatcherServlet。

②DispatcherServlet收到请求调用HandlerMapping处理器映射器。

③处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。

④DispatcherServlet调用HandlerAdapter处理器适配器。

⑤HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。

⑥Controller执行完成返回ModelAndView。

⑦HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。

⑧DispatcherServlet将ModelAndView传给ViewReslover视图解析器。

⑨ViewReslover解析后返回具体View。

⑩DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet响应用户。

在这里插入图片描述

3.2.SpringMVC组件解析

3.2.1.前段控制器 DispatcherServlet

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

3.2.2.处理器映射器 HandlerMapping

HandlerMapping 负责根据用户请求找到 Handler 即处理器,SpringMVC 提供了不同的映射器实现不同的

映射方式,例如:配置文件方式,实现接口方式,注解方式等。

3.2.3.处理器适配器 HandlerAdapter

通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

3.2.4.处理器:Handler

它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。

3.2.5.视图解析器:View Resolver

View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

3.2.6.视图:View

SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

3.3.SpringMVC注解解析

3.3.1.@RequestMapping

  • 作用

    用于建立请求 URL 和处理请求方法之间的对应关系

  • 位置

    • 类:请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录

    • 方法:请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

    • 类上:@RequestMapping("/user") 方法上:@RequestMapping("/adduser")

      路径就是/user/adduser

  • 属性

    • value:用于指定请求的URL。它和path属性的作用是一样的

    • method:用于指定请求的方式

    • params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样

      • 例子

        params = {“accountName”},表示请求参数必须有accountName

        params = {“moeny!100”},表示请求参数中money不能是100

3.4.SpringMVC组件扫描

SpringMVC基于Spring容器

Srping和SrpingMVC各自扫描各自层,需要指定扫描的路径

所以在进行SpringMVC操作时,需要将Controller存储到Spring容器中

如果使用@Controller注解标注的话

就需要使用<context:component-scan base-package=“com.xxx.controller"/>进行组件扫描。

<context:component-scan base-package="me.dddz.controller">
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    只扫描注解的类
</context:component-scan>                      

3.5 SpringMVC的XML配置解析

SpringMVC有默认组件配置

默认组件都是DispatcherServlet.properties配置文件中配置的

该配置文件地址org/springframework/web/servlet/DispatcherServlet.properties

该文件中配置了默认的视图解析器,如下:

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

翻看该解析器源码,可以看到该解析器的默认设置,如下:

REDIRECT_URL_PREFIX = "redirect:"  --重定向前缀
FORWARD_URL_PREFIX = "forward:"    --转发前缀(默认值)
prefix = "";     --视图名称前缀
suffix = "";     --视图名称后缀

配置内部资源视图解析器

spring-mvc.xml

<!--配置内部资源视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/views/"></property>
  <property name="suffix" value=".jsp"></property>
</bean>

四.SpringMVC数据响应

  • 页面跳转
    • 直接返回字符串
    • 通过ModelAndView返回
  • 回写数据
    • 直接返回字符串
    • 返回对象或集合

4.1.页面跳转

4.1.1.返回字符串方式

4.1.1.1.直接返回字符串

此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转

在这里插入图片描述

4.1.1.2.返回带有前戳的字符串

  • 转发:forward:/WEB-INF/views/index.jsp

    • 一般开发就是request.getDispacher().forward("/WEB-INF/views/index.jsp")
  • 重定向:redirect:/index.jsp

    • 一般开发就是response.xxx

4.1.2.通过ModelAndView返回

4.1.2.1.手动创建对象

@RequestMapping("/quick1")
public ModelAndView quick1() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("redirect:index.jsp");
    return modelAndView;
}

@RequestMapping("/quick2")
public ModelAndView quick2() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("forward:/WEB-INF/views/index.jsp");
    return modelAndView;
}

4.1.2.2.通过形参让Spring自动注入

@RequestMapping(value="/quick3")
    public ModelAndView quick3(ModelAndView modelAndView){
        modelAndView.addObject("username","itheima");
        modelAndView.setViewName("success");
        return modelAndView;
}

@RequestMapping("/quick4")
public ModelAndView quick4(ModelAndView modelAndView) {
    modelAndView.setViewName("forward:/WEB-INF/views/index.jsp");
    return modelAndView;
}


@RequestMapping(value="/quick5")
public String quick5(Model model){
    model.addAttribute("username","酷丁鱼");
    return "success";
}

4.1.2.3.直接使用原生对象

@RequestMapping(value="/quick5")
public String quick5(HttpServletRequest request){
    request.setAttribute("username","酷丁鱼");
    return "success";
}

4.2 回写数据

4.2.1.直接回写字符串

@RequestMapping("/test1")
public void test1(HttpServletResponse response) throws IOException {
    response.getWriter().print("Helloworld!");
}

@RequestMapping("/test2")
@ResponseBody //告知SrpingMVC框架,不进行**页面跳转**,直接进行回写数据
public String test2() {
    return "hello mvc";
}
  • @ResponseBody:将响应内容转换为Json格式
  • @RestController:定义在类上,表示这个类是一个Controller,且类中所有方法都是@ResponseBody

4.2.2.高级运用Jackson

4.2.2.1.导入依赖

pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.11.0</version>
</dependency>

4.2.2.2.运用

@RequestMapping("/test3")
@ResponseBody
public String test3() throws IOException {
    User user = new User();
    user.setAge(19);
    user.setUsername("yzj");
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(user);
    return json;
}
//这样返回的是一个字符串json:"json内容"

4.2.3 配置SpringMVC处理器映射器

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写,为处理器适配器配置消息转换参数,指定使用jackson进行对象或集合的转换,因此需要在spring-mvc.xml中进行如下配置:

spring-mvc.xml

<!--配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </list>
    </property>
</bean>

就可以直接返回对象

@RequestMapping("/test4")
@ResponseBody
//期望SpringMVC自动将User转换成Json格式字符串
public User test4() throws IOException {
    User user = new User();
    user.setAge(19);
    user.setUsername("yzj");
    return user;
}
//配置好以后直接返回json:"json内容"

4.2.4.配置SpringMVC处理器映射器注解驱动

spring-mvc.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="me.dddz.controller"/>

    <mvc:annotation-driven/>

</beans>

在 SpringMVC 的各个组件中,处理器映射器处理器适配器视图解析器称为 SpringMVC 的三大组件。

使用mvc:annotation-driven自动加载 RequestMappingHandlerMapping(处理映射器)和

RequestMappingHandlerAdapter( 处 理 适 配 器 ),可用在Spring-xml.xml配置文件中使用

mvc:annotation-driven替代注解处理器和适配器的配置。

同时使用mvc:annotation-driven默认底层就会集成jackson进行对象或集合的json格式字符串的转换。

五.SpringMVC获得请求参数

  • 基本类型参数
  • POJO类型参数
  • 数组类型参数
  • 集合类型数组

5.1.获得基本类型参数

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配。并且能自动做类型转换;

自动的类型转换是指从String向其他类型的转换

访问地址:http://localhost:8080/SpringMVC_war_exploded/test5?username=yzj&age=8

@RequestMapping("/test5")
@ResponseBody
public void test5(String username, int age) throws IOException {
    System.out.println("username = " + username);
    System.out.println("age = " + age);
}

5.2.获得POJO类型参数

Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配。

访问地址:http://localhost:8080/SpringMVC_war_exploded/test6?username=yzj&age=8

@RequestMapping("/test6")
@ResponseBody
public void test6(User user) throws IOException {
    System.out.println("user = " + user);
}

5.3.获得数组类型参数

Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配。

访问地址:http://localhost:8080/SpringMVC_war_exploded/test7?strs=a&strs=b&strs=c&strs=d

@RequestMapping("/test7")
@ResponseBody
public void test6(String [] strs) throws IOException {
    System.out.println(Arrays.asList(strs));
}

5.4.获得集合类型参数

5.4.1.使用form表单提交

将集合参数包装到一个POJO中才可以。

  • POJO对象
public class VO {
    private List<User> userList;

    @Override
    public String toString() {
        return "VO{" +
            "userList=" + userList +
            '}';
    }

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }
}
  • 前端数据封装
<form action="${pageContext.request.contextPath}/test8" method="POST">
    <input type="text" name="userList[0].username"><br/>
    <input type="text" name="userList[0].age"><br/>
    <input type="text" name="userList[1].username"><br/>
    <input type="text" name="userList[1].age"><br/>
    <input type="text" name="userList[2].username"><br/>
    <input type="text" name="userList[2].age"><br/>
    <input value="submit"><br/>
</form>
  • 后端代码测试
@RequestMapping("/test8")
@ResponseBody
public void test8(VO vo) throws IOException {
    System.out.println("vo = " + vo);
}

5.4.2.使用Ajax提交

指定contentType为json形式,那么在方法参数位置使用**@RequestBody**可以直接接受集合数据

无需使用POJO进行包装

  • @RequestBody:将请求内容转换为Json格式
  • ajax代码
<script type="application/javascript">
var userList = new Array();
userList.push({username:"yzj", age:22});
userList.push({username:"xsy", age:21});
userList.push({username:"zhangsan", age:25});
$.ajax({
    type: "POST",
    url: "${pageContext.request.contextPath}/test9",
    data: JSON.stringify(userList),
    contentType: 'application/json;charset=utf8'
});
</script>
  • 后端代码
@RequestMapping("/test9")
@ResponseBody
public void test9(@RequestBody List<User> userList) throws IOException {
    System.out.println("userList = " + userList);
}

5.5.请求杂项

5.5.1.配置静态资源

通过谷歌开发者工具抓包发现,没有加载到jquery文件,原因是SpringMVC的前端控制器DispatcherServlet的url-pattern配置的是/,代表对所有的资源都进行过滤操作,我们可以通过以下两种方式指定放行静态资源

  • 在spring-mvc.xml配置文件中指定放行的资源
    • 原理:将某些路径自定义mapping

spring-mvc.xml

<mvc:resources mapping="/js/**" location="/js/"/> 
  • 使用<mvc:default-servlet-handler/>标签
    • 原理:mvc找不到的资源默认交给谁处理

5.5.2.配置请求数据编码

当post请求时,数据会出现乱码,可以设置一个过滤器来进行编码的过滤。

web.xml

<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>

环境变量JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8

IDEA VM Options配置:-Dfile.encoding=UTF-8

IDEA Tomcat VM Options配置:-Dfile.encoding=UTF-8

5.6.@RequestParam

当请求的参数名称与Controller的业务方法参数名称不一致时,就需要通过@RequestParam注解进行显示的绑定

  • value:请求的参数名称
  • required:指定的请求参数是否必须包括,默认是true,如果没有此参数则报错
  • defaultValue:当没有指定请求参数时,则使用指定的默认值赋值
  • 前端代码
<form action="${pageContext.request.contextPath}/test10" method="POST">
    <input type="text" name="name"><br/>
    <input type="submit" value="提交"><br/>
</form>
  • 后端代码
@RequestMapping("/test10")
@ResponseBody
public void test110(@RequestParam("name") String x) throws IOException {
    System.out.println("x = " + x);
}

5.7.Restful风格参数

Restful是一种软件架构风格、设计风格、而不是标准,只提供了一组设计原则和约束条件。主要用于客户端额服务器交互类的软件,基于这个风格设计的软件可以更简洁、更有层次、更易于实现缓存机制

Restful风格的请求是使用"URL+请求方式"表示一次请求的目的,HTTP协议里面的四个表示操作方式:

  • GET:获取资源
  • @GetMapping
  • POST:新建资源
  • @PostMapping
  • PUT:更新资源
  • @PutMapping
  • DELETE:删除资源
  • @DeleteMapping
  • 获得Restful风格的参数
    • 第一步:@RequestMapping("/test12/{name}") 配置占位符
    • 第二部:@PathVariable(value = “name”, required = true),参数绑定占位符
    • 第三部:请求:http://localhost:8080/test12/yzj
@RequestMapping("/test12/{name}")
@ResponseBody
public void test12(@PathVariable(value = "name", required = true) String name) {
    
}

5.8.自定义类型转换器

  • SpringMVC 默认已经提供了一些常用的类型转换器
    • 客户端提交的字符串转换成int型进行参数设置
  • 对于没有提供的就需要自定义转换器
    • 日期类型的数据就需要自定义转换器。

开发步骤

  • 第一步:定义转换器类实现Converter接口

    public class DateConverter implements Converter<String, Date> {
        @Override
        public Date convert(String s) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = simpleDateFormat.parse(s);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
  • 第二步:在spring-mvc.xml中声明

    <bean id="converterService"
          class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="me.dddz.converter.DateConverter"/>
            </list>
        </property>
    </bean>
    
  • 第三步:在<annotation-driven>中引用转换器

    <mvc:annotation-driven conversion-service="converterService"/>
    

5.9.获得请求头

  • @RequestHeader 相当于request.getHeader()
    • value:请求头的名称
    • required:是否必须携带请求头
@RequestMapping("/test12")
@ResponseBody
public void test12(@RequestHeader(value = "User-Agent") String ua) throws IOException {
    System.out.println("ua = " + ua);
}
  • @CookieValue
@RequestMapping("/test13")
@ResponseBody
public void test13(@CookieValue("JSESSIONID") String jid) {
    System.out.println("jid = " + jid);
}

5.10.文件上传

当from表单修改为多部分表单时,request.getParameter()将失效

lenctype="application/x-www-form-urlencoded"时,form表单的正文内容格式是:key=value&key=value&key=value

l当form表单的enctype取值为Mutilpart/form-data时,请求正文内容就变成多部分形式:

在这里插入图片描述

  • 导入common-fileupload组件

    pom.xml

    <!--fileupload-->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.7</version>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    
  • 代码实现

    • 前端

      <form action="${pageContext.request.contextPath}/test14" method="post" enctype="multipart/form-data">
          <input type="text" name="username"><br/>
          <input type="file" name="uploadFile" value="点击上传" multiple="multiple"><br/>
          <input type="submit" value="提交"><br/>
      </form>
      
    • 后端

      • 传统方式

        //上传位置
        String path = request.getSession().getServletContext().getRealPath("/uploads");
        File file = new File(path);
        fi(!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();
                item.write(new File(path, filename));
                item.delete();
            }
        }
        
      • SpringMVC方式

        spring-mvc.xml

        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="maxUploadSize" value="5242800"/>
            <property name="maxUploadSizePerFile" value="5242800"/>
            <property name="defaultEncoding" value="UTF-8"/>
        </bean>
        
        @RequestMapping("/test14")
        @ResponseBody
        public void test13(String username, MultipartFile uploadFile) throws IOException {
            System.out.println("username = " + username);
            String originalFilename = uploadFile.getOriginalFilename();
            uploadFile.transferTo(new File("D:" + File.separator + "upload" + File.separator + originalFilename));
        }
        

        多文件上传将MultipartFile改成数组即可

六.SpringMVC拦截器

SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理

  • 拦截器链:Interceptor Chain —类似于Filter Chain
    • 拦截器是AOP思想的具体实现

6.1.Interceptor和Filter的区别

Filter Interceptor
使用范围 是Servlet规范中的一部分,任何JavaWeb工程都可以使用 是SpringMVC框架自己实现的,只有使用了SpringMVC框架的工程才能用
拦截范围 在url-pattern中配置了/*之后,可以对所有要访问的资源拦截 只会拦截访问的控制器方法,如果访问的是jsp、html、css、image或者js是不会进行拦截的

6.2.使用Interceptor

spring-mvc.xml

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="me.dddz.intercepter.Intercepter1"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="me.dddz.intercepter.Intercepter2"/>
    </mvc:interceptor>
</mvc:interceptors>

多个interceptor按顺序执行,其内部运行与filter一样

public class Intercepter1 implements HandlerInterceptor {
    @Override
    //目标方法执行之前
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle");
        String test = request.getParameter("test");

        if("yes".equalsIgnoreCase(test)) {
            return true;
        } else {
            return false;
        }
        //true放行,false不放行
    }

    @Override
    //目标方法执行之后,视图返回之前
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        modelAndView.addObject("username", "覆盖了?");
        System.out.println("postHandle");
    }

    @Override
    //目标方法执行之后,视图返回之后
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion");
    }
}

6.3.Interceptro方法说明

方法名 说明
preHandle() 在请求处理之前进行调用,返回值是boolean类型,返回false:请求结束,返回ture:继续调用下一个Interceptor的preHandle方法
postHandle() 在当前请求进行处理preHandle返回ture之后被调用,是在DispatcherServlet进行视图返回渲染之前被调用,所以可以在此方法中对Controller处理之后的ModelAndView对象进行操作
afterCompletion() 在整个请求结束之后并且preHandle返回true,也就是DispatcherServlet渲染了对应的视图之后执行

七.SpringMVC异常处理

7.1.异常处理的思路

系统中异常包括两类:预期异常和运行时RunitmeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发等手段减少运行时异常的发生

系统的Dao、Service、Controller出现都通过throws Exception向上抛出,最后由SpringMVC前端控制器交给异常处理器进行异常处理

在这里插入图片描述

7.2.SpringMVC异常处理两种方式

7.2.1.简单异常处理器SimpleMappingExceptionResolver

spring-mvc.xml

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="defaultErrorView" value="error"/>
    <property name="exceptionMappings">
        <map>
            <entry key="java.lang.ClassNotFoundException" value="error"/>
            <!--key是异常类型,value是视图-->
        </map>
    </property>
</bean>

7.2.2.异常处理接口HandlerExceptionResolver

public class Exception1 implements HandlerExceptionResolver {
   @Override
   public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
       ModelAndView modelAndView = new ModelAndView();
       if (e instanceof ClassNotFoundException) {
           modelAndView.addObject("info", "类找不到");
       } else {
           modelAndView.addObject("info", "其他异常");
       }
       model
       return modelAndView;
   }
}

spring-mvc.xml

<bean class="me.dddz.exception.Exception1"/>

猜你喜欢

转载自blog.csdn.net/weixin_48568292/article/details/107774746