ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-08-07 02:31:55  阅读:110  来源: 互联网

标签:文件 拦截器 String 上传下载 SpringMVC10 import 上传 public


拦截器+文件上传下载

拦截器

概述

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

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

过滤器

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

拦截器

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

自定义拦截器

那如何实现拦截器呢?

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

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

2、配置web.xml 和 applicationContext.xml 文件

3、编写一个拦截器

package com.edgar.config;

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就不执行下一个拦截器
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("============处理前================");
        return true;
    }

    // 在请求处理方法执行之后执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("============处理后================");
    }

    // 在dispatcherServlet处理后执行,做清理工作.
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 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.edgar.config.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

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

package com.edgar.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @RequestMapping("/t1")
    public String test(){
        System.out.println("TestController=>test()执行了");
        return "OK";
    }
}

6、启动tomcat 测试一下!

http://localhost:8080/t1

feh20e.png

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

实现思路

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

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

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

测试:

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

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

<%--在WEB-INF下的所有页面或者资源,只能通过controller,或者servlet进行访问--%>
<h1>登陆页面</h1>

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

2、编写一个Controller处理请求

package com.edgar.controller;

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

import javax.servlet.http.HttpSession;

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

    @RequestMapping("/main")
    public String main(){
        return "main";
    }

    @RequestMapping("/goLogin")
    public String goLogin(){
        return "login";
    }

    @RequestMapping("/login")
    public String login(HttpSession session, String username, String password, Model model){
        // 把用户的信息存在session中
        session.setAttribute("userLoginInfo",username);
        model.addAttribute("username",username);
        return "main";

    }

    @RequestMapping("/logout")
    public String logout(HttpSession session){
      session.removeAttribute("userLoginInfo");
      return "login";
    }

}

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

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>首页</h1>
<span>${username}</span>
<p>
    <a href="${pageContext.request.contextPath}/user/logout">注销</a>
</p>
</body>
</html>

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

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

5、编写用户登录拦截器

package com.edgar.config;

import org.springframework.web.servlet.HandlerInterceptor;

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

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 放行:如果是前往登录页面
        if (request.getRequestURI().contains("goLogin")) {
            return true;
        }

        // 放行:如果是登录提交请求
        if (request.getRequestURI().contains("login")) {
            return true;
        }

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

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

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

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

7、再次重启Tomcat测试!

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

文件上传和下载

准备工作

文件上传是项目开发中最常见的功能之一 ,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、编写前端页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="upload">
</form>
</body>
</html>

4、FileController

package com.edgar.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 {

    @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("上传文件保存地址:"+path);

        // 文件输入流
        InputStream is = file.getInputStream();
        // 文件输出流
        OutputStream os = new FileOutputStream(new File(path, 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.hashCode();

        return "redirect:/index.jsp";

    }

}

5、测试上传文件,OK!

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

1、编写Controller

@RequestMapping("/upload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) throws IOException {

    String username = request.getParameter("username");
    System.out.println(username);

    // 上传路径保存设置
    String path = request.getServletContext().getRealPath("/upload");
    File realPath = new File(path);
    if (!realPath.exists()) {
        realPath.mkdir();
    }

    // 上传文件地址
    System.out.println("上传文件保存地址:"+path);

    // 通过CommonsMultipartFile的方法直接写文件
    file.transferTo(new File(path,file.getOriginalFilename()));

    return "redirect:/index.jsp";
}

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

3、访问提交测试,OK!

文件下载

1、设置 response 响应头

2、读取文件 -- InputStream

3、写出文件 -- OutputStream

4、执行操作

5、关闭流 (先开后关)

代码实现:

@RequestMapping("/download")
public String downloads(HttpServletRequest request,HttpServletResponse response) throws Exception {
    // 要下载的图片地址
    String path = request.getServletContext().getRealPath("/upload");
    String fileName = "1.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 is = new FileInputStream(file);
    // 3.写出文件--输出流
    OutputStream os = response.getOutputStream();

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

前端

<a href="${pageContext.request.contextPath}/download">点击下载</a>

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

标签:文件,拦截器,String,上传下载,SpringMVC10,import,上传,public
来源: https://www.cnblogs.com/edgarstudy/p/15110888.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有