SpringMVC之使用与原理

SpringMVC之使用与原理


前言

SpringMVC 也叫 Spring web mvc。是 Spring内置的一个MVC框架,在 Spring3.0 后发布。SpringMVC 框架解决了WEB开发中常见的问题(参数接收、文件上传、表单验证等等),而且使用简单,与Spring无 缝集成。支持 RESTful风格的URL请求。采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性 和灵活性。

一、初窥门径

在没有使用SpringMVC之前我们都是使用Servlet在做Web开发。但是使用Servlet开发在接收请求参数,数据共享,页面跳转等操作相对比较复杂。servlet是java进行web开发的标准,既然springMVC是对servlet的封装,那么很显然**SpringMVC底层就是Servlet,SpringMVC就是对Servlet进行深层次的封装。**

二、小试牛刀

1.引入依赖

<?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>springmvckkb</groupId>
    <artifactId>com.dmlll.mvc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.15.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <target>1.8</target>
                    <source>1.8</source>
                </configuration>
            </plugin>
            <!--tomcat插件-->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>8080</port>
                    <path>/</path>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

SpringMVC依赖了Spring,如果对版本没有要求,不必再导入Spring
SpringMVC之使用与原理

2.创建Spring和SpringMVC的配置文件

2.1 Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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/context http://www.springframework.org/schema/context/spring-context.xsd
        ">
    <context:component-scan base-package="com.dmlll.dao,com.dmlll.service"/>
</beans>

2.2 SpringMVC配置文件

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

    <context:component-scan base-package="com.dmlll.controller"/>
    <!--开启mvc在注解驱动-->
    <mvc:annotation-driven/>
</beans>

3.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的配置-->     
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:application.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--SpringMVC的配置-->
    <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:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

</web-app>

4.编写Controller

@Controller
public class TestController {
    @RequestMapping("hello.do")
    public ModelAndView hello(){
        String str = "欲练此功,必先自宫";
        System.out.println(str);
        ModelAndView mv = new ModelAndView();
        mv.addObject("word",str);
        mv.setViewName("hello");
        return mv;
    }
}

5.编写个页面

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

6.启动tomcat

因为配置了插件,可以直接在maven中启动
SpringMVC之使用与原理
SpringMVC之使用与原理

三、粗通皮毛

1.SpringMVC的工作流程

SpringMVC之使用与原理

  1. 浏览器发送请求,DispatchServlet接收到浏览器发送的请求
<!--这里依赖你的web.xml中配置的
	<url-pattern>*.do</url-pattern> 所有带有后缀(.do)的请求经过前端控制器
	<url-pattern>/</url-pattern> 所有请求的经过前端控制器
-->
	<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:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  1. DispatchServlet接收到请求后转交给HandlerMapping
  2. HandlerMapping根据请求找到对应的处理器,并将其封装成一个处理器执行链(包括处理器Handler、处理器拦截器HandlerInterceptor)返回给DispatchServlet
  3. DispatchServlet根据Handler找到对应的HandlerAdaptor,HandlerAdaptor经过参数封装/数据格式转换等一系列操作。
  4. HandlerAdaptor执行Controller中的方法
  5. Controller返回ModelAndView
  6. HandlerAdaptor将ModelAndView返回给DispatchServlet
  7. DispatchServlet将ModelAndView交给ViewResolve进行解析
  8. ViewResolve将解析后得到的View返回给DispatchServlet
  9. DispatcherServlet调用视图对象进行渲染,得到响应对象
  10. 将响应对象返回给浏览器
    代码如下(示例):

2.SpringMVC组件

  1. DispatcherServlet:前端控制器
    用户请求的入口控制器,DispatcherServlet是整个流程控制的中心,由他调用其他组件处理用户的请求。DispatcherServlet降低了各组件之间的耦合性。
  2. HandlerMapping:处理器映射器
    HandlerMapping是派发请求的控制器。负责根据用户的请求找到Handler。
  3. Handler:处理器
    Handler即Controller,由程序员根据需求编写
  4. HandlerAdaptor:处理器适配器
    负责调用处理器、传递参数等工作。
  5. VIewResolver:视图解析器
    ViewResolver负责将处理结果生成View视图。ViewResolver首先根据逻辑视图名称(相对)解析成物理视图名称(绝对),在生成View视图对象,最后对View进行渲染,将处理结果展示给用户。

3.web.xml中url-pattern解析

	<servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

该节点一般有两种写法:

  1. *.xx
    在没有特殊要求的情况下,SpringMVC的前端控制器常使用后缀匹配方式
  2. /
    该种方式是让所有的请求都经过前端控制器,去找对应的处理器。但是静态文件不会去编写处理器,所以就需要去配置静态资源的放行
<!--方法1:在SpringMVC.xml中配置-->
<mvc:default-servlet-handler/>
<!--
声明该标签之后,SpringMVC框架会在容器中创建
DefaultServletHttpRequestHandler处理器对象。
该对象会对所有进入前端控制器的URL进行检查。
如果发现是静态资源的请求,就将该请求转交给Web应用服务器处理(如:Tomcat)
一般的服务器都有默认的Servlet。
Tomcat服务器中,有一个专门用于处理静态资源访问的Servlet---->DefaultServlet。位与tomcat安装目录/conf/web.xml中
-->
<!--方法2:在SpringMVC.xml中配置-->
<!--mapping:映射该文件夹中所有文件,location:文件所在位置-->
<mvc:resources mapping="/image/**" location="/image/"/>
<!--
在Spring3.0后,定义了专门处理静态资源请求的处理器ResourceHttpRequestHandler。并添加<mvc:resources/>标签,用于解决静态资源无法访问的问题
-->

4.常用注解

  1. @RequestMapping
    定义了处理器对于请求的映射规则,即请求路径。可以作用与类和方法
  2. @ResponseBody
    将返回的数据结构转换为JSON格式
  3. @PathVariable
    用来获取路径中的参数
    http://localhost:8080/user/{id}
  4. @RequestParam
    用于获取请求的参数
    http://localhost:8080/user?id=1
  5. @RequestBody
    用于POST请求上,接受JSON实体参数
  6. @ControllerAdvice
    Controller增强器,给Controller控制器添加统一的操作或处理

5.中文乱码

Spring对于请求参数中的中文乱码问题,给出了专门的CharacterEncodingFilter类,在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>

可进入该类查看对应的参数:
SpringMVC之使用与原理
如果使用的是maven中的tomcat插件,还应该去配置tomcat的字符集

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <port>8080</port>
        <path>/</path>
        <uriEncoding>utf-8</uriEncoding>
    </configuration>
</plugin>

四、登堂入室

1.处理器接收参数

编写传递参数的页面params.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>处理参数</title>
</head>
<body>
<form action="/params/get1.do">
    ID:<input type="text" name="id"><br/>
    姓名:<input type="text" name="name"><br/>
    地址:<input type="text" name="address"><br/>
    <button type="submit">提交</button>
</form>
</body>
</html>

编写请求结束跳转的页面ok.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${id},${name},${address}
</body>
</html>

编写实体类Person.java

public class Person {
    private Integer id;
    private String name;
    private String address;
	//setter/getter/toString
}

编写页面跳转的控制器ParamsController.java

@Controller
@RequestMapping("params")
public class ParamsController {

    @RequestMapping("view.do")
    public ModelAndView view(){
        System.out.println("进入params页面");
        return new ModelAndView("params");
    }
}    

1.1 直接使用方法的参数逐个接收

注意:参数名必须和前端传过来的名称一致
向ParamsController.java中添加方法

@RequestMapping("get1.do")
public ModelAndView get1(Integer id,String name,String address){
    System.out.println(id + "---" + name + "---" + address);
    ModelAndView mv = new ModelAndView("ok");
    mv.addObject("id",id);
    mv.addObject("name",name);
    mv.addObject("address",address);
    return mv;
}

运行:
SpringMVC之使用与原理
SpringMVC之使用与原理

1.2 使用对象接收多个参数

注意:对象的属性必须和前端传过来的参数名称一致
向ParamsController.java中添加方法

@RequestMapping("get2.do")
public ModelAndView get2(Person person){
    System.out.println(person.getId() + "---" + person.getName() + "---" + person.getAddress());
    ModelAndView mv = new ModelAndView("ok");
    mv.addObject("person",person);
    return mv;
}

修改params.jsp中的表单

<form action="/params/get2.do">
    ID:<input type="text" name="id"><br/>
    姓名:<input type="text" name="name"><br/>
    地址:<input type="text" name="address"><br/>
    <button type="submit">提交</button>
</form>

修改ok.jsp接收参数的变量

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${person.id},${person.name},${person.address}
</body>
</html>

运行:
SpringMVC之使用与原理
SpringMVC之使用与原理

1.3 使用原生HttpServletRequest获取

向ParamsController.java中添加方法

@RequestMapping("get3.do")
public ModelAndView get3(HttpServletRequest request){
    String id = request.getParameter("id");
    String name = request.getParameter("name");
    String address = request.getParameter("address");
    System.out.println(id + "---" + name + "---" + address);
    ModelAndView mv = new ModelAndView("ok");
    //封装成Person
    Person person = new Person();
    person.setId(Integer.valueOf(id));
    person.setName(name);
    person.setAddress(address);
    mv.addObject("person",person);
    return mv;
}

修改params.jsp的form路径

<form action="/params/get3.do">

运行:
SpringMVC之使用与原理
SpringMVC之使用与原理

1.4 获取日期类型的参数

直接接收会报错
修改Person.java,添加时间属性

private Date date;

修改params.jsp,添加时间选择框

日期:<input type="date" name="date"><br/>

运行:
SpringMVC之使用与原理
SpringMVC之使用与原理
需要在date属性上添加注解@DateTimeFormat(pattern = “yyyy-MM-dd”)
再次启动:
SpringMVC之使用与原理

1.5 获取数组类型的参数

修改ParamsController.java

@RequestMapping("get4.do")
public ModelAndView get4(String[] names){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",names);
    modelAndView.setViewName("ok");
    return modelAndView;
}

修改params.jsp表单

<form action="/params/get4.do">
    姓名1:<input type="text" name="name"><br/>
    姓名2:<input type="text" name="name"><br/>
    姓名3:<input type="text" name="name"><br/>
    <button type="submit">提交</button>
</form>

修改ok.jsp

 ${name[0]},${name[1]},${name[2]}

运行:
SpringMVC之使用与原理
SpringMVC之使用与原理

1.6 获取List类型的参数

集合类型不能直接接收

修改ParamsController.java

@RequestMapping("get5.do")
public ModelAndView get5(List<String> name){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",names);
    modelAndView.setViewName("ok");
    return modelAndView;
}

修改params.jsp

<form action="/params/get5.do">

此时运行:
SpringMVC之使用与原理
需要在集合参数上添加@RequestParam()注解

@RequestMapping("get5.do")
public ModelAndView get5(@RequestParam(value = "names") List<String> names){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",names);
    modelAndView.setViewName("ok");
    return modelAndView;
}

再次启动一切正常。
SpringMVC之使用与原理
如果将List<String>换成List<Person>
再次启动
(此时name属性与Person中的name属性对应,如果正常,则只有Person.name有值)
SpringMVC之使用与原理
提示List中的name不存在,因此不能直接使用List去接受对象集合,将集合封装成一个对象ListVO

public class ListVO<T> {
    private List<T> list;

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}

修改ParamsController.java

@RequestMapping("get6.do")
public ModelAndView get6(ListVO vo){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",vo.getNameList());
    modelAndView.setViewName("ok");
    return modelAndView;
}

修改params.jsp

<form action="/params/get6.do">
    姓名1:<input type="text" name="nameList[0].name"><br/>
    姓名2:<input type="text" name="nameList[1].name"><br/>
    姓名3:<input type="text" name="nameList[2].name"><br/>
    <button type="submit">提交</button>
</form>

启动程序:
SpringMVC之使用与原理
注意:前端参数列表的参数名必须跟该ListVO对象的属性一致

1.7使用URL地址传参

修改ParamController.java

@RequestMapping("get7/{id}.do")
public ModelAndView get7(@PathVariable("id") Integer id){
    ModelAndView modelAndView = new ModelAndView("ok");
    modelAndView.addObject("id",id);
    return modelAndView;
}

修改ok.jsp

  ${id}

直接在地址栏输入
http://localhost:8080/params/get7/1.do
因为在配置文件中配置的*.do,只有.do为后缀的才能被拦截到,所以采用了这种方式@RequestMapping(“get7/{id}.do”)

2.处理器方法返回值

处理器返回值有四种类型:

  1. ModelAndView
  2. String
  3. 返回自定义类型对象
  4. 无返回值void

ModelAndView在上一节已经使用。

2.2 返回String

@RequestMapping("get8.do")
public String get8(){
    return "ok";
}

如果携带参数可携带HttpServletRequest ,通过原生的方法传递参数

2.3 返回对象类型

2.3.1 返回基本类型

@RequestMapping("get9.do")
@ResponseBody
public String get9(){
    return "xiaoming";
}

SpringMVC之使用与原理

引入JSON依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.12.4</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.4</version>
</dependency>
@RequestMapping("get9.do")
@ResponseBody
public Person get9(){
    Person p = new Person();
    p.setAddress("东莞");
    p.setName("超级玛丽");
    p.setId(1);
    return p;
}

SpringMVC之使用与原理

2.4 返回void

使用原生的HttpServletRequest、HttpServletResponse

3. 转发和重定向

3.1 转发

@RequestMapping("get11.do")
public String get11(){
    return "forward:/ok.jsp";
}
@RequestMapping("get12.do")
public ModelAndView get12(){
    return new ModelAndView("forward:/ok.jsp");
}

3.2 重定向

@RequestMapping("get13.do")
public String get13(){
    return "redirect:/ok.jsp";
}
@RequestMapping("get14.do")
public ModelAndView get14(){
    return new ModelAndView("redirect:/ok.jsp");
}

一般的重定向不会传递参数,SpringMVC中的重定向可以传递参数,以?key=value的形式拼接

4.异常处理

使用@ExceptionHandler注解,指定为异常处理的方法。
返回值可以是:ModelAndView、String、void
参数可以是:Exception及其子类、HttpServletRequest、HttpServletResponse等,系统会自动为其赋值

4.1 自定义异常类

public class MyException extends Exception{
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}

ParamsController.java

@RequestMapping("get16.do")
public ModelAndView get16() throws MyException {
    throw new MyException("就故意报错");//抛出异常
}
@ExceptionHandler(value= MyException.class)
public ModelAndView get15(Exception ex){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("ok");
    modelAndView.addObject("msg",ex.getMessage());
    return modelAndView;
}

修改ok.jsp

${msg}

运行
SpringMVC之使用与原理
也可以通过@ControllerAdvice注解将异常处理方法统一管理

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView exception01(ArithmeticException ex){
        ModelAndView ok = new ModelAndView("ok");
        ok.addObject("msg",ex.getMessage());
        return ok;
    }
    @ExceptionHandler(value = Exception.class)
    public ModelAndView exception02(Exception ex){
        ModelAndView ok = new ModelAndView("ok");
        ok.addObject("msg",ex.getMessage());
        return ok;
    }
}

5. 拦截器

主要作用:拦截用户的请求,进行相应的预处理和后处理
如何实现:实现HandlerInterceptor接口,重写其方法

public class MyInterceptor implements HandlerInterceptor {
	//在处理器方法执行之前执行,返回值为true,放行拦截的方法,
	//将afterCompletion方法放入一个专门的方法栈等待
	//返回值为false,被拦截的方法则不执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }
	//该方法在处理器方法执行之后,返回结果之前,该方法可以改变处理器方法的处理结果和跳转的页面
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
	//preHandle方法返回true时,在处理器方法返回结果之后,执行该方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

配置拦截器

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean id="myInterceptor" class="com.dmlll.controller.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

编写拦截器代码

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("预处理-----------");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("处理中-----------");
        System.out.println("替换处理器存储的msg");
        request.setAttribute("msg","你被替换了");
    }

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

编写处理器

@RequestMapping("get17.do")
public String get17(HttpServletRequest request)  {
    System.out.println("处理器方法执行存储");
    request.setAttribute("msg","我是1");
    return "ok";
}

SpringMVC之使用与原理

6.文件上传和下载

6.1.文件上传

SpringMVC为文件上传提供了直接支持,即通过MultipartResolver实现
Spring中有一个实现类CommonsMultipartResolver
在SpringMVC上下文中默认没有装配MultipartResolver,需要先在配置文件中配置

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

引入依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

编辑页面进行文件上传

<form action="/params/get18.do/id" method="post" enctype="multipart/form-data">
    文件:<input type="file" name="file"><br/>
    <button type="submit">提交</button>
</form>

编写处理器

@RequestMapping("get18.do")
public String get18(@RequestParam("file") MultipartFile file,HttpServletRequest request) throws IOException {
    String originalFilename = file.getOriginalFilename();//原始文件名
    //获取后缀
    String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    //组成随机名称
    String filename = UUID.randomUUID().toString().replace("-","")+suffix;
    request.setAttribute("filename",filename);
    //存储路径
    String path = request.getServletContext().getRealPath("/upload") + "/";
    file.transferTo(new File(path,filename));
    System.out.println("上传成功");
    return "ok";
}

新建upload文件夹
SpringMVC之使用与原理
修改ok.jsp

<img src="upload/${requestScope.filename}">

运行:
SpringMVC之使用与原理

SpringMVC之使用与原理

6.2 下载

@RequestMapping("get19.do")
public ResponseEntity get19(HttpServletRequest request) throws IOException {
    //指定路径
    String path = request.getServletContext().getRealPath("/upload")+"/566e00bb19a8430e85beeafd4c27697a.jpg";
    //创建响应的头信息
    HttpHeaders headers = new HttpHeaders();
    //以流的形式打开
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    //以附件形式响应给用户
    headers.setContentDispositionFormData("attachment", URLEncoder.encode("566e00bb19a8430e85beeafd4c27697a.jpg","utf-8"));
    File file = new File(path);
    ResponseEntity responseEntity = new ResponseEntity(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
    return responseEntity;
}
<img src="/upload/566e00bb19a8430e85beeafd4c27697a.jpg">
<a href="/params/get19.do">下载</a>

SpringMVC之使用与原理

上一篇:处理器映射器与处理器适配器最佳实践(●ˇ∀ˇ●)


下一篇:道达尔将在全球5,000处服务站安装太阳能光伏板