欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

SSM第八讲 SpringMVC高级特性

SpringMVC高级特性


  • SpringMVC三种处理资源方式
  • Json数据交互
  • Springmvc处理异常方式
  • 文件上传下载

一、SpringMVC的拦截规则

昨天我们将SpringMVC拦截后缀设置为*.form代表SpringMVC会拦截*.form结尾的后缀

SpringMVC提供的拦截规则:

*.form:代表以*.form结尾的后缀请求都会进入springmvc管理

/:代表除了JSP以外拦截所有,html、css、js等静态web资源也会拦截

/*:拦截所有请求

1. 分析

如果SpringMVC拦截了静态资源会怎么样?会出现404错误!

在昨天的源码分析中分析发现,所有请求进入SpringMVC最终会寻找handler执行,很显然如果拦截到静态资源的话是肯定找不到对应的handler的,因此就会出现404情况。

2. 缺省servlet放行

tomcat提供的默认servlet(DefaultServlet),处理静态资源的(html/css/js),此Servlet在tomcat/conf/web.xml中有配置

在这里插入图片描述

在这里插入图片描述

<!--代表以html的任何请求进入Tomcat默认的Servlet处理(放行)-->
<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.png</url-pattern>
</servlet-mapping>

 

配置DefaultServlet需要引入依赖:

<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-catalina</artifactId>
    <version>8.5.41</version>
    <!--此jar包在tomcat中已经有了,但是如果不引入此依赖项目则会报错,因此依赖范围provided就行-->
    <scope>provided</scope>
</dependency>

 

回顾Maven依赖范围:

  • compile:编译时需要,测试时需要,运行时需要,打包时需要
  • provided:编译时需要,测试时需要,运行时不需要,打包时不需要
  • runtime:编译时不需要,测试时需要,运行时需要,打包时需要
  • Test:编译时不需要,测试时需要,运行不时需要,打包也需要

缺省servlet放行原理是如果是配置的后缀请求直接进入缺省servlet,而不是进入springmvc进行处理

但是如果springmvc的拦截规则配置成/*代表拦截请求优先进入springmvc不进入缺省servlet导致出现404

因此如果想要使用缺省servlet方式放行静态资源springmvc拦截规则不能为/*

3. 配置resource放行静态资源

<!--
    resources:配置springmvc放行
        mapping:映射地址
        location:具体目录
        /js/*代表page下面的所有资源不拦截
        /js/** 代表page下所有的资源不拦截包括子孙包
-->
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/img/**" location="/img/" />

 

<mvc:resources />由Spring MVC框架自己按配置的规则处理静态资源,并添加一些有用的附加值功能。

**注意:JSP页面不属于静态资源!**如果是常见的浏览器能解析的格式,直接按照协议返回,如果不是浏览器能直接解析的会返回下载头导致下载该jsp页面!

4. 配置SpringMVC静态资源处理

<mvc:default-servlet-handler />

Springmvc会在Spring MVC上下文中定义一个DefaultServletHttpRequestHandler

它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。

一般Web应用服务器默认的Servlet名称是”default”,因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web应用服务器的默认Servlet名称不是”default”,则需要通过default-servlet-name属性显示指定:

<mvc:default-servlet-handler default-servlet-name=“所使用的Web服务器默认使用的Servlet名称” />

<!--
    default-servlet-name:缺省servlet的名称(默认值为default)
-->
<mvc:default-servlet-handler default-servlet-name="default"/>

 

DefaultServletHttpRequestHandler底层也是依赖缺省servlet,请求被springmvc拦截下来之后会判断是否是静态资源,如果是那么就走缺省servlet

4. 探究三种放行

web.xml:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--配置springmvc配置文件的位置-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dispatcher-servlet.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <!--配置拦截所有请求,jsp也不例外-->
    <url-pattern>/*</url-pattern>
</servlet-mapping>

 

controller:

@Controller
public class Demo1Controller {

    @RequestMapping("/demo1")            
    public String demo1() {
        System.out.println("controller执行啦!");
        return "/success.jsp";         
    }

}

 

在这里插入图片描述

发现跳转到的jsp页面以源码形式展示,这是因为web.xml中配置/*导致jsp页面被拦截,而且配置的放行机制为

<mvc:default-servlet-handler />,把jsp页面交给缺省servlet,而缺省servlet只能处理静态页面,jsp严格来说不算是静态页面,缺省servlet就把他当做普通文本处理了

解决方法:web.xml中拦截规则使用/

5. 放行规则小结:

缺省servlet放行:请求没有进入springmvc,而是直接进入缺省servlet进行处理放行

resource放行:实质上请求是进入了springmvc然后由springmvc自己处理资源,达到放行效果

default-servlet-handler放行:请求进入springmvc然后对其进行筛选,发现是个”静态”资源就交给缺省servlet去处理,但是缺省servlet只会处理静态资源,如果是jsp会特殊处理!

6. 视图解析器

打开spring-webmvc-5.0.6.RELEASE.jar下的DispatcherServlet.properties文件查看默认注册的视图解析器

在这里插入图片描述

我们希望不适用默认的视图解析器,而是在视图解析器上”做点手脚”

<!--配置视图解析器
    prefix:视图解析器的前缀
    suffix:视图解析器的后缀
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

 

controller:

package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Demo1Controller {

    @RequestMapping("/demo1")            //自定义属性绑定
    public String demo1(Model model) {

        model.addAttribute("user","xiaodong");
        return "index";         //自动跳转到 /jsp/index.jsp页面
    }

}

 

二. Json的支持

所谓的对JSON的支持,就是SpringMVC支持自动将JSON转换成JAVA对象,也支持将Java对象自动转成JSON.

SpringMVC本身没有对JSON数据处理的类库.要支持JSON的自动转换必须导入JSON的支持包

Jackson依赖:

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

 

1. JSON转换成JAVA对象

需求:请求发送一个JSON字符串给执行方法,执行方法根据@RequestBody这个注解强制将

如果前端发送的不是JSON字符串则不能使用@RequestBody

请求发送过来的JSON转换成Java对象.

1.1页面以JSON字符串传递方式:

"{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}"

 

配置步骤

客户端请求

$.ajax({
    url: "/demo5_1.form",
    contentType:"application/json",     //告知ajax引擎传递的是json类型
    type:"post",            //传递json字符串必须使用post提交
    data: "{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}",
    success: function (data) {
    }
});

 

控制器代码

@RequestMapping("/demo5_1")
public String demo5_1(@RequestBody User user) {           //json字符串 转user
    System.out.println(user);

    return "/success.jsp";
}

 

Json字符串转Map

前端

$("#test3").click(function () {

    $.ajax({
        url: "/demo5_2.form",
        type:"post",
        contentType:"application/json",
        //Map类型只支持json字符串
        data: "{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}",
        success: function (data) {
        }
    });
});

 

后台:

//json字符串 转map  Map类型不支持json对象
@RequestMapping("/demo5_2")
public String demo5_1(@RequestBody Map map) {           
    
    System.out.println(map);

    return "/success.jsp";
}

 

2. 数据返回到页面,自动将Java对象转成JSON

Java对象转Json

借助@ResponseBody把Java对象转换为json对象,并且把响应头类型改为application/json;charset=utf8

前端:

$("#test4").click(function () {

    $.ajax({
        url: "/demo5_3.form",
        success: function (data) {
            alert(data);
            alert(JSON.stringify(data));
        }
    });
});

 

后台:

@RequestMapping("/demo5_3")
//表示对象以json对象写出到前端 并修改contentType:'application/json;charset=utf8'
@ResponseBody				
public User demo5_3() {         //user转json对象

    User user = new User();
    user.setId(20);
    user.setUsername("xiaobiao");
    user.setPassword("admin");
    user.setAddress("guangzhou");

    user.setBirthday(new Date());

    return user;
}

 

将Map对象转JSON对象

$("#test5").click(function () {

    $.ajax({
        url: "/demo5_4.form",
        success: function (data) {
            alert(data);
            alert(JSON.stringify(data));
        }
    });
});

 

@RequestMapping("/demo5_4")
@ResponseBody
public Map demo5_4() {           //map转json对象
    Map map=new HashMap();
    map.put("id",20);
    map.put("username","xiaobiao");
    map.put("password","admin");
    map.put("address","guangzhou");
    map.put("birthday",new Date());
    return map;
}

 

小结:

使用@ResponseBody如果返回的是一个Java对象,那么springmvc会帮我们自动转成json对象写入到前端

并且把响应头(Content-Type)设置为application/json;charset=utf8,但是如果直接返回一个字符串,那么@ResponseBody会以普通文本方式写入到前端Content-Type还是默认的text/plain;charset=ISO-8859-1就会造成中文乱码现象

@produces :设置响应的类型(Content-Type)

@consumes:规定请求的类型(Content-Type)

案例produces:响应普通字符串

如果响应的直接是个字符串则会出现乱码现象

@RequestMapping(value = "/demo5_5")
@ResponseBody
public String demo5_5() {          

    return "{\"username\":\"东方标准\"}";			
}

 

查看响应头:

在这里插入图片描述

修改代码:

//规定响应的格式为	application/json;charset=utf8
@RequestMapping(value = "/demo5_5",produces = "application/json;charset=utf8")
@ResponseBody
public String demo5_5() {

    return "{\"username\":\"东方标准\"}";
}

 

查看响应头:

在这里插入图片描述

以Json对象形式返回,并且编码为utf8

案例consumes:

我们知道@RequestBody能够把前台传递过来的json字符串自动封装到后台的Java对象中,但是前台提交的方式必须是POST,除此之外请求头(Content-Type)必须是application/json;charset=utf8,我们能不能在后台就规定(提示)一下前端传递的请求头的类型呢?用@RequestMapping注解中的consumes!

后台代码:

//规定前端提交的请求头必须application/json;charset=utf8
@RequestMapping(value = "/demo5_7", consumes = "application/json;charset=utf8")
@ResponseBody
public User demo5_7(@RequestBody User user) {           //map转json对象

    return user;
}

 

前端代码:

$("#test6").click(function () {
    var json={username:"东方标准",password:"admin"};
    $.ajax({
        url: "/demo5_7.form",
        type:"post",
        contentType: "application/json;charset=utf8",		
        data: "{\"username\": \"xiaodong\", \"address\": \"guangzhou\", \"birthday\": \"2000-10-10\"}"
        success: function (data) {
            alert(data);
            alert(JSON.stringify(data));
        }
    });
});

 

3. 探究springmvc参数封装

1. 表单entype类型

  • application/x-www-form-urlencoded

这是默认的编码类型,使用该类型时,会将表单数据中非字母数字的字符转换成转义字符,如"%HH",然后组合成这种形式key1=value1&key2=value2;所以后端在取数据后,要进行解码。

  • multipart/form-data

这是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 表单的 enctype 等于 multipart/form-data

注意:

  1. 一般来说,methodenctype是两个不同的互不影响的属性,但在传文件时,method必须要指定为POST,否则文件只剩下filename了;
  2. 当没有传文件时,enctype会改回默认的application/x-www-form-urlencoded
  • text/plain

按照键值对排列表单数据key1=val1\r\nkey2=val2,不进行转义。

  • application/json及其他MIME类型

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

表单数据编码类型application/json,已经被W3C遗弃(详见HTML JSON Form Submission),建议不要在<form enctype="...">中使用了,即使用了如果浏览器不支持,也会替换成application/x-www-form-urlencoded
同理,其余的MIME类型,也不支持,均会替换成默认编码application/x-www-form-urlencoded

contentType对照表:http://tool.oschina.net/commons/

2. 探究springmvc自动封装

我们前面已经学过,不使用@RequestBody注解springmvc也能帮我们自动封装Java对象

但是是有前提的:

  1. 请求类型为get:**提交的请求头必须是null(get提交设置了别的entype也会自动为null),因此get提交不需要担心请求头问题
  2. 请求类型为post:**提交的请求头必须是application/x-www-form-urlencoded类型(表单默认的提交类型),ajax不写也是默认这种类型

只要提交数据格式为username=东方标准&admin=123456springmvc都能帮我们封装数据,不限提交方式get/post

我们前面知道ajax提交使用json字符串,而且后台必须需用@RequestBody注解来强制封装,我们知道前端有json对象方式提交数据,此时如果请求头类型为application/x-www-form-urlencodedjson对象也会默认格式化为username=东方标准&admin=123456这种数据格式往后台提交,能够自动封装数据

测试springmvc自动封装(get)

前端:
<!--
	get方式提交,ContentType即使设置了也是null
	post方式可以
-->
<form action="/demo5_7.form" method="get" entype="application/x-www-form-urlencoded">
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="submit">
</form>

 

后台:
@RequestMapping(value = "/demo5_7")
@ResponseBody
public User demo5_7(User user, HttpServletRequest request) throws IOException {           //map转json对象
    /**
     * get提交ContentType为null
     * post提交ContentType为application/x-www-form-urlencoded
     */
    String contentType = request.getContentType();
    System.out.println(contentType);
    System.out.println(user);
    return user;
}

 

测试json对象自动封装数据(post)

前端:
$("#test6").click(function () {
    var json = {username: "dfbz", password: "admin"};
    $.ajax({
        url: "/demo5_7.form",
        type: "post",
        //请求头类型设置为默认的(不写也可以post默认就是application../x-www...)
        contentType:"application/x-www-form-urlencoded; charset=UTF-8",
        data: json,		//传递json对象
        success: function (data) {
            alert(data);
            alert(JSON.stringify(data));
        }
    });

});

 

后台:
@RequestMapping(value = "/demo5_7")
@ResponseBody
public User demo5_7(User user, HttpServletRequest request) throws IOException {           //map转json对象
    /**
     * ajax提交不写contentType默认为application/x-www-form-urlencoded
     */
    String contentType = request.getContentType();
    System.out.println(contentType);
    System.out.println(user);
    return user;
}

 

测试json字符串自动封装数据

前端:
$("#test6").click(function () {
    var json = {username: "dfbz", password: "admin"};
    $.ajax({
        url: "/demo5_6.form",
        type: "post",		//提交方式必须使用post
        //提交json字符串自动封装必须使用application/json
        contentType:"application/json;charset=utf8",		
        data: JSON.stringify(json),
        success: function (data) {
            alert(data);
            alert(JSON.stringify(data));
        }
    });

});

 

后台:
/**
 * 1. 使用@RequestBody前端必须传递json字符串
 * 2. 请求类型必须是application/json
 * 3. 必须是post提交
 * @param user
 * @return
 */
@RequestMapping(value = "/demo5_6")
@ResponseBody
public User demo5_6(@RequestBody User user) {
    return user;
}

 

小结:我们只要记住get一般是用于查询的,因此只要封装基本数据类型就可以,post一般做添加的因此需要封装Java对象

@RequestBody:强制封装,只能用于前端提交json字符串的,而且提交类型必须是application/json;charset=utf8,提交类型必须是Post(因为get的提交类型为null)

自动封装:用于前端提交key=val&key=val类型的数据,提交方式为get或者post+提交类型application/x-www-form-urlencoded;

3. 表单序列化

有时候我们也需要使用ajax提交整个表单的数据,如果将整个表单的数据手动拼接为json对象未免太过麻烦,好在jquery有帮我们提供一个表单序列化方法(serialize),将整个表单的数据序列化为key1=val1&key2=val2这样的格式,加上我们前面学过的知识可以使用ajax将整个表单的数据提交到后台并能自动封装了!

前端:

<form action="/demo5_7.form" id="mainForm" >
    <input type="text" name="username">
    <input type="text" name="password">
</form>
<button id="test6">ajax提交表单数据</button>
<script>
$("#test6").click(function () {
    $.ajax({
        url: "/demo5_7.form",
        type: "post",
        data: $("#mainForm").serialize(),		//序列化表单数据
        success: function (data) {
            alert(data);
            alert(JSON.stringify(data));
        }
    })

});
</script>

 

后端:

@RequestMapping(value = "/demo5_7")
@ResponseBody
public User demo5_7(User user, HttpServletRequest request) throws IOException {           
    System.out.println(user);
    return user;
}

 

三、SpringMVC的异常处理方式

1.单个异常处理方式

package com.dfbz.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class Demo2Controller {


    @RequestMapping("/demo2_1")
    @ResponseBody
    public String test1() {

        System.out.println("东方");
    	int i = 1 / 0;
    	System.out.println("标准");

        return "你好好";
    }

    /**
     * 当前controller方法出现异常进入此方法
     * @param model
     * @param e:出现的异常对象
     * @return
     */
    @ExceptionHandler(ArithmeticException.class)
    public String test2(Model model, Exception e) {

        model.addAttribute("error", e.getMessage());
        System.out.println("出现异常啦!");

        return "error";
    }
}

 

2. 全局异常处理方式

需要我们编写一个类实现HandlerExceptionResolver接口

定义全局异常:

package com.dfbz.exception;

import com.dfbz.controller.Demo2Controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 全局异常处理类
 */

public class MyExceptionHandler implements HandlerExceptionResolver {

    /**
     *
     * @param request
     * @param response
     * @param obj   :出现异常handler(HandlerMethod类型)
     * @param e     :出现的异常对象
     * @return
     */
    @Override
    public ModelAndView resolveException(
            HttpServletRequest request,
            HttpServletResponse response,
            Object obj,
            Exception e) {

        HandlerMethod method= (HandlerMethod) obj;
        ModelAndView mav=new ModelAndView();
        mav.setViewName("error");
        mav.addObject("error",e.getMessage());

        return mav;
    }
}

 

注入到IOC容器中:

<!--把异常类注入IOC容器-->
<bean class="com.dfbz.exception.MyExceptionHandler" />

 

测试controller:

@RequestMapping("/demo2_1")
@ResponseBody
public String test1() {

    System.out.println("东方");
    int i = 1 / 0;
    System.out.println("标准");

    return "你好好";
}

 

注意:方法处理异常优先级比全局异常高!如果进入了方法处理异常则不会进入全局异常方法中!

注解方式实现全局异常

使用@ControllerAdvice注解可以配置全局异常

@ExceptionHandler():设置什么异常才会进入方法

package com.dfbz.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

@ControllerAdvice           //全局异常注解
public class AnnoMyExceptionHandler {
    /**
     * 
     * @param e 触发的异常对象
     * @return
     */
    @ExceptionHandler(value = Exception.class)      //传入什么异常需要进入此方法
    public ModelAndView resolveException(Exception e) {

        ModelAndView mav=new ModelAndView();
        mav.setViewName("error");
        mav.addObject("error",e.getMessage());

        return mav;
    }
}

 

3. SpringMVC提供的处理方式

只需要在spring.xml配置文件中定义即可,适合全局处理简单的异常,缺点不能自定义异常信息

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>

<!--                <prop key="java.lang.ArithmeticException">/jsp/error.jsp</prop>-->
            <!--已经配置了视图解析器-->
            <prop key="java.lang.ClassCastException">index</prop>
            <prop key="java.lang.ArithmeticException">error</prop>
        </props>
    </property>
</bean>

 

4. 框架底层异常和无法捕获的异常处理方案

在web.xml文件中定义此类的处理方法

<!--如果程序出现Throwable异常则会跳转到/index.jsp页面-->
<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/index.jsp</location>
</error-page>
<error-page>
    <!--如果页面出现404则跳转到/success.jsp页面-->
    <error-code>404</error-code>
    <location>/success.jsp</location>
</error-page>

 

在这里插入图片描述

四、上传下载的实现

1.文件上传

SpringMVC支持文件上传组件

commons-fileupload组件.

commons-fileupload依赖commons-io组件.

1.1 文件上传开发流程

a.编写form表单 表单必须是post请求方式,enctype必须是multipart/form-data

(默认值是:application/x-www-form-urlencoded)

b.配置文件上传解析器 bean的名字不能写错,一定是multipartResolver

c.在controller中编写处理文件上传的方法,参数为MultipartFile

1.2 配置步骤

1.2.1.导入依赖

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

 

1.2.2. 前端页面

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

<%--
    文件上传enctype类型必须是multipart/form-data
    提交方式必须是post
--%>
<form action="/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="file">
    <input type="submit">
</form>

</body>
</html>

 

1.2.3. controller

@RequestMapping("/upload")
public String upload(HttpServletRequest request, MultipartFile file) throws IOException {          //变量名一定要和前端提交的name一致

    String fileName = file.getOriginalFilename();

    String realPath = request.getRealPath("upload");        //获取服务器端某个文件夹的绝对路径

    file.transferTo(new File(realPath +"/"+ UUID.randomUUID().toString() + fileName));

    return "success";
}

 

1.2.4. dispatcher-servlet.xml配置

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

    <!--默认文件最大大小,单位b-->
    <property name="maxUploadSize" value="20000000"></property>
</bean>

 

注意:

因为核心控制器对上传解释器的名字是固定的. 是multipartResolver,所以我们配置上传解释器,名字必须是multipartResolver

查询核心控制器DispacherServlet代码,发现multipartResolver一个固定加载的属性。

public class DispatcherServlet extends FrameworkServlet {
    public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";

 

如图所示

在这里插入图片描述

1.3. 多文件上传

前端页面

<h3>多文件上传</h3>
<form action="/uploads" enctype="multipart/form-data" method="post">
    <input type="file" name="files">
    <input type="file" name="files">
    <input type="file" name="files">
    <input type="file" name="files">
    <input type="submit">
</form>

 

controller

@RequestMapping("/uploads")
public String uploads(HttpServletRequest request, MultipartFile[] files) throws IOException {          //变量名一定要和前端提交的name一致

    String realPath = request.getRealPath("upload");        //获取服务器端某个文件夹的绝对路径

    for (MultipartFile file : files) {
        String fileName = file.getOriginalFilename();
        file.transferTo(new File(realPath + "/" + UUID.randomUUID().toString() + fileName));
    }

    return "success";
}

 

dispatcher-servlet.xml配置:

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

    <!--默认文件最大大小,单位b-->
    <property name="maxUploadSize" value="20000000"></property>
</bean>

 

1.3.多文件上传

前端页面

<h3>多文件上传</h3>
<form action="/uploads" enctype="multipart/form-data" method="post">
    <input type="file" name="files">
    <input type="file" name="files">
    <input type="file" name="files">
    <input type="file" name="files">
    <input type="submit">
</form>

 

controller

@RequestMapping("/uploads")
public String uploads(HttpServletRequest request, MultipartFile[] files) throws IOException {          //变量名一定要和前端提交的name一致

    String realPath = request.getRealPath("upload");        //获取服务器端某个文件夹的绝对路径

    for (MultipartFile file : files) {
        String fileName = file.getOriginalFilename();
        file.transferTo(new File(realPath + "/" + UUID.randomUUID().toString() + fileName));
    }

    return "success";
}

 

dispatcher-servlet.xml配置:

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

    <!--默认文件最大大小,单位b-->
    <property name="maxUploadSize" value="20000000"></property>
</bean>

作者:易兮科技 | 来源:https://blog.csdn.net/m0_47157676

赞(0) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » SSM第八讲 SpringMVC高级特性

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏