SpringMVC

SpringMVC

ssm :mybaits + Spring + SpringMVC MVC三层架构

什么是MVC ?

  • MVC式模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
    • Controller(控制器):
      1. 获取表单数据;
      2. 调用业务逻辑;
      3. 转向指定的页面
    • Model(模型):
      1. 业务逻辑;
      2. 保存数据的状态;
    • View(视图):
      1. 显示页面
  • 是将业务逻辑、数据、显示分离的方法来组织代码。
  • MVC主要作用是降低了视图于业务逻辑间的双向耦合
  • MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。

SprngMVC是Spring Framework的一部分,是基于java实现MVC的轻量级web框架。

Sprng MVC的特点:

  1. 轻量级,简单易学
  2. 高效,基于请求响应的MVC框架
  3. 于Spring兼容性好,无缝结合
  4. 约定优于配置
  5. 功能强大:RESful、数据验证、格式化、本地化、主题等
  6. 简介灵活

最总要一点还是使用的人多,使用的公司多。

中心控制器

​ Spring的web框架围绕DispatcherServlet设计。DispatcherServlet的作用是将请求分发到不同的处理器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UujmaON6-1652586542896)(C:/Users/hasee/AppData/Roaming/Typora/typora-user-images/image-20201025205411605.png)]

理解性的画图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rdy2ZOLZ-1652586542900)(C:/Users/hasee/AppData/Roaming/Typora/typora-user-images/image-20201025212018409.png)]

简要分析流程:

  1. DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心,用户发出请求,DispatcherServlet接受请求并拦截请求。

    • 我么假设请求的url为:http://localhost:8080/SpringMVC/hello

    • 如上url拆分为三部分:

      • http://localhost:8080服务器域名
      • SpringMVC部署在服务器上的web站点
      • hello表示控制前

      通过分析,如上url表示:请求位于服务器http://localhost:8080 上的SpringMVC站点的hello控制器。

  2. HandlerMapping为处理器映射。DiapatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找handler。

  3. HandlerExecution表示具体的handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行handler。

  6. Handler让具体的Contorller执行。

  7. Contorller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

  8. HandlerAdapter将视图逻辑名和模型传递给DispatcherServlet。

  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的视图名。

  10. 视图解析器将解析的视图名传递给DispatcherServlet。

  11. DispatcherServlet根据视图解析器解析的试图结果,调用具体的视图。

  12. 最终视图呈现给用户。

HelloSpringMVC配置版

  1. 新建一个module,添加web的支持!

  2. 确定导入SpringMVC依赖

  3. 配置web.xml,注册DispatcherServlet

    <?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">
    
        <!--1.注册DispatcherServlet-->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--关联一个DispatcherServlet要绑定的springmvc的配置文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-servlet.xml</param-value>
            </init-param>
            <!--启动级别-1-->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--/ 配置所有的求情:(不包括.jsp)-->
        <!--/* 配置所有的求情:(包括.jsp)-->
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  4. 配置spring.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--处理器映射器-->
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
        
        <!--处理器适配器-->
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
        
        <!--视图解析器:DispatcerServlet给他的ModelAndView-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!--Handler-->
        <bean class="com.dragon.controller.HelloController" id="/hello"/>
    
    </beans>
    
  5. Controller类

    public class HelloController implements Controller {
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            //ModelAndView 模型和视图
            ModelAndView mv = new ModelAndView();
    
            //封装对象,放在ModelAndView中,Model
            mv.addObject("msg", "HelloSpringMVC");
    
            //封装要跳转的视图,放在ModelAndView中
            mv.setViewName("hello");//:/WEB-INF/jsp/hello.jsp
    
            return mv;
        }
    }
    

使用注解开发SpringMVC

首先和上边的一样

  1. 创建web项目,导入jar包,确保artifacts里边有所有的包,编写web.xml,注册DispatcherServlet

    <?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">
    
        <!--1.注册DispatcherServlet-->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--关联一个DispatcherServlet要绑定的springmvc的配置文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-servlet.xml</param-value>
            </init-param>
            <!--启动级别-1-->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--/ 配置所有的求情:(不包括.jsp)-->
        <!--/* 配置所有的求情:(包括.jsp)-->
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    
  2. 编写springmvc-servlet.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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--处理器映射器-->
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
        <!--处理器适配器-->
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
        <!--视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!--BeanNameUrlHandlerMapping类去处理Controller类-->
        <bean class="com.dragon.controller.HelloController" id="/hello"/>
    </beans>
    
  3. 创建Controller

    //@Controller的类会自动添加到Spring的上下文中
    @Controller
    public class HelloController {
    
        //映射访问路径
        @RequestMapping("/hello")
        public String hello(Model model){
            //封装数据
            model.addAttribute("msg", "hello,springMVC");
    
            //视图解析器自动处理
            return "test";
        }
    }
    
    • @Controller是为了让spring IOC容器初始化时自动扫描到;
    • @RequestMapping是为了映射请求路径,这里因为类于方法上都有映射,所以访问时应该是“/hello”;
    • 方法中声明model类型的参数是为了把Action中的数据带到视图中;
    • 方法返回的结果是视图的名称test,加上配置文件中的前后缀编程/WEB-INF/jsp/test.jsp;
  4. 创建视图

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

小结:

使用SpringMVC必须配置的三大件:

  • 处理器映射器、处理器适配器、视图解析器

通常,我们只需要手动配置视图解析器,而处理器映射器处理器适配器只需要开启注册驱动即可,省去了大段的xml配置

控制器Controller

  • 控制器负责提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
  • 控制器负责解析用户的请求并将其转换为一个模型(Model)。
  • 在Spring MVC中一个控制器类可以包含多个方法。
  • 在Spring MVC中,对于Controller的配置方法由很多。

实现Controller接口

Controller是一个接口,在org.springframeword.web.sevlet.mvc包下,接口中只有一个方法:

public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView modelAndView = new ModelAndView();

        //将业务代码的返回值封装到ModelAndView,然后返回给视图
        String result = "SpringMVC~~~~~~~";
        modelAndView.addObject("msg", result);

        //视图
        modelAndView.setViewName("test");

        return modelAndView;
    }
}

使用注解@Controller(推荐使用)

  • @Controller注解类型用于声明Spring类的实例是一个控制器;

  • Spring可以使用扫描机制来找到应用程序中所有基于注解的控制器类,为了保证Spring能找到你的控制器,需要在配置文件中声明组件扫描:

        <!--自动扫描包,让指定包下的注解生效,由IOC统一管理-->
        <context:component-scan base-package="com.dragon.controller"/>
    
  • 增加一个Controller类,使用注解实现:

    //@Controller的类会自动添加到Spring的上下文中
    @Controller
    public class HelloController {
    
        //映射访问路径
        @RequestMapping("/hello")
        public String hello(Model model){
            //封装数据
            model.addAttribute("msg", "hello,springMVC");
    
            //视图解析器自动处理
            return "hello";
        }
    
    

@RequestMapping

  • @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

  • 只注解在方法上

    @Controller
    public class HelloController {
    
        @RequestMapping("/h1")
        public String hello(){
            return "hello";
        }
    
    

    访问路径为:http://localhost:8080/项目名/h1

  • 同时注解方法和类

    @Controller
    @RequestMapping("/admin")
    public class HelloController {
    
        @RequestMapping("/h1")
        public String hello(){
            return "hello";
        }
    
    

    访问路径为:http://localhost:8080/项目名/admin/h1

@ResponseBody

标注在方法上,表示不会走视图,直接返回前端字符串

Restful 风格

概念

​ restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,基于这个风格设计的软件可以更简介,更有层次,更易于实现缓存机制。

功能

  • 资源:互联网所有的事务都可以被抽象为资源。
  • 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
  • 分别对应 添加、删除、修改、查询。

传统方式操作资源:通过不同的参数来实现不同的效果!方法单一,post和get

  • 例子:问号传参

使用Restful操作资源:可以 通过不同的请求方式来实现不用的效果!如下:请求地址一样,但是功能可以不同:

  • http://127.0.01/item 查询,GET
  • http://127.0.01/item 新增,POST
  • http://127.0.01/item 更新,PUT
  • http://127.0.01/item 删除,DELETE

测试:

  1. 新建一个类RestfulController

  2. 在Spring MVC中可以使用**@PathVariable**注解,让方法参数的只对应绑定到一个URL模板变量上。

    @Controller
    public class RestfulController {
        @RequestMapping("h1/{a1}/{a2}")
        public String test1(@PathVariable int a1,@PathVariable int a2, Model model) {
            model.addAttribute("msg","结果:"+a1+a2);
            return "hello";
        }
    }
    

使用method属性指定请求类型

使用约束请求的类型,可以收窄请求范围。指定请求的类型如:POST、DELETE、PUT、GET

增加一个方法

@Controller
public class HelloController {

    //映射访问路径,必须是post请求
    @RequestMapping(value = "/h1",method = {RequestMethod.POST})
    public String hello(){
        return "hello";
    }

对应的jap页面

<form action="/h1" method="post">
    <input type="text" name="name"/>
    <input type="submit"/>
</form>

浏览器默认提交是get

处理乱码

Spring 自带过滤器,在org.springframework.web.filter.CharacterEncodingFilter包下

    <filter>
        <filter-name>encoding</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>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

JSON

什么是json?

  • JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式,目前使用特别广泛。
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • 简介和清晰的层次结构使得JSON成为理想的数据交换语言。
  • 易于阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

JSON键值对是用来保存JavaScript对象的一种方式,和JavaScript对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号“”包裹,使用冒号:分隔,然后紧接着值:

{"name":"renbo"}
{"age":"3"}

编写一个javaScript对象

  <script type="text/javascript">
    var user={
      name: "任博",
      age:3
    };
  </script>

将js转换为json对象:

<script type="text/javascript">var json = JSON.stringify(user);</script>

将json转换为js对象:

<script type="text/javascript">var a1 = JSON.parse(json);</script>

Controller返回JSON数据

jackson

  • jackson应该是目前比较好的json解析工具了;

  • 当然工具不止这一个,比如还有阿里巴巴的fastjson等等;

  • 使用它,我们需要带入它的jar包;

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.11.3</version>
    </dependency>
    
  1. 使用jackson包下的ObjectMapper类
  2. 把创建好的对象放入ObjectMapper类中的writeValueAsString方法中进行转换
  3. 测试;
@Controller
public class UserController {
    @ResponseBody
    @RequestMapping("/j1")
    public String json1() throws JsonProcessingException {

        ObjectMapper mapper = new ObjectMapper();
        User user = new User("任博", 1);
        String s = mapper.writeValueAsString(user);
        return s;
    }
}

阿里巴巴的fastjson

  • 导入依赖
  • 测试:
JSON.toJSONString(Object);             //java对象 转换 json字符串
JSON.parseObject(String,Object.class); //json字符串 转换 java对象
JSON.toJSON(Object);                   //java对象 转换 json对象
JSON.toJavaObject(JsonObject,Object.claa);  //json对象 转换 java对象

JSON乱码问题配置

我们可以在springmvc的配置文件上添加一段消息StringHttpMessageConverter转换配置!

    <!--Json乱码问题配置-->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="utf-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

Ajax技术

简介:

  • AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

  • AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

  • Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技 术。

  • 在 2005 年,Google 通过其 Google Suggest 使 AJAX 变得流行起来。Google Suggest能够自动帮 你完成搜索单词。

  • Google Suggest 使用 AJAX 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时, JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。

  • 就和国内百度的搜索框一样:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8LXaCuqI-1652586542904)(C:/Users/hasee/AppData/Roaming/Typora/typora-user-images/image-20201101111251915.png)]

  • 传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网 页。

  • 使用ajax技术的网页,通过在后台服务器进行少量的数据交换,就可以实现异步局部更新。

  • 使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。

Ajax代码

  • url:请求后台路径
  • data:前端携带返回给后台参数
  • success:后端返回的东西
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
    <script src="${pageContext.request.contextPath}/statics/js/jquery-3.5.1.js"></script>

    <script>
      function a() {
        $.post({
          url: "${pageContext.request.contextPath}/a1",
          data:{"name":$("#username").val()},
          success:function (data) {
            alert(data);
          }
        })
      }
    </script>

  </head>
  <body>
  <%--失去焦点的时候,发起一个请求(携带信息)到后台--%>
  用户名<input type="text" id="username" οnblur="a()">
  </body>
</html>

简化,ajax参数可以直接卸载括号里

    <script>
      function a() {
        $.post("${pageContext.request.contextPath}/a1",{"name":$("#username").val()},function (data){
          alert(data)
        })
      }
    </script>

返回前端json对象

<script type="text/javascript" src="${pageContext.request.contextPath}/statics/js/jquery-3.5.1.js"></script>

<script>
    $(function () {
        $("#btn").click(function () {
            $.post("${pageContext.request.contextPath}/a2",function (data) {
                let html = "";
                for (let i = 0; i < data.length; i++) {
                    html += "<tr>" +
                        "<td>" + data[i].name + "</td>" +
                        "<td>" + data[i].age + "</td>" +
                        "<td>" + data[i].sex + "</td>" +
                        "<td>" + data[i].hobby + "</td>" +
                        "</tr>";
                }
                $("#content").html(html);
            })
        })
    })
</script>

<body>
<input type="button" value="加载数据" id="btn">
<table>
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>性别</td>
    </tr>
    <tbody id="content">
        <%--数据:后台--%>
    </tbody>
</table>

注册提示效果

我们再测试一个小Demo,思考一下我们平时注册时候,输入框后面的实时提示怎么做到的;如何优化 我们写一个Controller

    @RequestMapping("/a3")
    public String ajax3(String name,String pwd){
        String msg = "";
        //模拟数据库中存在数据
        if (name!=null){
            if ("admin".equals(name)){
                msg = "OK";
            }else {
                msg = "用户名输入错误";
            }
        }
        if (pwd!=null){
            if ("123456".equals(pwd)){
                msg = "OK";
            }else {
                msg = "密码输入有误";
            }
        }
        return msg; //由于@RestController注解,将msg转成json格式返回
    }
<head>
  <title>ajax</title>
  <script src="${pageContext.request.contextPath}/statics/js/jquery3.1.1.min.js"></script>
  <script>
    function a1(){
      $.post({
        url:"${pageContext.request.contextPath}/a3",
        data:{'name':$("#name").val()},
        success:function (data) {
          if (data.toString()=='OK'){
            $("#userInfo").css("color","green");
          }else {
            $("#userInfo").css("color","red");
          }
          $("#userInfo").html(data);
        }
      });
    }
    function a2(){
      $.post({
        url:"${pageContext.request.contextPath}/a3",
        data:{'pwd':$("#pwd").val()},
        success:function (data) {
          if (data.toString()=='OK'){
            $("#pwdInfo").css("color","green");
          }else {
            $("#pwdInfo").css("color","red");
          }
          $("#pwdInfo").html(data);
        }
      });
    }
  </script>
</head>
<body>
<p>
  用户名:<input type="text" id="name" οnblur="a1()"/>
  <span id="userInfo"></span>
</p>
<p>
  密码:<input type="text" id="pwd" οnblur="a2()"/>
  <span id="pwdInfo"></span>
</p>
</body>
</html>

拦截器

SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开 发者可以自己定义一些拦截器来实现特定的功能。

过滤器与拦截器的区别:拦截器是AOP思想的具体应用。

过滤器:

  • servlet规范中的一部分,任何java web工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器:

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

springmvc配置拦截器

    <!--拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--包括这个请求下面的所有请求-->
            <mvc:mapping path="/**"/>
            <bean class="com.dragon.config.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

实现 HandlerInterceptor 接口。

public class MyInterceptor implements HandlerInterceptor {
    //return true:执行下一个拦截器,放行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
    }
}

文件上传

准备工作

  • 文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上 下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring 的文件上传功能,则需要在上下文中配置MultipartResolver。
  • 前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为 multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务 器;

对表单中的 enctype 属性做个详细的说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编 码方式的表单会将表单域中的值处理成 URL 编码方式。
  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文 件域指定文件的内容也封装到请求参数中,不会对字符编码。
  • text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单 发送邮件。

导入依赖

    <dependencies>
        <!--文件上传-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>

spring配置bean:multipartResolver

【注意!!!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这 里栽过坑,教训!】

    <!--文件上传配置-->
    <bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
        <!--请求的编码格式,必须和jsp的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1-->
        <property name="defaultEncoding" value="utf-8"/>
        <!--上传文件大小上限,单位为字节(10485760=10M)-->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>

CommonsMultipartFile 的 常用方法:

  • String getOriginalFilename():获取上传文件的原名
  • InputStream getInputStream():获取文件流
  • void transferTo(File dest):将上传文件保存到一个目录文件中

Controller

@Controller
public class FileController {
    //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象
    //批量上传CommonsMultipartFile则为数组即可
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile
                                     file , HttpServletRequest request) throws IOException {
        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();
        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);
        //上传路径保存设置
        String path =
                request.getServletContext().getRealPath("/upload");
        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);
        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new
                File(realPath,uploadFileName)); //文件输出流
        //读取写出
        int len=0;
        byte[] buffer = new byte[1024];
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }

采用file.Transto 来保存上传的文件

Controller

    /*
     * 采用file.Transto 来保存上传的文件
     */
    @RequestMapping("/upload2")
    public String fileUpload2(@RequestParam("file") CommonsMultipartFile
                                      file, HttpServletRequest request) throws IOException {
        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        //上传文件地址
        System.out.println("上传文件保存地址:"+realPath);
        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(new File(realPath +"/"+
                file.getOriginalFilename()));
        return "redirect:/index.jsp";
    }

文件下载

文件下载步骤:

  1. 设置 response 响应头
  2. 读取文件 – InputStream
  3. 写出文件 – OutputStream
  4. 执行操作
  5. 关闭流 (先开后关)

代码实现:

@RequestMapping(value="/download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String path = request.getServletContext().getRealPath("/upload");
        String fileName = "基础语法.jpg";
        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer
        response.setCharacterEncoding("UTF-8"); //字符编码
        response.setContentType("multipart/form-data"); //二进制传输数据
        //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));
        File file = new File(path,fileName);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();
        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return null;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值