SpringMVC

目录

概念:

SpringMVC的参数绑

目录

概念:

搭建SpringMVC的框架结构

SpringMVC的参数绑定

SpringMVC 重要点:

SpringMVC注解

1)RequestParam

2)RequestBody

3)PathVaribale

4)RequestHeader(使用较少,了解)

5)CookieValue(使用较少,了解)

6)ModelAttribute(重要的)

7)SessionAttributes

SpringMVC返回值类型

1)返回字符串(常用)

2)返回void(在框架不提倡使用)

3)返回ModelAndView(类)

框架中可以实现重定向和转发方式

响应数据类型

json(重要),xml

前提:需要导入新的坐标依赖

注意:前端控制器会进行静态资源的拦截

3)编写jquery代码, 添加对应的ajax请求

SpringMVC文件上传

概述

新建工程:(内容知识点全面)

SpringMVC拦截器

概述:

拦截器和过滤器进行比较?(面试概率不是很高)

拦截器操作步骤(一个拦截器):

多个拦截器

框架下异常处理

概述

实现步骤:


SpringMVC 重要点:

SpringMVC注解

1)RequestParam

2)RequestBody

3)PathVaribale

4)RequestHeader(使用较少,了解)

5)CookieValue(使用较少,了解)

6)ModelAttribute(重要的)

7)SessionAttributes

SpringMVC返回值类型

1)返回字符串(常用)

2)返回void(在框架不提倡使用)

3)返回ModelAndView(类)

框架中可以实现重定向和转发方式

响应数据类型

json(重要),xml

前提:需要导入新的坐标依赖

注意:前端控制器会进行静态资源的拦截

3)编写jquery代码, 添加对应的ajax请求

SpringMVC文件上传

概述

新建工程:(内容知识点全面)

SpringMVC拦截器

概述:

拦截器和过滤器进行比较?(面试概率不是很高)

拦截器操作步骤(一个拦截器):

多个拦截器

框架下异常处理

概述

实现步骤:


SpringMVC的参数绑定

SpringMVC 重要点:

SpringMVC注解

1)RequestParam

2)RequestBody

3)PathVaribale

4)RequestHeader(使用较少,了解)

5)CookieValue(使用较少,了解)

6)ModelAttribute(重要的)

7)SessionAttributes

SpringMVC返回值类型

1)返回字符串(常用)

2)返回void(在框架不提倡使用)

3)返回ModelAndView(类)

框架中可以实现重定向和转发方式

响应数据类型

json(重要),xml

前提:需要导入新的坐标依赖

注意:前端控制器会进行静态资源的拦截

3)编写jquery代码, 添加对应的ajax请求

SpringMVC文件上传

概述

新建工程:(内容知识点全面)

SpringMVC拦截器

概述:

拦截器和过滤器进行比较?(面试概率不是很高)

拦截器操作步骤(一个拦截器):

多个拦截器

框架下异常处理

概述

实现步骤:


kuang:

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <!--EL表达式的标签支持-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

springMVC乱码过滤

配置web.xml

 / 过滤的不是所有的请求,像页面的jsp请求不过滤,需要修改路径 /*

 配置位置

json

导入jackson jar包

前后台分离 在使用json格式的乱码问题 固定写法

springmvc框架给我们提供的, 

使用json格式,1 导入jar, 2 解决json乱码问题 3 使用ObjectMapper对象转换成json,

@RestController

如果使用@RestController 那么返回的数据格式只能是json格式,视图解析器是不会走的,@RequestBody也是这个作用,当用了@RestController时就可以不用。

返回日期方式

或者也可以使用SimpleDateFormat方法

FastJson

简单

 

技术点

概念:

        springMVC框架技术,把spring和mybatis技术结合到视图层。

        基于MVC结构,请求驱动类型的轻量级web框架,属于spring框架的后续设计

        它有很多的控制器,不需要实现任何接口,同时支持RESTFUL编程风格。

        resultful编程风格:我们用的get方式提交  "?username=haha&password=123456"的形式

        就是resultful编程风格。

SpringMVC 控制器

1、前端控制器  在web.xml中配置,作用是客户端和服务器的交互,其实就是Javaweb中的

      servlet。

2、请求到处理器映射(控制类)  通过注解配置@Controller 和@RequestMapping(path =

      "/hello") 实现在页面中请求到处理器处理请求的映射。

3、视图解析器  解析处理器中return "success",通过视图解析器解析为jsp文件这个jsp文件的

     名字要跟return返回的字符串一样才能被识别到,响应给浏览器。

    MVC中页面不是通过跳转完成的,不像javaWeb,是通过代码中的返回值,视图解析器会

    把返回值解析成jsp页面用户显示。

4、处理器或者页面控制器

5、验证器

6、命令对象

7、表单对象

搭建SpringMVC的框架结构

 

解决maven项目创建过慢的问题

标记为功能目录

1、添加依赖坐标

1)<maven.compiler.target>1.8</maven.compiler.target>
注意选择与我们使用的jdk版本要一致

配置servlet和jsp是因为servlet和jsp在springMVC框架中是为了我们编写代码时用的,而运行时用的是Tomcat上的servlet和jsp。所以需要设置作用域使只在编译时有效。

scope 作用域: provided使编译器有效。

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



2) pom.xml坐标依赖
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <!-- 版本锁定 -->
    <spring.version>5.0.2.RELEASE</spring.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
      </dependency>

      <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
          <scope>provided</scope>
      </dependency>

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

  </dependencies>

2、配置前端控制器web.xml

它在org.springframework…….DispatcherServlet类中通过map映射指明只要在 / 路径下就能找到前端控制器,并通过初始化参数让程序在加载web.xml前端控制器同时也能加载springMVC.xml配置文件。

<!--配置前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

3、创建SpringMVC配置文件

<!--添加注解扫描-->
    <context:component-scan base-package="com.neuedu"></context:component-scan>

配置tomcat服务器

小知识:建工程自带的index.jsp里面是没有设置字符集的,我们不想写可以把工程带的删掉,自己在创建一个jsp文件就自动带基础的配置了

添加约束

配置开启SpringMVC的注解

狂的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.quxingtao.controller"/>

    <mvc:default-servlet-handler/><!--过滤静态资源 CSS,HTML等-->

    <mvc:annotation-driven/><!--配置 HeadlerMapping和HandlerApapter两个实例-->

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

</beans> 

 控制器

 

 

4、控制器类实现

创建控制器类

@Controller代表这是一个控制器类,否则通过IOC容器创建对象

在访问页面发送请求时通过@RequestMapping注解在页面映射路径找到这个方法。

配置标签

<load-on-startup>1</load-on-startup>
这个标签目的是启动servlet就先加载init-parm文件,会先扫描sprinMVC中的注解的信息。

5、配置视图解析器:

视图解析器其实是官方封装好的类,我们只需要把视图解析器的对象放在ico容器,

name = “prefix”叫做前缀,说明要指向的路径value = “”

value = “/pages/” 

告诉视图解析器要解析路径位置,视图解析器便会拿我们在控制器类中return返回的字符串去找对应名字的jsp文件进行解析显示。

 / 代表web资源的根目录

name="suffix" value=".jsp"

给解析器指明路径下找的文件是  .jsp格式的文件

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

然后如下图所示运行就可以在页面中查看解析结果

SpringMVC执行流程 (面试)

1、web工程就需要启动Tomcat服务器,启动后自动加载我们以下配置的文件

     在web.xml中配置一些信息

     1)DispatcherServlet 创建了一个对象 叫做前端控制器(控制请求信息)

           前端通过它实现对接、获取,拿到获取的数据往后面给下一步,

     2)在它的内部配置了一个信息(classpath:springMVC.xml),目的是加载xml配置文件。

     3)加载完配置文件后到springMVC.xml文件中加载,

     4)扫描到注解@Controller修饰的HelloController类文件(控制器),这时

           HelloControlle 对象被创建。

2、浏览器要访问服务器资源,发送请求,服务器处理请求信息

    1)请求首先要找控制它对应的控制器,那就是HelloController控制器类,

    2)控制器类中有多个方法,具体哪个方法控制要看请求的路径和映射路径要一致,

    3)处理方法中要处理具体的请求信息(调用Spring(下一层)进行业务逻辑处理),并且返

        回字串,对字符串进行视图解析找到对应的jsp文件。

3、响应

     通过视图解析的jsp文件,响应给客户端浏览器

在代码运行角度看控制器的作用:

客户端点击超链接发起访问,直接访问到web.xml中配置的前端控制器DispatcherServlet(起到指挥作用),控制器再指挥到注解对应的控制类处理,通过控制类找到springMVC.xml中的视图解析器,通过视图解析器解析成jsp文件(success.jsp)再通过控制器回到客户端。

@RequestMapping注解

作用:用于建立页面中请求的地址(URL路径)和处理请求(控制器类)的方法实现对应的映射连接。

作用的位置:

1、类上可使用

表示请求的url是第一级访问目录,如果该位置上不写url,那么相当于web应用的根目录 /。

2、方法上可使用

如果有类上使用的形式,那么方法上是表示第二级目录。

属性:path =”目录”

属性:value 用于指定请求的url,和path作用一样

属性:method 用于请求方式  get post

属性:params 用于指定限制请求参数的条件  支持一些简单的表达式 

           要求请求参数有key和value映射关系。

属性:headers:用于指定限制请求消息头的条件

     

相当于请求过来的信息要有”haha”才会识别,没有就不识别

SpringMVC的参数绑定

作用:为页面提供了一种方式,可以在Java程序中(后台)获取对应的页面表单数据信息进行操作,如自动封装成对象。

绑定机制:(要求)

1)提交的数据(表单) 必须遵循键值对的形式 key=value                     

username=haha&password=123456

2)提交的表单数据,作为控制器类方法中的参数进行绑定。

3)要求提交的表单name属性和方法参数的名称是相同的。

绑定参数支持数据类型:

1)基本数据类型和String类型

   

@RequestMapping("/testParam")

    public String testParam(String username){

        System.out.println("用户名:" + username);

        return "success";

    }

<a href="/param/testParam?username=haha">请求参数绑定——用户名</a>

2)实体类型(JavaBean类型)

1.依然是表单中name属性和参数名字一致

2.如果一个实体类中包含其他的引用类型,那么表单的name要写成:对象.属性


   

如果一个实体类中包含其他的引用类型(一对一),那么表单的name要写成:对象.属性

在上一个例子中添加引用类型演示

    <%--一定是为了封装实体类对象--%>

    <form action="/param/saveAccount" method="post">

        姓名:<input type="text" name="username"><br>

        密码:<input type="text" name="password"><br>

        金额:<input type="text" name="money"><br>



        用户姓名:<input type="text" name="user.uname"><br>

        用户年龄:<input type="text" name="user.age"><br>

        <input type="submit" value="提交">

    </form>

3)集合类型(List Set Map)

list[0].属性

        用户姓名:<input type="text" name="list[0].uname"><br>

        用户年龄:<input type="text" name="list[0].age"><br>



        用户姓名:<input type="text" name="map['one'].uname"><br>

        用户年龄:<input type="text" name="map['one'].age"><br>

解决中文乱码问题

设置过滤器 Spring提供的 

配置需要在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>

以上操作等价于我们之前学JavaWeb的表单提交(getParameter)

SpringMVC 重要点:

1、参数绑定(页面数据和具体的控制器的处理方法实现对应关系)(重点)

2、注解(重点) 使用注解比较多

3、返回值类型  返回值需要通过视图解析器成jsp还需要带一些不同的数据类型显示。可通过注解去使用(重点)

4、SpringMVC上传文件

5、拦截器

SpringMVC注解

五个掌握。两个了解

前提:

开始SpringMVC的注解扫描

    <!--为了我们能使用SpringMVC的注解-->

    <mvc:annotation-driven></mvc:annotation-driven>

1)RequestParam

作用:是将请求中页面指定名称的参数给控制器中的方法的形参赋值

属性:

name : 请求参数中的名称  页面中name

value 与name的作用一样

required 请求参数中是否必须提供此参数,默认值是true表示必须提供

(了解,每一个注解都有这个属性)

2)RequestBody

(在异步通讯中使用 等同JavaWeb中的ajax技术交互时使用)

作用:用于获取请求体内容(表单),得到的格式是key=value结构的数据

注意:get方式不适用, username=haha&password=123

所以只能使用post请求方式

3)PathVaribale

作用:针对用于参数绑定url中的占位符,例如请求url中 /xxx/{id}

{id} 我们可以给任意的值 叫做{id}占位符 在书写过程直接写值就可以,只是值可以变化

restful风格  这是springMVC支持restful风格的一个重要标志

使用场景:页面访问时可以顺便把值带到控制器类中,并给到类中的参数.

4)RequestHeader(使用较少,了解)

作用:获取请求中的消息头(比如获取cookie中的JSESSIONID)

5)CookieValue(使用较少,了解)

作用:将指定cookie名称的值传入控制器类中方法参数

属性:value和name 指定cookie的名称

6)ModelAttribute(重要的)

用于修饰方法和参数

1) 修饰方法,表示当前方法会在控制器的方法执行之前,先执行。

  比如说在控制器类需要处理的方法之前,先执行此注解修饰的方法

  可以有返回值也可以没有

2) 修饰参数 获取指定的数据给参数赋值

应用场景:

场景:当页面数据提交不是完整的实体类数据时或者遗漏,放入数据库可能会影响操作

       为了保证后续操作,可以使用数据库原有属性,利用ModelAttribute注解提前把遗漏数据填充 

       进实体类中去封装,在让控制类去处理信息。

实例:编辑一个用户时,用户有一个创建信息字段,该字段的值是不允许修改的,在提交表单数据时肯定没有该字段的内容,一旦更新时候会将该字段的内容设置为null,这个时候可以用该注解解决

7)SessionAttributes

该注解声明共享数据,由ModelMap的get方法取出。

用于多次执行控制器方法间的参数共享 实际来说就是Javaweb中的作用域

利用SessionAttributes将msg=哈哈 存入到session域中

本质:将存入request域对象中的数据,存入session域对象

使用注解@SessionAttributes

清除session中的共享数据

SpringMVC返回值类型

三种方法都可以实现页面的跳转

1)返回字符串(常用)

返回字符串实现找到对应的jsp文件(通过视图解析器实现的)

    /**

     * 返回字符串

     * */

    @RequestMapping("/testString")

    public String testString(Model model){

        //调用service层 处理逻辑,通过service实现调用持久层操作数据库

        //模拟数据的操作

        User user = new User();

        user.setUname("哈哈");

        user.setAge(20);

        model.addAttribute("user", user);

        return "success";

    }

使用视图解析器需要在springMVC.xml中配置

2)返回void(在框架不提倡使用)

    /**

     * 返回值是void  不是我们提倡在框架中使用的

     * 操作的时候是和我们之前JavaWeb中的servlet技术操作是一样的

     * */

    @RequestMapping("/testVoid")

    public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //请求转发

        request.getRequestDispatcher("/pages/success.jsp").forward(request,response);



        //重定向

        response.sendRedirect(request.getContextPath()+"/index.jsp");

    }

3)返回ModelAndView(类)

类中的方法有addObject(“”,xxx) 声明到域对象中,

mv.setViewName("success");  跳转到哪个页面,在页面中EL表达式取出${requestScope.xxx}

是SpringMVC固定提供的一个对象(可以作为控制器方法的返回值)

也可以存到域对象中

  @RequestMapping("/testModelAndView")

    public ModelAndView testModelAndView(){

        //创建ModelAndView对象

        ModelAndView mv = new ModelAndView();

        //模拟数据的操作

        User user = new User();

        user.setUname("哈哈");

        user.setAge(20);

        //将user对象存储到mv对象中,也会将user对象存储到request域中

        mv.addObject("user", user);



        //跳转到哪个页面

        mv.setViewName("success");

        return mv;

    }

框架中可以实现重定向和转发方式

请求转发

   

重定向

这个路径注意修改(是项目的根目录就/文件名.jsp)

注意:如果是重定向到jsp页面,jsp文件不能写在WEB-INF下面

(WEB-IN目录都是一些配置的文件,不是我们常用的)

/**

     * 按照框架的方式写请求转发和重定向

     */



    @RequestMapping("/testForwardandRedirect")

    public String testForwardandRedirect(){



        System.out.println("testForwardandRedirect方法执行了...");

        //请求转发   也可以转发到其他的控制器

        //return "forward:/pages/success.jsp";

        //相当于使用

        // request.getRequestDispatcher("/pages/success.jsp").forward(request,response);



        //重定向

        return "redirect:/index.jsp";

        //response.sendRedirect(request.getContextPath()+"/index.jsp");

        //注意:如果是重定向到jsp页面,jsp文件不能写在WEB-INF下面

    }

响应数据类型

json(重要),xml

@ResponseBody响应json数据格式,跟之前axjx的异步操作是一样的,只不过把ajax中servlet换成注解方式实现的

作用:注解将Controller类的方法返回的对象,通过HttpMessageConverter接口转换为指定格式的数据(json),响应给客户端浏览器

前提:需要导入新的坐标依赖

jar包支持(json解析器)

jackson

步骤

1)导入jackson依赖坐标和Jquery      

         <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-core</artifactId>

            <version>2.9.0</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-annotations</artifactId>

            <version>2.9.0</version>

        </dependency>

注意:前端控制器会进行静态资源的拦截

2)当我们导入静态资源的时候,SpringMVC是没有对应的反应的

原因:DispatcherServlet前端控制器会进行静态资源的拦截

解决方式:

1、重新设置一下web.xml,要求它不能拦截静态资源springMVC.xml


  

    <!--前端控制器,不会拦截一下静态资源-->

    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>

    <mvc:resources mapping="/images/**" location="/images/"></mvc:resources>

    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>

2、默认的拦截方式

springMVC框架对名字过长有bug,需要把jquery的包修改名字为jquery.js

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

3)编写jquery代码, 添加对应的ajax请求

添加对应的ajax请求              

             $.ajax({

                    //json格式,设置属性名和属性值

                    url:"user/testAjax",

                    contentType:"application/json;charset=UTF-8",

                    data:'{"uname":"haha","age":"20"}',

                    dataType:"json",

                    type:"post",

                    success:function (data) {

                        //服务器响应的json数据,进行解析

                        alert(data.uname);

                        alert(data.age);

                    }

                });

4)控制器实现

    @RequestMapping("/testAjax")

    public @ResponseBody User testAjax(@RequestBody User user){

        System.out.println("testAjax方法执行了...");

        System.out.println(user);



        //做出对应的响应

        //模拟数据操作

        user.setUname("呵呵");

        user.setAge(40);



        //做出响应

        return user;



    }

SpringMVC文件上传

概述

两种形式

1)利用框架自带的文件上传功能

2)不利用框架,利用第三方插件实现上传

这两种形式实现文件上传的前提(前台页面):

1)form表单中属性enctype的值必须是multipart/form-data

2)method属性必须是post

3)提供一个上传的控件 <input type="file">

前台页面满足这三点才能实现上传的操作

SpringMVC上传原理

 

新建工程:(内容知识点全面)

pom.xml

 

 <!--版本锁定-->
  <spring.version>5.0.2.RELEASE</spring.version>
</properties>

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>${spring.version}</version>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.0</version>
    <scope>provided</scope>
  </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-core</artifactId>
    <version>2.9.0</version>
  </dependency>
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
  </dependency>
</dependencies>

springMVC.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <!--开启注解扫描-->
    <context:component-scan base-package="com.neuedu"></context:component-scan>

    <!--视图解析器对象-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/pages/"></property>
        <property name="suffix" value=".jsp"></property><!--给解析器指明路径后解析成  .jsp格式  -->
    </bean>

    <!--开启spingMVC注解-->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!--前端控制器,不会拦截一下静态资源-->
    <mvc:resources mapping="/css/**" location="/css/"></mvc:resources>
    <mvc:resources mapping="/images/**" location="/images/"></mvc:resources>
    <mvc:resources mapping="/js/**" location="/js/"></mvc:resources>
   
</beans>

web.xml

​
<display-name>Archetype Created Web Application</display-name>
<!--配置前端控制器-->
<servlet>
  <servlet-name>dispatcherServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

  <init-param>
    <param-name>contextConfigLocation</param-name><!--name固定写法-->
    <param-value>classpath:springMVC.xml</param-value>
  </init-param>
  <!--目的是启动servlet就先加载init-parm文件,先扫描注解的信息-->
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>dispatcherServlet</servlet-name>
  <url-pattern>/</url-pattern>
</servlet-mapping>

<!--配置过滤器 解决参数绑定中文乱码问题-->
<filter>
  <filter-name>characterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <!--加入初始化参数,指明过滤UTF-8-->
  <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>

​

实现步骤

1)上传所需要的依赖

pom文件需要导入坐标依赖
 

   <dependency>

      <groupId>commons-fileupload</groupId>

      <artifactId>commons-fileupload</artifactId>

      <version>1.3.1</version>

    </dependency>



    <dependency>

      <groupId>commons-io</groupId>

      <artifactId>commons-io</artifactId>

      <version>2.4</version>

    </dependency>

2)配置文件解析器

  

1024进制 B KB MB GB

 

<!--配置文件解析器,要求id名字必须是multipartResolver -->

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

        <property name="maxUploadSize" value="10485760"></property>

    </bean>

3)配置上传的控件, 前台页面

以下固定操作:

 

enctype="multipart/form-data"

method="post"

   

    <form action="/user/fileupload" method="post" enctype="multipart/form-data">

        文件的选择:<input type="file" name="upload"><br>

        <input type="submit" value="上传">

    </form>

4)最终上传

UUID 作用:作为服务存放图片的唯一标识,作用就是为了不让不同的客户端上传的图片发生覆盖

核心的东西就这三步:       

 

         //上传文件存放的位置

        String path = request.getSession().getServletContext().getRealPath("/upload/");



        //获取上传文件的名字

        String fileName = upload.getOriginalFilename();



        //完成上传  path 传来的文件需要存放到的位置  fileName存放文件的名字

        upload.transferTo(new File(path,fileName));

目录target:上传生成文件存放在目录是target。包括生成的class文件

SpringMVC拦截器

概述:

属于SpringMVC框架下一个特殊功能,其他结构是不能使用的

作用:对处理器进行预处理和后处理的技术,后处理的技术包括处理方法执行后和页面执行完后做什么

可以定义一个拦截器链,类似于之前的过滤器链

拦截器链:按照有一定的顺序结构,去拦截对应的访问方法

拦截器和过滤器进行比较?(面试概率不是很高)

1、过滤器是Servlet规范的一部分,任何框架结构都是可以使用过滤器的(springMVC也是可以使用过滤器的,但是过滤器只是针对于页面表现层,因为过滤的是页面访问的信息)

2、拦截器是SpringMVC的独有功能

3、过滤器配置这种写法/*,是可以过滤任何资源,也可以指定单独的资源进行过滤

4、拦截器只会对控制器中的方法进行拦截

5、拦截器是AOP思想实现的功能

6、SpringMVC下我们只需要配置xml文件就可以实现过滤器

7、实现拦截器,需要实现HandlerInterceptor接口

操作步骤(一个拦截器):

1)编写一个普通的类,让该类实现HandlerInterceptor接口,那么它就是一个拦截器

public class MyInterceptor implements HandlerInterceptor

2)实现该接口中的方法(和AOP中的通知是一样的,为了增强对应的控制器的处理方法)

Ctrl + o 快捷键可以实现接口方法的重写

HandlerInterceptor接口中的三个方法:

第一个:preHandle()  预处理(在执行处理控制器中的方法之前先执行)

如果返回值是true,表示不拦截(放行),如果有后续拦截器,那么继续看是否拦截,如果不拦截,执行控制器中的具体方法

如果返回值false,不会执行控制器中的方法

request或response可以跳转执行页面,如果指定了跳转的页面,控制器也可以跳 不影响控制器类中的方法

第二个:postHandle()  (后处理 在执行处理控制器中的方法后执行)

是在控制器方法执行之后,但是在jsp执行之前 需要执行的方法,

request或response可以跳转执行页面,如果指定了跳转的页面,

那么会影响控制器方法中的跳转就失效

第三个:afterCompletion() 也是后执行是最终处理,(它是在页面完成后执行处理)

jsp页面执行后执行   如果使用request或response不能跳转页面,因为页面加载完了

3)配置拦截器,xml文件(建立拦截器类和控制器类建立上关联)

/**

    <!--配置拦截器部分-->

    <mvc:interceptors>

        <!--配置第一个拦截器-->

        <mvc:interceptor>

            <!--要拦截的具体的方法-->

            <mvc:mapping path="/user/**"/>

            <!--配置拦截器对象。并把它交给IOC容器,程序内部自动执行,

我们不需要配置id去使用这个对象-->

            <bean class="com.neuedu.interceptor.MyInterceptor"></bean>

        </mvc:interceptor>

    </mvc:interceptors>

实现拦截器接口的方法,配置return的放回值false,那么请求就被隔离。访问不到controller

多个拦截器

跟一个拦截器原理是一样的,只是拦截的功能是不一样的(比如一个包下的不同控制器类)

在实现的时候——主要是到底是横向排列还是纵向排列(了解)

主要配置拦截器xml文件       

<!--配置第一个拦截器-->

        <mvc:interceptor>

            <!--要拦截的具体的方法-->

            <mvc:mapping path="/user/abc"/>

            <!--<mvc:exclude-mapping path=""/>-->

            <!--配置拦截器对象-->

            <bean class="com.neuedu.interceptor.MyInterceptor"></bean>

        </mvc:interceptor>



        <!--配置第二个拦截器-->

        <mvc:interceptor>

            <!--要拦截的具体的方法-->

            <mvc:mapping path="/user/abc"/>

            <!--<mvc:exclude-mapping path=""/>-->

            <!--配置拦截器对象-->

            <bean class="com.neuedu.interceptor.MyInterceptor1"></bean>

        </mvc:interceptor>

框架下异常处理

概述

在一系列操作中可能会出现异常:

浏览器发出请求-->前端控制器     --> 表现层 --> 业务逻辑层 --> 持久层

错误页面     异常处理器组件        抛出        抛出   <-- 出现异常抛出

                交给异常处理的类

如果持久层出现异常抛出

业务逻辑层接收到持久层的异常也抛出

表现层同理抛出

前端控制器接收到下层出现的异常,然后使用异常处理器组件(catch{}的意思),交给异常处理的类

最后交给浏览器出现错误页面

注意:如果不给出错误页面,客户端能看到的就是异常信息(比如404)

实现步骤:

出现错误时,通过springMVC.xml文件中配置的异常处理器把错误截住,不让显示在页面中。截住的异常在异常处理器类(实现一个接口HandlerExceptionResolve)中处理,在异常处理器类中自定义一个异常类,把我们自定义异常的信息通过接口的ModelAndView对象,存在域对象中跳转到显示异常的页面,在由显示异常的页面通过EL表达式获取域对象中的数据,让客户看到

 

1)编写一个自定义异常类,所有的自定义异常类都要继承Exception类

/**

 * 自定义异常

 * */

public class SysException extends Exception{

    //存储提示信息,用于提示页面

    private String message;



    @Override

    public String getMessage() {

        return message;

    }



    public void setMessage(String message) {

        this.message = message;

    }



//构造方法,当调用这个方法就把自定义异常的信息初始化

    public SysException(String message){

        this.message = message;

    }

}

2)编写异常显示的页面

error.jsp,直接用文字显示就可以,使用异常处理类中通过域对象共享的数据出现在提示异常的页面

浏览器请求的页面:

3)自定义异常处理器 处理的信息是我们自己写

实现一个接口HandlerExceptionResolver

实现接口中的方法,这个方法是写业务逻辑处理的方法

如果有异常我们需要拿到我们自定义异常的对象。出现异常的类要判断我们自定义异常类是否是它的子类,如果不是那么使用我们自定义的异常类,显示给用户。如果出现异常的类是我们自定义类的父类,那么也得只用我们自定义的异常,否则出现异常客户会看不到我们自己定义的异常

4)在前端控制器xml文件中配置异常处理器。让配置文件识别到异常处理器

     

   <!--配置异常处理器-->

        <bean id="sysExceptionResolver" class="com.neuedu.exception.SysExceptionResolver"></bean>

制造异常 测试代码

SpringMVC:拦截器+文件上传下载

拦截器kuang

概述

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

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

过滤器

  • servlet规范中的一部分,任何java web工程都可以使用

  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用

  • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

自定义拦截器

那如何实现拦截器呢?

想要自定义拦截器,必须实现 HandlerInterceptor 接口。

1、新建一个Moudule , springmvc-07-Interceptor  , 添加web支持

2、配置web.xml 和 springmvc-servlet.xml 文件

3、编写一个拦截器

package com.kuang.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

   //在请求处理的方法之前执行
   //如果返回true执行下一个拦截器
   //如果返回false就不执行下一个拦截器
   public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
       System.out.println("------------处理前------------");
       return true;
  }

   //在请求处理方法执行之后执行
   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
       System.out.println("------------处理后------------");
  }

   //在dispatcherServlet处理后执行,做清理工作.
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
       System.out.println("------------清理------------");
  }
}

4、在springmvc的配置文件中配置拦截器

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <!--/** 包括路径及其子路径-->
       <!--/admin/* 拦截的是/admin/add等等这种 , /admin/add/user不会被拦截-->
       <!--/admin/** 拦截的是/admin/下的所有-->
       <mvc:mapping path="/**"/>
       <!--bean配置的就是拦截器-->
       <bean class="com.kuang.interceptor.MyInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

5、编写一个Controller,接收请求

package com.kuang.controller;

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

//测试拦截器的控制器
@Controller
public class InterceptorController {

   @RequestMapping("/interceptor")
   @ResponseBody
   public String testFunction() {
       System.out.println("控制器中的方法执行了");
       return "hello";
  }
}

6、前端 index.jsp

<a href="${pageContext.request.contextPath}/interceptor">拦截器测试</a>

7、启动tomcat 测试一下!

图片

验证用户是否登录 (认证用户)

实现思路

1、有一个登陆页面,需要写一个controller访问页面。

2、登陆页面有一提交表单的动作。需要在controller中处理。判断用户名密码是否正确。如果正确,向session中写入用户信息。返回登陆成功。

3、拦截用户请求,判断用户是否登陆。如果用户已经登陆。放行, 如果用户未登陆,跳转到登陆页面

测试:

1、编写一个登陆页面  login.jsp

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

<h1>登录页面</h1>
<hr>

<body>
<form action="${pageContext.request.contextPath}/user/login">
  用户名:<input type="text" name="username"> <br>
  密码:<input type="password" name="pwd"> <br>
   <input type="submit" value="提交">
</form>
</body>
</html>

2、编写一个Controller处理请求

package com.kuang.controller;

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

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class UserController {

   //跳转到登陆页面
   @RequestMapping("/jumplogin")
   public String jumpLogin() throws Exception {
       return "login";
  }

   //跳转到成功页面
   @RequestMapping("/jumpSuccess")
   public String jumpSuccess() throws Exception {
       return "success";
  }

   //登陆提交
   @RequestMapping("/login")
   public String login(HttpSession session, String username, String pwd) throws Exception {
       // 向session记录用户身份信息
       System.out.println("接收前端==="+username);
       session.setAttribute("user", username);
       return "success";
  }

   //退出登陆
   @RequestMapping("logout")
   public String logout(HttpSession session) throws Exception {
       // session 过期
       session.invalidate();
       return "login";
  }
}

3、编写一个登陆成功的页面 success.jsp

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

<h1>登录成功页面</h1>
<hr>

${user}
<a href="${pageContext.request.contextPath}/user/logout">注销</a>
</body>
</html>

4、在 index 页面上测试跳转!启动Tomcat 测试,未登录也可以进入主页!

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>
   <title>$Title$</title>
 </head>
 <body>
 <h1>首页</h1>
 <hr>
<%--登录--%>
 <a href="${pageContext.request.contextPath}/user/jumplogin">登录</a>
 <a href="${pageContext.request.contextPath}/user/jumpSuccess">成功页面</a>
 </body>
</html>

5、编写用户登录拦截器

package com.kuang.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginInterceptor implements HandlerInterceptor {

   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
       // 如果是登陆页面则放行
       System.out.println("uri: " + request.getRequestURI());
       if (request.getRequestURI().contains("login")) {
           return true;
      }

       HttpSession session = request.getSession();

       // 如果用户已登陆也放行
       if(session.getAttribute("user") != null) {
           return true;
      }

       // 用户没有登陆跳转到登陆页面
       request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
       return false;
  }

   public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

  }
   
   public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

  }
}

6、在Springmvc的配置文件中注册拦截器

<!--关于拦截器的配置-->
<mvc:interceptors>
   <mvc:interceptor>
       <mvc:mapping path="/**"/>
       <bean id="loginInterceptor" class="com.kuang.interceptor.LoginInterceptor"/>
   </mvc:interceptor>
</mvc:interceptors>

7、再次重启Tomcat测试!

OK,测试登录拦截功能无误.

文件上传和下载kuang

准备工作

文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。

前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;

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

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。

  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。

  • text/plain:除了把空格转换为 "+" 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。

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

一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。

  • Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。

  • 而Spring MVC则提供了更简单的封装。

  • Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。

  • Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类:

  • CommonsMultipartResolver。因此,SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。

文件上传

1、导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包;

<!--文件上传-->
<dependency>
   <groupId>commons-fileupload</groupId>
   <artifactId>commons-fileupload</artifactId>
   <version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>4.0.1</version>
</dependency>

2、配置bean:multipartResolver

注意!!!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这里栽过坑,教训!】以下的文件大小上线和单位可以不配

<!--文件上传配置-->
<bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <!-- 请求的编码格式,必须和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):将上传文件保存到一个目录文件中

我们去实际测试一下

3、编写前端页面

<form action="/upload" enctype="multipart/form-data" method="post">
 <input type="file" name="file"/>
 <input type="submit" value="upload">
</form>

4、Controller

package com.kuang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;

@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";
  }
}

5、测试上传文件,OK!

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

1、编写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";
}

2、前端表单提交地址修改

3、访问提交测试,OK!

文件下载

文件下载步骤:

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;
}

前端

<a href="/download">点击下载</a>

测试,文件下载OK,大家可以和我们之前学习的JavaWeb原生的方式对比一下,就可以知道这个便捷多了!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值