SpringMVC 路径拦截、json交互、文件上传

学习目标

【学习目标】

1,掌握Controller的返回值使用

2,掌握Controller中的转发和重定向使用

3,掌握SpringMVC与json交互

4,掌握图片上传

拦截路径问题

创建项目、依赖

<?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>springmvc</groupId>
    <artifactId>springmvc_one</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>

        </dependency>
        <!--引入jackson支持,实现json与java对象的互转-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.0</version>
        </dependency>

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

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>
        <!--Apache提供的文件上传组件支持-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!--引入jersey支持包实现应用系统与文件系统的通讯访问-->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

    </dependencies>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <!--SpringMVC前端控制器(拦截请求、调用controller控制器方法处理请求、响应)-->
    <servlet>
        <servlet-name>s</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>
    </servlet>

    <!--
      拦截请求:
      1. *.do 拦截所有以.do作为后缀的请求
         要求:请求路径后缀必须以.do结尾;
         缺点:不方便;不支持restful风格的请求
      2. / 表示拦截所有的请求,但不包含jsp请求
         注意:此时静态资源默认就访问不了了。
      -->
    <servlet-mapping>
        <servlet-name>s</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

    <!--<servlet-mapping>-->
        <!--<servlet-name>default</servlet-name>-->
        <!--<url-pattern>*.jsp</url-pattern>-->
    <!--</servlet-mapping>-->

    <!--处理乱码的过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    </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>
    
</web-app>

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 http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--1.开启注解扫描-->
    <context:component-scan base-package="com"/>

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

    <!--文件上传解析器(注意id是固定)-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--指定运行上传的文件最大值:10M(字节)-->
        <property name="maxUploadSize" value="10485760"/>
    </bean>
    
    <!--3.开启注解驱动-->
    <mvc:annotation-driven/>

    <!--4.指定放行的静态资源-->
    <!--mapping 表示映射的路径(访问路径)-->
    <!--location 表示映射的路径对应的实际的物理路径-->
    <mvc:resources mapping="/pages/**" location="/WEB-INF/pages/"/>
    <mvc:resources mapping="/js/**" location="WEB-INF/js/"/>
    <mvc:resources mapping="/index.jsp" location="/index.jsp"/>
    
</beans>

访问静态资源解决办法1:推荐

 <!--4.指定放行的静态资源-->
    <!--mapping 表示映射的路径(访问路径)-->
    <!--location 表示映射的路径对应的实际的物理路径-->
    <mvc:resources mapping="/pages/**" location="/WEB-INF/pages/"/>
    <mvc:resources mapping="/js/**" location="WEB-INF/js/"/>
    <mvc:resources mapping="/index.jsp" location="/index.jsp"/>

解决2:缺省servlet(了解)

  1. web.xml配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51vTxZ9b-1582268945627)(media/8677c136f294f1532144a689c71a0a5f.png)]

  1. 为什么再web.xml中配置的/,导致静态资源访问不了

tomcat服务器也叫做servlet服务器,访问任何资源都是通过servlet把资源返回到浏览器客户端。访问静态资源不是servlet程序,其实是通过一个叫做DefaultServlet(缺省servlet)默认的servlet把静态资源返回到客户端。

在这里插入图片描述

如果项目中配置拦截的路径是/, 会覆盖默认的servlet,导致静态资源处理不了。

  1. 如何解决?
<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>*.html</url-pattern>
</servlet-mapping>

Model和ModelMap

作用

  • 通过Model与ModelMap可以往request域中存储数据。

  • Model与ModelMap作为控制器方法的参数。

    package com;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class ModelController {
        @RequestMapping("model")
        public String model(Model model) {
            model.addAttribute("cn", "china");
            return "sucess";
        }
    
        @RequestMapping("modelMap")
        public String modelMap(ModelMap modelMap){
            modelMap.addAttribute("usa","American");
            return "sucess";
        }
        
    }
    
    

SessionAttributes 注解

使用说明

作用:

用于多次执行控制器方法间的参数共享。

属性:

names:用于指定存入的属性名称

type:用于指定存入的数据类型。该类型的所有数据都会存储到session中。

好处:

减少控制器类域servletApi的耦合。不使用HttpSession对象就可以往session域中存放数据

缺点:

因为往session中放数据是自动存放的,不可控,不方便维护排查错误。

使用示例

package com;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

/**
 * @SessionAttributes names 指定Model对象的哪些key会自动放入session
 * types = Integer.class Model中的Integer类型的所有key都自动放入session
 * 好处:
 * 减少控制器类域servletApi的耦合。不使用HttpSession对象就可以往session域中存放数据
 * 缺点:
 * 因为往session中放数据是自动存放的,不可控,不方便维护排查错误。
 */
@Controller
@SessionAttributes(names = {"name1", "name2"}, types = Integer.class)
public class SessionAttributesController {

    @RequestMapping("set")
    // Model 作为方法参数
    public String setSession(Model model) {
        model.addAttribute("name1", "jack");
        model.addAttribute("name2", "rose");
        model.addAttribute("num1", 100);
        model.addAttribute("num2", 200);
        model.addAttribute("address", "gz");
        return "sucess";

    }


    @RequestMapping("get")
    public String getSession(ModelMap modelMap) {
        System.out.println(modelMap.get("name1"));
        System.out.println(modelMap.get("name2"));
        System.out.println(modelMap.get("num1"));
        System.out.println(modelMap.get("num2"));
        System.out.println(modelMap.get("address"));
        return "sucess";
    }

    @RequestMapping("delete")
    public String deleteSession(SessionStatus sessionStatus) {
        // 清空session中通过@SessionAttributes注解往session存放的所有的key
        sessionStatus.setComplete();
        return "sucess";
    }
}

交互 json 数据[应用]

注解说明

@RequestBody

作用:在处理器方法形参上使用,把请求的json格式数据,转换成java对象。

@ResponseBody

作用:在处理器方法返回值上使用,或者方法上使用。把响应的java对象,转换成json格式数据。

添加依赖

说明:springmvc默认,使用HttpMessageConverter消息转换器,进行json格式数据转换。需要加入jackson依赖包支持。

<!--引入jackson支持,实现json与java对象的互转-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>

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

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

使用示例

  1. js代码

    <script>
        $(function () {
            $("#but").click(function () {
                $.ajax({
                    type: "post",
                    url: "/responseJson",
                    data: '{"id":100,"name":"jack","money":100}',
                    dataType: "json",
                    contentType: "application/json;charset=utf-8",
                    success: function (json) {
                        alert("json=" + json + ";json.id=" + json.id + " json.name =" + json.name + "  json.money= " + json.money)
                    }
                })
            })
        })
    </script>
    

2、定义Account账户对象,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-InWXJ8Jy-1582268945628)(media/0b866fb1b48726e9ca8a19258a845ca6.png)]

3、实现控制器代码:

package com;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import po.Account;

@Controller
public class ResponseBodyController {

    @ResponseBody
    @RequestMapping("responseJson")
    public Account responseJson(@RequestBody Account account) {
        System.out.println("接受的数据是   " + account);
        account.setId(2);
        account.setName("小明");
        account.setMoney(999.99);
        return account;
    }
}

Restful 风格 URL与@PathVarible注解

概述

REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中,他是 HTTP规范的主要编写者之一。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。

REST其核心价值在于如何设计出符合 REST风格的网络接口。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

restful 的优点

它结构清晰、符合标准、易于理解、 扩展方便,所以正得到越来越多网站的采用。

restful 的特性

资源( Resources) : 网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一 资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的 URI就可以,因此 URI 即为每一个资源的独一无二的识别符。

表现层( Representation) : 把资源具体呈现出来的形式,叫做它的表现层 (Representation)。

比如,文本可以用 txt 格式表现,也可以用 HTML 格式、 XML 格式、 JSON格式表现,甚至可以采用二 进制格式。

状态转化( State Transfer) : 每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段, 让服务器端发生“状态转化” ( State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词: GET 、 POST 、PUT、DELETE。它们分别对应四种基本操作: GET 用来获取资源, POST 用来新建资源,PUT 用来更新资源, DELETE 用来删除资源。

restful 的示例:

/account/1 HTTP GET : 得到 id = 1 的 account

/account/1 HTTP DELETE: 删除 id = 1 的 account

/account/1 HTTP PUT: 更新 id = 1 的 account

/account HTTP POST: 新增 account

  • HTTP请求有几种方式? 共7种

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YfUT4Mss-1582268945629)(media/8dbbffe85ee902132d645d352db378d5.png)]

  • 我们的jsp、html,只支持get、post

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AYQwkLTO-1582268945629)(media/1540730089410.png)]

基于 HiddenHttpMethodFilter 的示例

介绍

作用:

由于浏览器 form 表单只支持 GET 与 POST 请求,而 DELETE、 PUT 等 method并不支持, Spring3.0添加了一个过滤器,可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法,使得支持GET、 POST、 PUT与 DELETE 请求。

过滤器:org.springframework.web.filter.HiddenHttpMethodFilter

使用方法:

第一步:在 web.xml 中配置该过滤器。

第二步:请求方式必须使用 post 请求。

第三步:按照要求提供_method 请求参数,该参数的取值就是我们需要的请求方式。

源码分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TqRluwHC-1582268945629)(media/07dc17f86be87c3f8ac2827555ed8434.png)]

示例

web.xml配置
  • 配置过滤器:HiddenHttpMethodFilter
<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>
页面
<!--隐藏域中指定提交方式-->
<form method="post" action="rest/100">
    <input type="submit" value="post">
</form>

<!--隐藏域中指定提交方式-->
<form method="post" action="http://localhost:8080/rest/200">
    <input type="hidden" name="_method" value="get">
    <input type="submit" value="get">
</form>
<!--隐藏域中指定提交方式-->
<form method="post" action="rest/300">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="delete">
</form>
<!--隐藏域中指定提交方式-->
<form method="post" action="rest/400">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="put">
</form>
控制器
package com;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
//@RequestMapping("rest")
public class RestFulController {

    @RequestMapping(value = "rest/{id}", method = RequestMethod.GET)
    public String testGet(@PathVariable("id") String num) {
        System.out.println("get方法id的值是:" + num);
        return "sucess";
    }
    
    @RequestMapping(value = "rest/{id}", method = RequestMethod.POST)
    public String testPost(@PathVariable("id") String num) {
        System.out.println("post方法id的值是:" + num);
        return "sucess";
    }

    // 只处理put请求
    // 如果是put请求,不能跳转要返回json格式
    @RequestMapping(value = "rest/{id}", method = RequestMethod.DELETE)
    //添加ResponseBody,就会自动返回json格式
    @ResponseBody
    public String testDetele(@PathVariable("id") String num) {
        System.out.println("delete方法id的值是:" + num);
        return "sucess";
    }

    // 只处理delete请求
    // 如果是delete请求,不能跳转要返回json格式
    @RequestMapping(value = "rest/{id}", method = RequestMethod.PUT)
    //添加ResponseBody,就会自动返回json格式
    @ResponseBody
    public String testPut(@PathVariable("id") String num) {
        System.out.println("put方法id的值是:" + num);
        return "[{\"id\":\"100\",\"name\":\"jack\"},{\"id\":\"100\",\"name\":\"jack\"}]";
    }
}

控制器方法的返回值[掌握]

返回值分类

返回String

默认会转发

@Controller
public class ModelController {
    @RequestMapping("model")
    public String model(Model model) {
        model.addAttribute("cn", "china");
        return "sucess";
    }

返回void

应用:

  1. 自己再方法内部通过servletApi返回结果

    举例:方法内部自己重定向、转发、返回json字符串

  2. 文件下载,此时返回void

 @RequestMapping("void")
    public void retunrVoid(HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.out.println("returnVoid");
        response.getWriter().write("returnVoid");
    }

返回ModelAndView

ModelAndView 是 SpringMVC为我们提供的一个对象,该对象也可以用作控制器方法的返回值。该对象中有两个方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6j6Rd4ZL-1582268945630)(media/76618dffbaff29a8896b1851cbacd840.png)]

java代码

 @RequestMapping("modelAndView")
    public ModelAndView returnModelAndView(){
        System.out.println("returnModelAndView");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("username","小明");
        modelAndView.setViewName("sucess");
        return modelAndView;
    }

前端代码:

<%--
  Created by IntelliJ IDEA.
  User: 22051
  Date: 2018/10/27
  Time: 21:10
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>sucess!!!</h1>
${requestScope.username}

</body>
</html>

转发和重定向

forward 转发

  • contrller 方法提供了一个 String 类型返回值之后,它需要在返回值里使用:forward:

  • 它相当于“ response.getRequestDispatcher(url).forward(…)”

  • 实现如下,

@RequestMapping("forward")
public String testForward(){
    System.out.println("执行转发");
    //转发时,路径要写斜杠,不然会找不到资源
    return "forward:/return/void";
}

redirect 重定向

  • contrller 方法提供了一个 String 类型返回值之后,它需要在返回值里使用:redirect:

  • 它相当于“ response.sendRedirect(url)” 。需要注意的是,如果是重定向到 jsp
    页面,则 jsp 页面不能写在 WEB-INF 目录中,否则无法找到。

  • 实现如下,

@RequestMapping("redirect")
public String testRedirect(){
    System.out.println("执行转发");
    //重定向时,路径要写斜杠,不然会找不到资源
    return "redirect:/return/void";
}

SpringMVC 实现文件上传[应用]

传统文件上传

简介

三要素

  1. form 表单的 enctype 取值必须是:multipart/form-data(默认值是:application/x-www-form-urlencoded)

    enctype:是表单请求正文的类型

  2. method 属性取值必须是 Post

  3. 提供一个文件选择域<input type=”file” />

借助第三方组件实现文件上传

使用 Commons-fileupload 组件实现文件上传,需要导入该组件相应的支撑 jar 包:Commons-fileupload 和commons-io。 commons-io 不属于文件上传组件的开发 jar文件,但 Commons-fileupload 组件从 1.1 版本开始,它工作时需要 commons-io包的支持。

添加依赖

<!--Apache提供的文件上传组件支持-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

文件上传完整实现

页面
<h6>测试上传文件1</h6>
<form action="/upload1" method="post" enctype="multipart/form-data">
    <input type="text" name="user"> <br>
    <input type="file" name="测试上传文件1"> <br>
    <input type="submit">
</form>
控制器
  @RequestMapping("upload1")
    public String loadFile1(HttpServletRequest request) throws Exception {
        // 1.通过ServletContext对象获取上传的目录地址
        String path = request.getSession().getServletContext().getRealPath("/upload");
        System.out.println(path);
        // 2. 创建创建的子目录,每一天产生一个目录
        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        // 3. 创建目录对象
        File file = new File(path,date);
        if (!file.exists()){
            file.mkdirs();
        }
        // 4. 处理文件上传
        // 4.1 创建FileItem的工厂
        FileItemFactory factory = new DiskFileItemFactory();
        // 4.2 创建文件上传核心工具类
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 4.3 把请求文件表单数据转换为FileItem的集合
        // FileItem表示表单的每一个元素,用对象封装
        List<FileItem> items = upload.parseRequest(request);
        // 4.4 遍历
        for(FileItem item : items){
            //判断
            if (item.isFormField()){
                // 表示是普通表单元素:<input type="text" name="username">
                System.out.println("输入的用户名:" + item.getString("UTF-8"));
            } else {
                // 文件元素:<input type="file" name="imgFile">
                // 文件上传
                // a. 获取文件名称
                String fileName = item.getName();
                // b. 处理文件名唯一
                fileName = UUID.randomUUID().toString().replaceAll("-","") + "_" + fileName;
                // c. 上传
                item.write(new File(file,fileName));
                // d. 删除文件上传产生的临时文件
                item.delete();
            }
        }
        return "sucess";
    }

SpringMVC文件上传(重点)

页面

<h6>测试上传文件2</h6>
<form action="/upload2" method="post" enctype="multipart/form-data">
    <input type="text" name="user"> <br>
    <input type="file" name="imgFile"> <br>
    <input type="submit">
</form>

控制器

  • springmvc框架为我们提供了一个对象MultipartFile,该对象可以作为控制器方法的参数。参数的名称必须和表单file元素的name属性取值一致

  • MultipartFile提供了transferTo(file)方法可以直接上传文件

  • 实现文件上传,

 /**
     * springmvc框架为我们提供了一个对象MultipartFile,该对象可以作为控制器方法的参数。参数的名称必须和表单file元素的name属性取值一致
     */
    @RequestMapping("upload2")
    public String loadFile2(HttpServletRequest request, MultipartFile imgFile) throws IOException {
        // 1.通过ServletContext对象获取上传的目录地址
        String path = request.getSession().getServletContext().getRealPath("/upload");
        // 2. 创建创建的子目录,每一天产生一个目录
        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        // 3. 创建目录对象
        File file = new File(path,date);
        if (!file.exists()){
            file.mkdirs();
        }
        // 4. 处理文件上传
        // 4.1 获取文件名,处理文件名唯一
        String fileName = imgFile.getOriginalFilename();
        fileName = UUID.randomUUID().toString().replaceAll("-","") + "_" + fileName;
        // 4.2 文件上传
        imgFile.transferTo(new File(file,fileName));
        return "sucess";
    }

配置

  • 配置文件上传解析器:CommonsMultipartResolver
<!--文件上传解析器(注意id是固定)-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <!--指定运行上传的文件最大值:10M(字节)-->
        <property name="maxUploadSize" value="10485760"/>
</bean>

注意:文件上传的解析器 id是固定的,不能起别的名称,否则无法实现请求参数的绑定。(不光是文件,其他字段也将无法绑定)

springmvc 跨服务器方式的文件上传(了解)

分服务器的目的

  • 在实际开发中,我们会有很多处理不同功能的服务器。

例如:

  • 应用服务器:负责部署我们的应用

  • 数据库服务器:运行我们的数据库

  • 缓存和消息服务器:负责处理大并发访问的缓存和消息

  • 文件服务器:负责存储用户上传文件的服务器。(注意:此处说的不是服务器集群)

分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MY97wMOP-1582268945630)(media/8c021524913708cfbafd5eb33ebffcef.png)]

文件服务器的部署

  • (1) 先解压一个tomcat服务器,这里用的是tomcat9

(什么版本都没有关系:如tomcat6、tomcat7、tomcat8、tomcat9)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NuTytNNT-1582268945630)(media/15854157e239085bc481611f0e3224d8.png)]

  • (2) 修改web.xml配置文件

如:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OrVbv0J-1582268945631)(media/a1839b0310e4a9476ec018b888e777ec.png)]

修改内容:

默认 readonly 为 true,当 readonly 设置为 false时,可以通过一些方式进行文件操控。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tfqpPLr-1582268945631)(media/2688d8dbbaea81b7c74be31aa14767f0.png)]

  • (3) 创建一个文件系统,保存所有文件(文件上传到这里)
  1. 在tomcat的webapps目录下新建fileSystem文件系统

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zBsZJtcO-1582268945632)(media/6fd6b122d748e48a2061ff9c9262c31f.png)]

  1. 在fileSystem中新建upload目录、indexjsp测试文件即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GxvMirqE-1582268945632)(media/f0d0c4d1abd98b06e5942a8d0070f291.png)]

  1. 在conf/server.xml中修改tomcat端口

tomcat服务端口默认8080,修改为:6080

  1. 启动tomcat,访问index.jsp

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RmnqRjrs-1582268945632)(media/c5c82c082a8e79a396f28c1d6256a044.png)]

这里只是测试下,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ps7F06xr-1582268945632)(media/b2187ac241a0d081616fd649e8587b95.png)]

导入 jersey 的坐标

<!--引入jersey支持包实现应用系统与文件系统的通讯访问-->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-core</artifactId>
            <version>1.18.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.18.1</version>
        </dependency>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJUFE14q-1582268945633)(media/df950fc84a9e46f1a4dc8e0f778b6e5e.png)]

前端页面

<h6>测试上传文件3</h6>

<form action="/upload3" method="post" enctype="multipart/form-data">
    <input type="text" name="xx">
    <input type="file" name="imgFileXXX">
    <input type="submit">
</form>

编写控制器实现上传图片

 @RequestMapping("upload3")
    public String loadFile3(HttpServletRequest request, MultipartFile imgFileXXX) throws IOException {
        //创建jersey包中提供的client对象
        Client client = new Client();

        //使用client和文件服务器建立联系
        //上传地址:http://localhost:6080/fileSystem/upload/文件
        String uploadPath = "http://localhost:6080/fileSystem/upload/" + imgFileXXX.getOriginalFilename();
        WebResource resource = client.resource(uploadPath);

        //把web资源对象写到文件服务器
        resource.put(String.class, imgFileXXX.getBytes());

        return "sucess";
    }

bean.xml配置文件上传解析器

<!--文件上传解析器(注意id是固定)-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--指定运行上传的文件最大值:10M(字节)-->
        <property name="maxUploadSize" value="10485760"/>
    </bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值