SpringMVC知识点记录

  • 1. SpringMVC简介
  • 2. 入门案例
  • 3. @RequestMapping注解
    • 3.1 @RequestMapping注解的功能
    • 3.2 @RequestMapping注解的位置
    • 3.3 @RequestMapping注解的value属性
    • 3.4 @RequestMapping注解的method属性
    • 3.5 @RequestMapping注解的params属性(了解)
    • 3.6 @RequestMapping注解的headers属性(了解)
    • 3.7 SpringMVC支持ant风格的路径
    • 3.8 SpringMVC支持路径中的占位符(重点)
  • 4. SpringMVC获取请求参数
    • 4.1 通过ServletAPI获取请求参数
    • 4.2 通过控制器方法的形参获取请求参数
    • 4.3 @RequestParam注解
    • 4.4 @RequestHeader注解 和 @CookieValue注解
    • 4.5 通过POJO获取请求参数
    • 4.6 解决获取请求参数的乱码问题
  • 5. 域对象共享数据
    • 5.1 使用ServletAPI想request域对象共享数据(不常用)
    • 5.2 使用ModelAndView向request域对象共享数据
    • 5.3 使用Model向request域对象共享数据
    • 5.4 使用ModelMap向request域对象共享数据
    • 5.5 使用map向request域对象共享数据
    • 5.6 Model、ModelMap、Map的关系
    • 5.7 向session域共享数据
    • 5.8 向application域共享数据
  • 6.SpringMVC的视图
    • 6.1 ThymeleafView
    • 6.2 转发视图 InternalResourceView
    • 6.3 重定向视图 RedirectView
    • 6.4 视图控制器 view-controller
  • 7. RESTful
    • 7.1 RESTful简介
    • 7.2 RESTful的实现
    • 7.3 HiddenHttpMethodFilter
  • 8. RESTful 案例
    • 8.1 准备工作
    • 8.2 功能清单
    • 8.3 具体功能:查询功能
      • 8.3.1 查询功能
      • 8.3.2 解决静态资源问题
    • 8.4 具体功能:添加功能
    • 8.5 具体功能:修改功能
    • 8.6具体功能:删除功能
  • 9. SpringMVC处理ajax请求
    • 9.1 @RequestBody
    • 9.2 @RequestBody获取json格式的请求
    • 9.3 @ResponseBody
    • 9.4 @ResponseBody响应浏览器json数据
    • 9.5 @RestController
  • 10. 文件下载和上传
    • 10.1 文件下载
    • 10.2 文件上传
  • 11. 拦截器
  • 12. 异常处理器
  • 13. 注解配置SpringMVC
  • 14. SpringMVC执行流程

1. SpringMVC简介


2. 入门案例

文件结构

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.atguigu</groupId><artifactId>spring_mvc_helloworld</artifactId><version>1.0-SNAPSHOT</version><!--打包方式为war--><packaging>war</packaging><dependencies><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.1</version></dependency><!-- 日志 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency><!-- ServletAPI --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- Spring5和Thymeleaf整合包 --><dependency><groupId>org.thymeleaf</groupId><artifactId>thymeleaf-spring5</artifactId><version>3.0.12.RELEASE</version></dependency></dependencies><properties><maven.compiler.source>19</maven.compiler.source><maven.compiler.target>19</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties></project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--配置SpringMVC的前端控制器,对浏览器发送的请求进行处理SpringMVC的配置文件的默认位置和名称:位置:WEB-INF下名称:<servlet-name>-servlet.xml,当前配置下的配置文件名为SpringMVC-servlet.xml--><servlet><servlet-name>SpringMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--设置SpringMVC配置文件的位置和名称--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:SpringMVC.xml</param-value></init-param><!--将DispatcherServlet的初始化时间提前到了服务器启动时--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>SpringMVC</servlet-name><!--url-pattern:/:匹配浏览器向服务器发送的所有请求,不包括.jsp/*:匹配浏览器向服务器发送的所有请求,包括.jsp--><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

SpringMVC配置文件

<?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="com.atguigu.controller"/><!-- 配置Thymeleaf视图解析器 --><bean id="viewResolver"class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!--/WEB-INF/templates/index.html--><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean>
</beans>

请求控制器类

package com.atguigu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class HelloController {//@RequestMapping注解:处理请求和控制器方法之间的映射关系//@RequestMapping注解的value属性可以通过请求地址匹配请求,/表示的当前工程的上下文路径@RequestMapping("/")public String protal(){//将逻辑视图返回return "index";}@RequestMapping("/hello")public String hello(){return "success";}
}

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h3>xixi</h3><a th:href="@{/hello}">测试SpringMVC</a>
</body>
</html>

sucess.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<h1>成功</h1>
</body>
</html>

3. @RequestMapping注解

3.1 @RequestMapping注解的功能

@RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来,建立映射关系。

3.2 @RequestMapping注解的位置

@RequestMapping注解标识的位置:
1、标识一个类:设置映射请求的请求路径的初始信息
2、标识一个方法:设置映射请求的请求路径的具体信息

/*** @RequestMapping注解标识的位置:* 1、标识一个类:设置映射请求的请求路径的初始信息* 2、标识一个方法:设置映射请求的请求路径的具体信息*/
@Controller
@RequestMapping("/test")
public class TestRequestMappingController {//此时控制器方法所匹配的请求的请求路径为/test/hello@RequestMapping("/hello")public String helloworld(){return "success";}
}

3.3 @RequestMapping注解的value属性

@RequestMapping注解values属性:
作用: 通过请求的请求路径匹配请求;
value属性是数组类型,即若当前浏览器所发送请求的请求路径匹配value属性中的任何一个值,则当前请求就会被注解所标识的方法进行处理。

/*** @RequestMapping注解values属性:* 作用:通过请求的请求路径匹配请求;* value属性是数组类型,即若当前浏览器所发送请求的请求路径匹配value属性中的任何一个值,则当前请求就会被注解所标识的方法进行处理。*/
@Controller
@RequestMapping("/test")
public class TestRequestMappingController {//此时控制器方法所匹配的请求的请求路径为/test/hello或者/test/abc@RequestMapping({"/hello","/abc"})public String helloworld(){return "success";}
}

3.4 @RequestMapping注解的method属性

@RequestMapping注解的method属性
作用: 通过请求的请求方式匹配请求;
method属性时RequestMethod类型的数组,即若当前浏览器所发送请求的请求方式匹配method属性中的任何一种请求方式,则前请求就会被注解所标识的方法进行处理。

常见的异常报错
若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求方式不匹配,则此时页面报错405
注意:
除了表单提交、Ajax请求等是post请求之外,基本都是get请求

/*** @RequestMapping注解的method属性* 作用:通过请求的请求方式匹配请求;* method属性时RequestMethod类型的数组,即若当前浏览器所发送请求的请求方式匹配method属性中的任何一种请求方式,则前请求就会被注解所标识的方法进行处理。* 若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求方式不匹配,则此时页面报错405*/
@Controller
@RequestMapping("/test")
public class TestRequestMappingController {//此时控制器方法所匹配的请求的请求路径为/test/hello或者/test/abc@RequestMapping(value = {"/hello","/abc"},method = RequestMethod.POST)public String helloworld(){return "success";}
}

在@RequestMapping的基础上,结合请求方式的一些派生注解:
@GetMapping、@PostMapping、@DeleteMapping、@PutMapping

3.5 @RequestMapping注解的params属性(了解)

/*** @RequestMapping注解的params属性:* 作用:通过请求的请求参数匹配请求,即浏览器发送的请求的请求参数必须满足params属性的设置;** params可以使用四种表达式:*  "param":当前请求的请求参数中必须携带param参数;*  "!param":当前请求的请求参数中不能携带param参数;*  "param=value":当前请求的请求参数中必须携带param参数,且值为value;*  "param!=value":当前请求的请求参数中可以不携带param参数,如果携带了param参数,必须不能等于value。(简言之,不能接待value的param参数);**  参数不符合时,报错:400-Parameter conditions "username" not met for actual request parameters:*/@Controller
@RequestMapping("/test")
public class TestRequestMappingController {//此时控制器方法所匹配的请求的请求路径为/test/hello或者/test/abc@RequestMapping(value = {"/hello", "/abc"}, method = {RequestMethod.POST, RequestMethod.GET},params ={"username","!password","age=20","sex=女"})public String helloworld() {return "success";}
}

3.6 @RequestMapping注解的headers属性(了解)

/*** @RequestMapping注解的headers属性:*  "header":要求请求映射所匹配的请求必须携带header请求头信息*  "!header":要求请求映射所匹配的请求必须不能携带header请求头信息*  "header=value":要求请求映射所匹配的请求必须携带header请求头信息且header=value*  "header!=value":要求请求映射所匹配的请求必须携带header请求头信息且header!=value**  headers = {"referer"} 请求头中必须含有referer属性,代表着必须有来源页面,代表着不能靠手动输入地址来访问二级以下的页面;**  注意:若浏览器所发送的请求的请求路径和@RequestMapping注解value属性匹配,但是请求头不匹配,则报错404*/
@Controller
@RequestMapping("/test")
public class TestRequestMappingController {//此时控制器方法所匹配的请求的请求路径为/test/hello或者/test/abc@RequestMapping(value = {"/hello", "/abc"},method = {RequestMethod.POST, RequestMethod.GET},headers = {"referer"})public String helloworld() {return "success";}
}

3.7 SpringMVC支持ant风格的路径

?:表示任意的单个字符
*:表示任意的0个或多个字符
**:表示任意层数的任意目录
注意:在使用时,只能使用//xxx的方式

    // a?a :a和a的中间可以表示任意一个字符,例如/test/aba/ant。但是注意有些特殊字符(?)除外。//@RequestMapping("/a?a/ant")// a*a :a和a的中间可以表示任意一个字符,例如/test/abba/ant。但是注意有些特殊字符(?和/)除外。//@RequestMapping("/a*a/ant")// 代表多层目录 例如:/test/abba/abba/ant@RequestMapping("/**/ant")public String testAnt(){return "success";}

3.8 SpringMVC支持路径中的占位符(重点)

 /*** SpringMVC使用路径中的占位符* 传统方式:/deleteUser?id=1* rest方式:/user/delete/1* 需要在@RequestMapping注解的value属性中所设置的路径中,使用{xxx}的方式表示路径中的数据,* 再通过@PathVariable注解,将占位符所标识的值和控制器方法的形参进行绑定*/@RequestMapping("/rest/{id}/{username}")public String testRest(@PathVariable("id") Integer id,@PathVariable("username") String username){System.out.println("id="+id+";username="+username);//最终输出结果:id=1;username=adminreturn "success";}

4. SpringMVC获取请求参数

4.1 通过ServletAPI获取请求参数

    /*** 1、通过ServletAPI获取请求参数* 只需要在控制器方法的形参位置设置HttpServletRequest类型的形参,就可以在控制器方法中使用request对象获取请求参数。* @param request* @return*/@RequestMapping("/param/servletAPI")public String getParamByServletAPI(HttpServletRequest request){String username = request.getParameter("username");String password = request.getParameter("password");System.out.println("username="+username+";password="+password);//输出结果:username=admin;password=123return "success";}

4.2 通过控制器方法的形参获取请求参数

    /*** 2、通过控制器方法的形参获取* 只需要在控制器方法的形参位置设置一个形参,形参的名字要和请求参数的名字一致即可。* @param username* @param password* @return*///通过控制器方法的形参获取请求参数@RequestMapping("/param1")public String getParam1(String username,String password){System.out.println("username="+username+";password="+password);//输出结果:username=admin;password=123return "success";}

4.3 @RequestParam注解

    /*** 3、@RequestParam注解* 通过控制器方法的形参获取请求参数,并且使用@RequestParam注解解决形参和前端请求参数名字不一致的情况* @RequestParam注解:将请求参数和控制器方法的形参进行绑定;* 三个属性:*  value = "userName" :设置和形参绑定的请求参数的名字;*  required = false :设置是否必须传输value所对应的请求参数,默认值为true;*      注意:若设置了required = true,而没有传输则会报错 400;*  defaultValue = "User1" :设置当没有传输value所对应的请求参数时,为形参设置默认值,前提是需要设置required = false;**/@RequestMapping("/param2")public String getParam2(@RequestParam(value = "userName") String username, @RequestParam("passWord") String password){System.out.println("username="+username+";password="+password);//输出结果:username=admin;password=123return "success";}

4.4 @RequestHeader注解 和 @CookieValue注解

@RequestHeader是将请求头信息和控制器方法的形参创建映射关系
@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

@CookieValue是将cookie数据和控制器方法的形参创建映射关系
@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam

    /*** 3、@RequestParam注解* 通过控制器方法的形参获取请求参数,并且使用@RequestParam注解解决形参和前端请求参数名字不一致的情况* @RequestParam注解:将请求参数和控制器方法的形参进行绑定;* 三个属性:*  value = "userName" :设置和形参绑定的请求参数的名字;*  required = false :设置是否必须传输value所对应的请求参数,默认值为true;*      注意:若设置了required = true,而没有传输则会报错 400;*  defaultValue = "User1" :设置当没有传输value所对应的请求参数时,为形参设置默认值,前提是需要设置required = false;* 4、@RequestHeader注解:将请求头信息和控制器方法的形参绑定* 5、@CookieValue注解:将cookie数据和控制器方法的形参绑定*/@RequestMapping("/param2")public String getParam2(@RequestParam(value = "userName") String username,@RequestParam("passWord") String password,@RequestHeader("referer") String referer,@CookieValue("JSESSIONID") String jsessionId){System.out.println("username="+username+";password="+password);//输出结果:username=admin;password=123System.out.println("referer="+referer);//输出结果:referer=http://localhost:8080/spring_mvc_demo_war_exploded/System.out.println("cookie="+jsessionId);//输出结果:cookie=61A430AE2B0EC2959F2C0C0B3825A8B5return "success";}

4.5 通过POJO获取请求参数

    /*** 通过控制器方法的实体类型的形参获取请求参数:* 需要在控制器方法的形参位置设置实体类类型的形参,要保证实体类中的属性的属性名和请求参数的名字一致,可以通过实体类类型的形参获取请求参数。* @param user* @return*/@RequestMapping("param/pojo")public String getParamByPojo(User user){System.out.println(user); //输出结果:User{id=null, username='admin', password='123'}return "success";}

4.6 解决获取请求参数的乱码问题

tomcat8以后get请求不需要解决乱码问题,post请求需要自己来解决;

web.xml中加入配置(SpringMVC中处理编码的过滤器一定要配置到其他过滤器之前,否则无效)

    <!--配置Spring的编码过滤器--><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>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>


5. 域对象共享数据

5.1 使用ServletAPI想request域对象共享数据(不常用)

@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request){request.setAttribute("testScope", "hello,servletAPI");return "success";
}

5.2 使用ModelAndView向request域对象共享数据

    /*** 向域对象共享数据:* 1、通过ModelAndView向请求域共享数据*  使用ModelAndView时,可以使用其Model功能向请求域共享数据*  使用View功能设置逻辑视图,但是控制器方法一定要将ModelAndView作为方法的返回值* @return*/@RequestMapping("/test/mav")public ModelAndView testMAV(){/*** ModelAndView包含Model和View的功能:* Model:向请求域中共享数据;* View:设置逻辑视图实现页面跳转;*/ModelAndView mav = new ModelAndView();//向请求域中共享数据mav.addObject("testRequestScope", "hello,ModelAndView");//设置逻辑视图mav.setViewName("success");return mav;}

success.html

<p th:text="${testRequestScope}"></p>

运行结果

5.3 使用Model向request域对象共享数据

    /*** 使用Model向请求域中共享数据* @param model* @return*/@RequestMapping("/test/model")public String testModel(Model model){model.addAttribute("testRequestScope","hello,Model");return "success";}

运行结果

5.4 使用ModelMap向request域对象共享数据

    /*** 使用ModelMap向请求域中共享数据* @param modelMap* @return*/@RequestMapping("/test/modelMap")public String testModelMap(ModelMap modelMap){modelMap.addAttribute("testRequestScope","hello,ModelMap");return "success";}

运行结果

5.5 使用map向request域对象共享数据

    /*** 使用Map向请求域中共享数据* @param map* @return*/@RequestMapping("/test/map")public String testMap(Map<String,Object> map){map.put("testRequestScope","hello,Map");return "success";}

运行结果

5.6 Model、ModelMap、Map的关系

Model、ModelMap、Map类型的参数其实本质上都是 BindingAwareModelMap 类型的

public interface Model{}
public class ModelMap extends LinkedHashMap<String, Object> {}
public class ExtendedModelMap extends ModelMap implements Model {}
public class BindingAwareModelMap extends ExtendedModelMap {}

5.7 向session域共享数据

    /*** 向session域共享数据* @param session* @return*/@RequestMapping("/test/session")public String testSession(HttpSession session){session.setAttribute("testSessionScope","hello,session");return "success";}

success.html

<p th:text="${session.testSessionScope}"></p><br>

运行结果

5.8 向application域共享数据

    /*** 向application域共享数据* @param session* @return*/@RequestMapping("/test/application")public String testApplication(HttpSession session){ServletContext servletContext = session.getServletContext();servletContext.setAttribute("testApplicationScope","hello,application");return "success";}

success.html

<p th:text="${application.testApplicationScope}"></p><br>

运行结果


6.SpringMVC的视图

6.1 ThymeleafView

当控制器方法中所设置的视图名称没有任何前缀时,此时的视图名称会被SpringMVC配置文件中所配置
的视图解析器解析,视图名称拼接视图前缀和视图

后缀所得到的最终路径,会通过转发的方式实现跳转

    @RequestMapping("/test/view/thymeleaf")public String testThymeleafView(){return "success";}

6.2 转发视图 InternalResourceView

    /*** 转发视图:InternalResourceView* @return*/@RequestMapping("/test/view/forward")public String testInternalResourceView(){return "forward:/test/model";}

运行结果

6.3 重定向视图 RedirectView

    /*** 重定向视图:RedirectView* @return*/@RequestMapping("/test/view/redirect")public String testRedirectView(){return "redirect:/test/model";}

运行结果

6.4 视图控制器 view-controller

当控制器方法中,仅仅用来实现页面跳转,即只需要设置视图名称时,可以将处理器方法使用view-controller标签进行表示

SpringMVC.xml

    <!--开启mvc的注解驱动--><mvc:annotation-driven></mvc:annotation-driven><!--视图控制器:为当前的请求直接设置视图名称实现页面跳转若设置视图控制器,则只有视图控制器所设置的请求会被处理,其他的请求将全部404,此时必须再配置一个标签来开启mvc的注解驱动(<mvc:annotation-driven></mvc:annotation-driven>)--><mvc:view-controller path="/" view-name="index"></mvc:view-controller>

7. RESTful

7.1 RESTful简介

RESTRepresentational State Transfer,表现层资源状态转移

7.2 RESTful的实现

GET 用来获取资源;
POST 用来新建资源;
PUT 用来更新资源;
DELETE用来删除资源;

REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数。
而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。

操作 传统方式 REST风格
查询操作 getUserById?id=1 user/1 (get请求方式)
保存操作 saveUser user (post请求方式)
删除操作 deleteUser?id=1 user/1 (delete请求方式)
更新操作 updateUser user (put请求方式)

查询操作

    /*** 查询所有用户信息* @return*/@RequestMapping(value = "/user",method = RequestMethod.GET)public String getAllUser(){System.out.println("查询所有用户信息 --> /user --> get");return "success";}/*** 根据id查询用户信息* @param id* @return*/@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)public String getUserById(@PathVariable("id") Integer id){System.out.println("根据id查询用户信息 --> /user/"+id+" --> get");return "success";}

添加操作

    /*** 添加用户信息* @return*/@RequestMapping(value = "/user",method = RequestMethod.POST)public String insertUser(){System.out.println("添加用户信息--> /user --> post请求");return "success";}

7.3 HiddenHttpMethodFilter

修改操作和删除操作

    /*** 修改用户信息* 注意:浏览器目前只能发送get和post请求,若要发送put和delete请求,需要在web.xml中配置一个过滤器HiddenHttpMethodFilter* 配置了过滤器之后,发送的请求需要满足两个条件,才能将请求方式转换为put和delete*  1、当前请求的请求方式必须为post*  2、当前请求必须传送请求参数_method,_method的值才是最终的请求方式* @return*/@RequestMapping(value = "/user",method = RequestMethod.PUT)public String updatetUser(){System.out.println("修改用户信息--> /user --> put请求");return "success";}/*** 删除用户信息* @param id* @return*/@RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)public String deleteUser(@PathVariable("id") Integer id){System.out.println("删除用户信息--> /user/"+id+" --> delete请求");return "success";}

web.xml中设置处理请求方式的过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--配置Spring的编码过滤器--><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>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--设置处理请求方式的过滤器--><filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--设置SpringMVC的前端控制器--><servlet><servlet-name>SpringMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:SpringMVC.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>SpringMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

index.html中设置请求方式

<form th:action="@{/user}" method="post"><input type="hidden" name="_method" value="put"><input type="submit" value="修改用户信息">
</form>
<form th:action="@{/user/5}" method="post"><input type="hidden" name="_method" value="delete"><input type="submit" value="删除用户信息">
</form>

8. RESTful 案例

8.1 准备工作

实体类

package com.atguigu.pojo;public class Employee {private Integer id;private String lastName;private String email;//1 male, 0 femaleprivate Integer gender;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public Integer getGender() {return gender;}public void setGender(Integer gender) {this.gender = gender;}public Employee(Integer id, String lastName, String email, Integergender) {super();this.id = id;this.lastName = lastName;this.email = email;this.gender = gender;}public Employee() {}}

DAO

package com.atguigu.dao;import com.atguigu.pojo.Employee;
import org.springframework.stereotype.Repository;import java.util.Collection;
import java.util.HashMap;
import java.util.Map;@Repository
public class EmployeeDao {private static Map<Integer, Employee> employees = null;static{employees = new HashMap<Integer, Employee>();employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1));}private static Integer initId = 1006;public void save(Employee employee){if(employee.getId() == null){employee.setId(initId++);}employees.put(employee.getId(), employee);}public Collection<Employee> getAll(){return employees.values();}public Employee get(Integer id){return employees.get(id);}public void delete(Integer id){employees.remove(id);}
}

控制类 EmployeeController.java

package com.atguigu.controller;import org.springframework.stereotype.Controller;@Controller
public class EmployeeController {@Autowiredprivate EmployeeDao employeeDao;
}

8.2 功能清单

功能 URL地址 请求方式
访问首页 / GET
查询全部数据 /employee GET
删除 /employee/2 DELETE
跳转到添加数据页面 /toAdd GET
执行保存 /employee POST
跳转到更新数据页面 /employee/2 GET
执行更新 /employee PUT

8.3 具体功能:查询功能

8.3.1 查询功能

控制类 EmployeeController.java

    /*** 查询所有的员工信息* @param model* @return*/@RequestMapping(value = "/employee",method = RequestMethod.GET)public String getAllEmployee(Model model){//获取所有的员工信息Collection<Employee> employees = employeeDao.getAll();//将所有的员工信息在请求域中共享model.addAttribute("employees",employees);//跳转到列表页面return "employee_list";}

employee_list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>employee_list</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<table><tr><th colspan="5">employee list</th></tr><tr><td>id</td><td>lastName</td><td>email</td><td>gender</td><td>options(<a th:href="@{/to/add}">add</a> )</td></tr><tr th:each="employee : ${employees}"><td th:text="${employee.id}"></td><td th:text="${employee.lastName}"></td><td th:text="${employee.email}"></td><td th:text="${employee.gender}"></td><td><a href="">delete</a><a href="">update</a></td></tr>
</table>
</body>
</html>

运行结果

8.3.2 解决静态资源问题

在SpringMVC.xml中配置DefaultServlet来处理静态资源

<mvc:default-servlet-handler></mvc:default-servlet-handler>

SpringMVC.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="com.atguigu"/><!-- 配置Thymeleaf视图解析器 --><bean id="viewResolver"class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!--/WEB-INF/templates/index.html--><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--配置默认的servlet处理静态资源当前工程的web.xml配置的前端控制器DispatcherServlet的<url-pattern>/</url-pattern>是斜线tomcat的web.xml配置的默认的DefaultServlet的<url-pattern>/</url-pattern>也是斜线此时,浏览器发送的请求冲突了,会优先被DispatcherServlet进行处理,但是DispatcherServlet无法处理静态资源若配置了<mvc:default-servlet-handler></mvc:default-servlet-handler>,此时浏览器发送的所有请求都会被DefaultServlet来处理。若配置了<mvc:default-servlet-handler></mvc:default-servlet-handler>和<mvc:annotation-driven></mvc:annotation-driven>,则浏览器发送的请求会先被DispatcherServlet来处理,无法处理再交给DefaultServlet来处理。--><mvc:default-servlet-handler></mvc:default-servlet-handler><!--开启mvc的注解驱动--><mvc:annotation-driven></mvc:annotation-driven><!--视图控制器:为当前的请求直接设置视图名称实现页面跳转若设置视图控制器,则只有视图控制器所设置的请求会被处理,其他的请求将全部404,此时必须再配置一个标签来开启mvc的注解驱动(<mvc:annotation-driven></mvc:annotation-driven>)--><mvc:view-controller path="/" view-name="index"></mvc:view-controller>
</beans>

8.4 具体功能:添加功能

SpringMVC.xml

视图控制器中添加视图
<mvc:view-controller path="/to/add" view-name="employee_add"></mvc:view-controller>

<?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="com.atguigu"/><!-- 配置Thymeleaf视图解析器 --><bean id="viewResolver"class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="UTF-8"/><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!--/WEB-INF/templates/index.html--><!-- 视图前缀 --><property name="prefix" value="/WEB-INF/templates/"/><!-- 视图后缀 --><property name="suffix" value=".html"/><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--配置默认的servlet处理静态资源当前工程的web.xml配置的前端控制器DispatcherServlet的<url-pattern>/</url-pattern>是斜线tomcat的web.xml配置的默认的DefaultServlet的<url-pattern>/</url-pattern>也是斜线此时,浏览器发送的请求冲突了,会优先被DispatcherServlet进行处理,但是DispatcherServlet无法处理静态资源若配置了<mvc:default-servlet-handler></mvc:default-servlet-handler>,此时浏览器发送的所有请求都会被DefaultServlet来处理。若配置了<mvc:default-servlet-handler></mvc:default-servlet-handler>和<mvc:annotation-driven></mvc:annotation-driven>,则浏览器发送的请求会先被DispatcherServlet来处理,无法处理再交给DefaultServlet来处理。--><mvc:default-servlet-handler></mvc:default-servlet-handler><!--开启mvc的注解驱动--><mvc:annotation-driven></mvc:annotation-driven><!--视图控制器:为当前的请求直接设置视图名称实现页面跳转若设置视图控制器,则只有视图控制器所设置的请求会被处理,其他的请求将全部404,此时必须再配置一个标签来开启mvc的注解驱动(<mvc:annotation-driven></mvc:annotation-driven>)--><mvc:view-controller path="/" view-name="index"></mvc:view-controller><mvc:view-controller path="/to/add" view-name="employee_add"></mvc:view-controller>
</beans>

employee_add.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<form th:action="@{/employee}" method="post"><table><tr><th colspan="2">add employee</th></tr><tr><td>lastName</td><td><input type="text" name="lastName"></td></tr><tr><td>email</td><td><input type="text" name="email"></td></tr><tr><td>gender</td><td><input type="radio" name="gender" value="1">male<input type="radio" name="gender" value="0">female</td></tr><tr><td colspan="2"><input type="submit" value="add"></td></tr></table>
</form>
</body>
</html>

控制器类 EmployeeController.java

    /*** 添加员工信息* @param employee* @return*/@RequestMapping(value = "/employee",method = RequestMethod.POST)public String addEmployee(Employee employee){//保存员工信息employeeDao.save(employee);//重定向到列表功能 /employeereturn "redirect:/employee";}

运行结果

8.5 具体功能:修改功能

先跳转到修改页面,然后再修改页面用PUT请求提交修改

跳转超链接

            <!--拼接符号--><!--<a th:href="@{'/employee/'+${employee.id}}">update</a>--><!--管道符号--><a th:href="@{|/employee/${employee.id}|}">update</a>

employee_update.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>employee_update</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<form th:action="@{/employee}" method="post"><input type="hidden" name="_method" value="put"><input type="hidden" name="id" th:value="${employee.id}"><table><tr><th colspan="2">update employee</th></tr><tr><td>lastName</td><td><input type="text" name="lastName" th:value="${employee.lastName}"></td></tr><tr><td>email</td><td><input type="text" name="email" th:value="${employee.email}"></td></tr><tr><td>gender</td><td><input type="radio" name="gender" value="1" th:field="${employee.gender}">male<input type="radio" name="gender" value="0" th:field="${employee.gender}">female</td></tr><tr><td colspan="2"><input type="submit" value="update"></td></tr></table>
</form>
</body>
</html>

控制类 EmployeeController.java

    /*** 跳转到修改员工信息页面* @param id* @param model* @return*/@RequestMapping(value = "/employee/{id}",method = RequestMethod.GET)public String toUpdate(@PathVariable("id") Integer id,Model model){//根据id来查询员工信息Employee employee = employeeDao.get(id);//将员工信息共享到请求域中model.addAttribute("employee",employee);//跳转到employee_update.htmlreturn "employee_update";}/*** 修改员工信息* @param employee* @return*/@RequestMapping(value = "/employee",method = RequestMethod.PUT)public String updateEmployee(Employee employee){//修改员工信息employeeDao.save(employee);//重定向到列表功能 /employeereturn "redirect:/employee";}

运行结果

8.6具体功能:删除功能

employee_list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<div id="app"><table><tr><th colspan="5">employee list</th></tr><tr><td>id</td><td>lastName</td><td>email</td><td>gender</td><td>options(<a th:href="@{/to/add}">add</a> )</td></tr><tr th:each="employee : ${employees}"><td th:text="${employee.id}"></td><td th:text="${employee.lastName}"></td><td th:text="${employee.email}"></td><td th:text="${employee.gender}"></td><td><a @click="deleteEmployee()" th:href="@{|/employee/${employee.id}|}">delete</a><!--拼接符号--><!--<a th:href="@{'/employee/'+${employee.id}}">update</a>--><!--管道符号--><a th:href="@{|/employee/${employee.id}|}">update</a></td></tr></table>
</div>
<form action="" method="post"><input type="hidden" name="_method" value="delete">
</form>
<!--引入vue.js-->
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">var vue = new Vue({el:"#app",methods:{deleteEmployee(){// 获取form表单var form = document.getElementsByTagName("form")[0];// 将超链接的ref属性值赋值给form表单的action属性//event.target 表示当前触发事件的标签form.action = event.target.href;// 表单提交form.submit();// 阻止超链接的默认行为(阻止超链接跳转到href的地址)event.preventDefault();}}})
</script>
</body>
</html>

控制类 EmployeeController.java

    /*** 删除员工信息* @param id* @return*/@RequestMapping(value = "/employee/{id}",method = RequestMethod.DELETE)public String deleteEmployee(@PathVariable("id") Integer id){//删除员工信息employeeDao.delete(id);//重定向到列表功能 /employeereturn "redirect:/employee";}

运行结果


9. SpringMVC处理ajax请求

9.1 @RequestBody

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>index.html</title>
</head>
<body>
<div id="app"><h1>index.html</h1> <br><input type="button" value="测试SpringMVC处理ajax" @click="testAjax()"><br>
</div>
<script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script>
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">/*** axios中文网:axios-js.com/zh-cn* axios格式:* axios({*     url:"", //请求路径*     method:"",  //请求方式*     params:{},  //请求参数(1、以name=value&name=value的方式发送请求参数;2、不管使用的请求方式是get或post,请求参数都会被拼接到请求地址中;3、此种方式的请求参数可以通过request.getParameter()获取)*     data:{}  //请求参数(1、是以json格式发送请求参数;2、请求参数会被保存到请求报文的请求体传输到服务器;3、此种方式的请求参数不可以通过request.getParameter()获取)* }).then(response=>{*     console.log(response.data);* });*/var vue = new Vue({el:"#app",methods:{testAjax(){axios.post("/spring_mvc_ajax_war_exploded/test/ajax?id=1001",{username:"admin",password:"123456"}).then(response=>{console.log(response.data);})}}})
</script>
</body>
</html>

控制类 TestAjaxController.java

    /*** 1、@RequestBody:将请求体中的内容和控制器方法的形参进行绑定;* @param id* @param requestBody* @param response* @throws IOException*/@RequestMapping("/test/ajax")public void testAjax(Integer id, @RequestBody String requestBody, HttpServletResponse response) throws IOException {System.out.println("id:"+id); //输出结果:id:1001System.out.println("requestBody:"+requestBody); //输出结果:requestBody:{"username":"admin","password":"123456"}response.getWriter().write("hello,axios");}

9.2 @RequestBody获取json格式的请求

pom.xml

        <!--导入jackson依赖--><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.1</version></dependency>

SpringMVC.xml

    <!--开启mvc的注解驱动--><mvc:annotation-driven></mvc:annotation-driven>

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>index.html</title>
</head>
<body>
<div id="app"><h1>index.html</h1> <br><input type="button" value="测试@RequestBody处理json格式的请求参数" @click="testRequestBody()"><br>
</div>
<script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script>
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">var vue = new Vue({el:"#app",methods:{testRequestBody(){axios.post("/spring_mvc_ajax_war_exploded/test/RequestBody/json",{username:"admin",password: "123456",age:23,gender:"男" }).then(response=>{console.log(response.data);})}}})
</script>
</body>
</html>

控制类 TestAjaxController.java

    /*** 2、使用@RequestBody注解将json格式的请求参数转换为java对象(有实体类的)*  (1)导入jackson的依赖*  (2)在SpringMVC的配置文件中设置<mvc:annotation-driven></mvc:annotation-driven>;*  (3)在处理请求的控制器方法的形参位置,直接设置json格式的请求参数要转换的java类型的形参,使用@RequestBody注解标识;* @param user* @param response* @throws IOException*/@RequestMapping("/test/RequestBody/json")public void testRequestBody(@RequestBody User user, HttpServletResponse response) throws IOException {System.out.println("user:"+user); //输出结果:user:User{id=null, username='admin', password='123456', age=23, gender='男'}response.getWriter().write("hello,RequestBody");}
    /*** 2、使用@RequestBody注解将json格式的请求参数转换为java对象(如果没有实体类用map集合)* @param map* @param response* @throws IOException*/@RequestMapping("/test/RequestBody/json")public void testRequestBody(@RequestBody Map<String,Object> map,HttpServletResponse response) throws IOException {System.out.println(map); //输出结果:{username=admin, password=123456, age=23, gender=男}response.getWriter().write("hello,RequestBody");}

9.3 @ResponseBody

index.html

    <a th:href="@{/test/ResponseBody}">测试@ResponseBody注解响应浏览器数据</a><br>

控制类 TestAjaxController.java

    /*** 3、@ResponseBody:将所标识的控制器方法的返回值作为响应报文的响应体响应到浏览器* @return*/@RequestMapping("/test/ResponseBody")@ResponseBodypublic String testResponseBody(){return "success";}

9.4 @ResponseBody响应浏览器json数据

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>index.html</title>
</head>
<body>
<div id="app"><h1>index.html</h1> <br><input type="button" value="测试@ResponseBody响应json格式的数据(实体类)" @click="testResponseBodyUser()"><br><input type="button" value="测试@ResponseBody响应json格式的数据(map集合)" @click="testResponseBodyMap()"><br><input type="button" value="测试@ResponseBody响应json格式的数据(list集合)" @click="testResponseBodyList()"><br>
</div>
<script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script>
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">var vue = new Vue({el:"#app",methods:{testResponseBodyUser(){axios.post("/spring_mvc_ajax_war_exploded/test/ResponseBody/json1").then(response=>{console.log(response.data);})},testResponseBodyMap(){axios.post("/spring_mvc_ajax_war_exploded/test/ResponseBody/json2").then(response=>{console.log(response.data);})},testResponseBodyList(){axios.post("/spring_mvc_ajax_war_exploded/test/ResponseBody/json3").then(response=>{console.log(response.data);})}}})
</script>
</body>
</html>

控制类 TestAjaxController.java

/*** 常用的java对象转换为json的结果:* 实体类 --> json对象* map --> json对象* list --> json数组*//*** 4、使用@ResponseBody注解响应浏览器json格式的数据(实体类)*  (1)导入jackson的依赖*  (2)在SpringMVC的配置文件中设置<mvc:annotation-driven></mvc:annotation-driven>;*  (3)将需要转换为json字符串的java对象直接作为控制器方法的返回值,再使用@ResponseBody注解标识控制器方法,就可以将java对象直接转换为json字符串,并响应到浏览器;* @return*/@RequestMapping("/test/ResponseBody/json1")@ResponseBodypublic User testResponseBodyJson1(){User user = new User(1001,"admin","123456",20,"男");return user;}/*** 4、使用@ResponseBody注解响应浏览器json格式的数据(Map集合)* @return*/@RequestMapping("/test/ResponseBody/json2")@ResponseBodypublic Map<String,Object> testResponseBodyJson2(){User user1 = new User(1001, "admin1", "123456", 20, "男");User user2 = new User(1002, "admin2", "123456", 21, "男");User user3 = new User(1003, "admin3", "123456", 22, "男");Map<String,Object> map = new HashMap<>();map.put("1001",user1);map.put("1002",user2);map.put("1003",user3);return map;}/*** 4、使用@ResponseBody注解响应浏览器json格式的数据(List集合)* @return*/@RequestMapping("/test/ResponseBody/json3")@ResponseBodypublic List<User> testResponseBodyJson3(){User user1 = new User(1001, "admin1", "123456", 20, "男");User user2 = new User(1002, "admin2", "123456", 21, "男");User user3 = new User(1003, "admin3", "123456", 22, "男");List<User> userList = Arrays.asList(user1, user2, user3);return userList;}

运行结果

9.5 @RestController

//@RestController = @Controller + @ResponseBody ; 相当于为类添加了@Controller注解,为类中的每个方法添加了@ResponseBody注解;
@RestController
public class TestAjaxController {}

10. 文件下载和上传

10.1 文件下载

index.html

    <a th:href="@{/test/down}">下载图片</a>

控制类 FileUpAndDownController.java

/*** SpringMVC实现下载功能* ResponseEntity:可以作为控制器方法的返回值,表示响应到浏览器的完整的响应报文** @param session* @return* @throws IOException*/@RequestMapping("/test/down")public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throwsIOException {//获取ServletContext对象ServletContext servletContext = session.getServletContext();//获取服务器中文件的真实路径String realPath = servletContext.getRealPath("/img/1.jpg");//创建输入流InputStream is = new FileInputStream(realPath);//创建字节数组  is.available()获取输入流所对应的文件的字节数byte[] bytes = new byte[is.available()];//将流读到字节数组中is.read(bytes);//创建HttpHeaders对象设置响应头信息MultiValueMap<String, String> headers = new HttpHeaders();//设置要下载方式以及下载文件的名字headers.add("Content-Disposition", "attachment;filename=1.jpg");//设置响应状态码HttpStatus statusCode = HttpStatus.OK;//创建ResponseEntity对象ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers,statusCode);//关闭输入流is.close();return responseEntity;}

10.2 文件上传

依赖

        <!--https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency>

SpringMVC配置

    <!--配置文件上传解析器--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

index.html

    <!--文件上传的要求1、form表单的请求方式必须为post;2、form表单必须设置属性enctype="multipart/form-data"--><form th:action="@{/test/up}" method="post" enctype="multipart/form-data">头像:<input type="file" name="photo" value="选择文件"><br><input type="submit" value="上传"></form>

控制类 FileUpAndDownController.java

/*** SpringMVC实现文件上传功能** @param photo* @param session* @return* @throws IOException*/@RequestMapping("/test/up")public String testUp(MultipartFile photo, HttpSession session) throws IOException {//获取上传文件的文件名String filename = photo.getOriginalFilename();//获取上传的文件的后缀名String hzName = filename.substring(filename.lastIndexOf("."));//获取UUIDString uuid = UUID.randomUUID().toString();//拼接一个新的文件名filename = uuid + hzName;//获取ServletContext对象ServletContext servletContext = session.getServletContext();//获取当前工程下photo目录的真实路径String photoPath = servletContext.getRealPath("photo");//创建photoPath所对应的File对象File file = new File(photoPath);//判断file所对应目录是否存在if (!file.exists()) {//如果不存在,直接创建file.mkdir();}String finalPath = photoPath + File.separator + filename;System.out.println(finalPath); // 输出结果为:D:\SSM\SSM\spring_mvc_ajax\target\spring_mvc_ajax-1.0-SNAPSHOT\photo\touxiang1.jpg//上传文件photo.transferTo(new File(finalPath));return "success";}

11. 拦截器


12. 异常处理器


13. 注解配置SpringMVC


14. SpringMVC执行流程


SpringMVC知识点记录相关推荐

  1. javaweb基础知识点记录2

    javaweb基础知识点记录 1.在service方法中,首先获得请求的方法名,然后根据方法名调用对应的doXXXX方法,比如说请求参数为GET,那么就会去调用doGet方法,请求参数为POST,那么 ...

  2. javaweb基础知识点记录1

    javaweb基础知识点记录 1.当我们通过在浏览器的输入栏中直接输入网址的方式访问网页的时候,浏览器采用的就是GET方法向服务器获取资源. 2.我们可以将Servlet看做是嵌套了HTML代码的ja ...

  3. 毕业论文知识点记录(四)——MaxEnt模型

    毕业论文知识点记录(四)--MaxEnt模型 0 序言 经过了几次文章分享,数据已经准备得差不多了,师姐说可以先利用现有数据跑一个结果,然后再逐步增加想要的环境数据,改善结果. 另外,谨记师姐的一句话 ...

  4. 毕业论文知识点记录(六)——基于R语言优化maxent模型

    毕业论文知识点记录(六)--基于R语言优化maxent模型 第一步:R安装 这个网上都有很多详细的步骤,就不再详细介绍了. 第二步:R安装包 因为优化maxent模型需要用到kuenm程序包,但是官网 ...

  5. 毕业论文知识点记录(三)——SPSS去相关

    毕业论文知识点记录(三)--SPSS去相关 #(一)数据下载 1.草地贪夜蛾的发生记录,这个数据在前面文章中有描述.草地贪夜蛾发生记录下载 2.气候数据 数据来源:worldclim 我选择的分辨率是 ...

  6. 油猴脚本——掘金Markdown格式适配器知识点记录【油猴脚本、Markdown、浏览器文件读取、tooltip、SVG、、模拟用户输入、aria-xxxx属性、剪切板操作、】

    油猴脚本--掘金Markdown格式适配器知识点记录 脚本更新日志 参考:掘金Markdown格式适配器更新日志 - 掘金 脚本地址: 更新:2021年9月3日19:57:35 参考:掘金Markdo ...

  7. C++教程从0到1入门编程中知识点记录!

    C++教程从0到1入门编程中知识点记录! 一.C语言 1.冒泡排序 示例代码: #include <iostream> using namespace std; int main() { ...

  8. 【算法笔记题解】《算法笔记知识点记录》第三章——入门模拟1——简单模拟

    如果喜欢大家还希望给个收藏点赞呀0.0 相关知识点大家没基础的还是要看一下的,链接: <算法笔记知识点记录>第三章--入门模拟 由于放原题的话文章实在太长,所以题多的话我只放思路和题解,大 ...

  9. 学习IPPS库的编码部分知识点记录

    学习IPPS库的编码部分知识点记录 1.哈夫曼编码 相关函数 IppStatus ippsDeflateHuff_8u(const Ipp8u *pLitSrc, const Ipp16u *pDis ...

最新文章

  1. 机器学习笔试题精选(五)
  2. Fedora12下安装NCTUns6.0
  3. SAP Cloud Platform上Destination属性为odata_gen的具体用途
  4. Linux系统编程---8(全局变量异步I/O,可重入函数)
  5. third day- 01--文件操作
  6. HTML的xmlns的作用
  7. php中获取上一页的url地址
  8. 智能视屏会议系统(19)---开源视频会议SIP协议栈
  9. undefined reference to `sqlite3_column_table_name‘
  10. 想知道CSDN积分怎么获取谢谢啦 需要下载文件
  11. PDF、图片、合并、转化工具
  12. 偏微分方程数值解的matlab 实现,偏微分方程数值解的Matlab 实现
  13. 生物信息学数据库导航
  14. 服务器没有显示器能接笔记本吗,笔记本能连显示器吗_笔记本能不能接显示器...
  15. centos mysql 5.2.3 编译安装_在CentOS上编译安装MySQL 5.7.13步骤详解
  16. 一名弱弱的程序猿立冬到星海湾大桥走了一天。。。
  17. 苹果系统和windows系统怎么切换_Windows体验苹果系统,Macbook你也可以拥有!
  18. Android Hawk数据库 github开源项目,字节跳动社招面试记录
  19. 各式 Web 前端開發工具整理
  20. 【新学期、新Flag】例文:我的新学期Flag

热门文章

  1. PHP中include与require的用法区别
  2. 《面试知识,工作可待:集合篇》-java集合面试知识大全
  3. C++头文件和源文件的编译过程
  4. lisp 图层字体式样替换_新建图层编辑字体颜色 ps替换字体颜色
  5. 【C语言】--编译及编译器
  6. Acrel-6000/B电气火灾监控系统麻城广场设计与应用
  7. 【电气设计】理论知识学习(持续更新中...)
  8. 技能干货:产品经理该如何入门数据分析?
  9. CP15 中的寄存器
  10. Vue2积分商城PC端项目(六)