SpringMVC08:拦截器+文件下载

news2024/11/24 15:31:48

目录

一、概述

二、自定义拦截器

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

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

3、编写一个拦截器

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

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

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

1、编写一个导航页面index.jsp

2、编写一个登录页面login.jsp

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

4、编写一个主页面main.jsp

5、编写一个登录的拦截器LoginInterceptor.java

6、编写一个登录控制类LoginController.java

7、在springmvc的配置文件web.xml中配置拦截器

四、文件上传和下载

1、准备工作

2、文件上传

1、导入文件上传的jar包

2、配置bean:multipartResolver

3、编写前端页面

4、文件控制类FileController.java

5、测试上传文件

6、采用file.transTo方法来保存上传的文件

3、文件下载

1、文件下载步骤

2、代码实现:① 编写FileController类中的downloadFile方法;

一、概述

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

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

过滤器:

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

拦截器:

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

二、自定义拦截器

想要自定义拦截器,必须实现HandlerInceptor接口;

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

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

3、编写一个拦截器

public class MyInterceptor implements HandlerInterceptor {
    @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("拦截后================");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("清理================");;
    }
}

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

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

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

@RestController
public class InterceptorController {
    @RequestMapping("/test1")
    public String test1(){
        System.out.println("测试方法通过打印");
        return "okok!";
    }
}

访问地址:http://localhost:8080/test1

测试结果:

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

  • 有一个登录页面,需要写一个controller访问页面;
  • 判断用户名密码是否正确
  • 登录页面有一个提交表单的动作,需要在controller中处理。判断用户名密码是否正确。如果正确,向session中写入用户信息,返回登录成功!
  • 拦截用户请求,判断用户是否登录。如果用户已经登录。放行,如果用户未登录,跳转到登录页面;

1、编写一个导航页面index.jsp

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

2、编写一个登录页面login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录页面</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login">
    用户名:<input type="text" name="username"/><br>
    密 码:<input type="text" name="password"/><br>
    <input type="submit" value="提交">
</form>
</body>
</html>

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

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

4、编写一个主页面main.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
<p>首页内容显示</p>
</body>
</html>

5、编写一个登录的拦截器LoginInterceptor.java

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果访问路径中含有“login”,那么是登陆页面则放行
        System.out.println("URI:"+request.getRequestURI());
        if (request.getRequestURI().contains("login")) {
            return true;
        }
        //如果session中用户已经被保存,说明已登录则放行
        HttpSession session = request.getSession();
        if (session.getAttribute("user") != null){
            return true;
        }
        /**用户没有登录并且访问的不是登录页面,
         * 那么系统要跳转到登录页面登录后才可进行其他操作*/
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        return false;
    }
}

6、编写一个登录控制类LoginController.java

@Controller
@RequestMapping("/user")
public class LoginController {
    //提交登录
    @RequestMapping("/login")
    public String login(HttpSession session,String username,String password){
        //向session记录用户信息
        System.out.println("接收前端===" + username);
        session.setAttribute("user",username);
        return "success";
    }
    //跳转到登录页面
    @RequestMapping("/jumpLogin")
    public String jumpLogin(){
        return "login";
    }
    //跳转到成功页面
    @RequestMapping("/jumpSuccess")
    public String jumpSuccess(){
        return "main";
    }
    //退出登录
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        session.removeAttribute("user");
        return "login";
    }
}

7、在springmvc的配置文件web.xml中配置拦截器

    <!--配置拦截器-->
    <mvc:interceptors>        
        <mvc:interceptor>
            <!--/admin/** 拦截的是/admin/下的所有-->
            <mvc:mapping path="/user/**"/>
            <bean class="com.lucky.config.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

重新启动测试!

四、文件上传和下载

1、准备工作

文件上传是项目开发中最常见的功能之一,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的组件。

2、文件上传

1、导入文件上传的jar包

commons-fileupload,Maven会自动帮我们导入它的依赖包commons-io包;

    <dependencies>
        <!--文件上传-->
        <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>3.1.0</version>
        </dependency>
    </dependencies>

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的常用方法:

1、getOriginalFilename():获取上传文件的原名;
2、InputStream getInputStream():获取文件流;
3、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、文件控制类FileController.java

@Controller
public class FileController {
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file")CommonsMultipartFile file,
                             HttpServletRequest request) throws IOException {
        //1、获取文件名
        String filename = file.getOriginalFilename();
        //2、如果文件名为空,直接回到首页
        if ("".equals(filename)) {
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名:" + filename);
        //3、上传路径保存设置
        String path = request.getSession().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, filename));
        //读取写出
        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、测试上传文件

使用不同的方式上传文件需要更改前端页面action路径。

6、采用file.transTo方法来保存上传的文件

① 编写FileController 类中的fileUpload2方法;

@Controller
public class FileController {
    @RequestMapping("/upload2")
    public String fileUpload2(@RequestParam("file")CommonsMultipartFile file,HttpServletRequest request) throws IOException {
        //1、上传路径保存设置
        String path = request.getSession().getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        //2、上传文件地址
        System.out.println("上传文件保存地址:" + realPath);
        //3、通过CommonsMultipartFile的方法直接写文件
        file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));
        return "redirect:/index.jsp";
    }

}

② 前端表单提交地址修改

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

③ 访问提交测试,ok。

3、文件下载

1、文件下载步骤

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

2、代码实现:
① 编写FileController类中的downloadFile方法;

@Controller
public class FileController {
    @RequestMapping("/download")
    public String downloadFile(HttpServletResponse response,HttpServletRequest request) throws Exception {
        //1、要下载的图片所在的地址
        String path = request.getSession().getServletContext().getRealPath("/upload");
        String fileName = "1.png";
        //2、设置response响应头
        response.reset();//设置页面不缓存,清空buffer
        response.setCharacterEncoding("utf-8");//字符编码
        response.setContentType("multipart/form-data");//二进制传输数据
        //3、设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
        File file = new File(path, fileName);
        //4、读取文件--输入流
        InputStream is = new FileInputStream(file);
        //5、写出文件--输出流
        OutputStream os = response.getOutputStream();
        byte[] buff = new byte[1024];
        int index = 0;
        //6、执行写出操作
        while ((index=is.read(buff))!=-1) {
            os.write(buff,0,index);
            os.flush();
        }
        os.close();
        is.close();
        return null;
    }
}

② 前端代码:

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

③ 测试下载!

完结~~~~撒花~~~~~感谢围观*★,°*:.☆( ̄▽ ̄)/$:*.°★* 。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/668347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】Mysq备份与恢复

文章目录 一、数据库备份的分类1. 数据备份的重要性2. 数据库备份的分类3. 常见的备份方法 二、Mysql 完全备份与恢复1. Mysql 完全备份2. 数据库完全备份分类2.1 物理冷备份及恢复2.2 mysqldump 备份数据库完全备份一个或多个完整的库&#xff08;包括其中所有的表&#xff09…

基于YOLOv5实现安全帽检测识别

目录 1、作者介绍2、YOLOv5网络模型2.1 算法简介2.2 数据集介绍2.2.1 VOC数据集准备2.2.2 YOLOv5算法检测流程 3、代码实现3.1 数据集划分部分代码3.2 训练阶段3.3 测试阶段3.4 检测结果 4、问题与分析参考链接 1、作者介绍 陈梦丹&#xff0c;女&#xff0c;西安工程大学电子…

【6.20】sleep()和wait()的区别

sleep()和wait()的区别 1、wait()方法 1.1使用场景 当某个线程获取到锁后&#xff0c;却还是不满足执行的条件&#xff0c;就可以调用对象锁的wait方法&#xff0c;进入等待状态。 直到外在条件满足了&#xff0c;就可以由其它线程调用notify或者notifyAll方法&#xff0c;…

在软件研发排期中要求“倒推时间”,项目结束后悲剧了……

有没有遇到某个项目任务的研发周期已被各路boss定下&#xff0c;研发团队都觉得时间不合理&#xff0c;反馈给上级无果&#xff0c;而要求“倒推时间”进行任务排期的情况&#xff1f; 什么是“倒推时间”&#xff1f; 目标倒推法&#xff0c;从剩下的时间反推算出每天该做的事…

【Java】死锁问题及ThreadLocal

什么是死锁分析过程发生死锁的原因避免死锁ThreadLocal 什么是死锁 多个线程同时被阻塞&#xff0c;它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞&#xff0c;因此程序不可能正常终止。这是一个最严重的BUG之一。 分析过程 1.一个线程一把锁 一个线…

深入理解TDD(测试驱动开发):提升代码质量的利器

在日常的软件开发工作中&#xff0c;我们常常会遇到这样的问题&#xff1a;如何在繁忙的项目进度中&#xff0c;保证我们的代码质量&#xff1f;如何在不断的迭代更新中&#xff0c;避免引入新的错误&#xff1f;对此&#xff0c;有一种有效的开发方式能帮助我们解决这些问题&a…

14.处理大数据集

14.1 随机梯度下降 假设你正在使用梯度下降来训练一个线性回归模型 当m个样本的m很大时&#xff0c;求和计算量太大了。这种梯度下降算法有另外一个名字叫做批量梯度下降&#xff08;batch gradient desent&#xff09;。这种算法每次迭代需要使用全量训练集&#xff0c;直到算…

【代码阅读软件】Source Insight 4 使用教程 | 很详细——适合新手

目录 一、概述二、常用的几个窗口&#x1f449;2.1 符号窗口&#xff08;Symbol Window&#xff09;&#x1f449;2.2 项目文件窗口&#xff08;Project Window&#xff09;&#x1f449;2.3 关系窗口&#xff08;Relation Window&#xff09;&#x1f449;2.4 上下文窗口&…

STM32--基于固件库(Library Faction)的led灯点亮

目录 一、STM32芯片的简单介绍 二、基于固件库&#xff08;Library Faction&#xff09;的led灯点亮 这是一个学习stm32的开端&#xff0c;我们由简入难&#xff0c;之前学过C51/52或是其他型号的一般都是从led开始&#xff0c;也就是简单的输入输出端口的应用。&#xff08;想…

SpringBoot整合模板引擎Thymeleaf(1)

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Thymeleaf概述 Thymeleaf是一种用于Web和独立环境的现代服务器端的Java模板引擎&#xff0c;主要目标是将优雅的自然模板带到开发工作流程中&#xff0c;并将HTML在浏览器中…

【kubernetes】Etcd集群部署与验证

前言:二进制部署kubernetes集群在企业应用中扮演着非常重要的角色。无论是集群升级,还是证书设置有效期都非常方便,也是从事云原生相关工作从入门到精通不得不迈过的坎。通过本系列文章,你将从虚拟机准备开始,到使用二进制方式从零到一搭建起安全稳定的高可用kubernetes集…

吐血整理,性能测试Jmeter分布式压测遇坑总结+解决

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 为什么要使用分布…

JSON.parse() 全面用法介绍

JSON 通常用于与服务端交换数据。在接收服务器数据时一般是字符串。我们可以使用 JSON.parse() 方法将数据转换为 JavaScript 对象。 语法 JSON.parse(text[, reviver]) text:必需&#xff0c; 一个有效的 JSON 字符串。 reviver: 可选&#xff0c;一个转换结果的函数&#xf…

SPI协议解析

SPI协议介绍 引言介绍SPI简介物理层协议层通讯的起始和停止信号SPI 模式 优缺点优点缺点 使用例程基于STM32的SPI通信准备硬件连接 软件实现 总结 引言 SPI是串行外设接口的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线。由于SPI高速和同步的特…

vite环境变量与模式

环境变量 Vite 在一个特殊的 import.meta.env 对象上暴露环境变量。这里有一些在所有情况下都可以使用的内建变量&#xff1a; import.meta.env.MODE: {string} 应用运行的模式。 import.meta.env.BASE_URL: {string} 部署应用时的基本 URL。他由base 配置项决定。 import.m…

【ESP8266】使用MQTT协议 连接华为云iotDA,实现设备属性上报

相关资料&#xff1a;https://github.com/CQUPTLei/ESP8266 往期文章&#xff1a;【ESP8266】基础AT指令和常用WIF指令 【MQTT 5.0】协议 ——发布订阅模式、Qos、keepalive、连接认证、消息结构 一、华为云iotDA1.1 什么是iotDA1.2 创建 iotDA 产品 二、使用ESP8266上报设备…

【杂谈理解】STM32F10X标准库工程模板

前言 基于STM官网的STM32F10x标准外设库V3.6.0版本&#xff0c;文件的操作流程是参考江科大的。记录下此文方便学习和回忆。文章后也会放置完整的工程文件和意法官网下载STM32F10x标准外设库的压缩包。 流程 到意法官网下载STM32F10x标准外设库的压缩包。先找到压缩包的地址&a…

CMake详解

file文件操作 cmake的file命令_cmake file_物随心转的博客-CSDN博客 set指令 CMake中的set指令详解_cmake set_guanguanboy的博客-CSDN博客 include_directories指令 Cmake命令之include_directories介绍 - 简书 add_subdirectory Cmake命令之add_subdirectory介绍 - 简书…

两台电脑用网线传输文件的一些问题解决

两台电脑用网线传输文件 步骤如下&#xff1a; 一、两台电脑插上网线 网线568A和568B可能没什么影响 二、 ipv4地址配置 两个网线插上电脑会自动生成一个ipv4地址 cmd里使用ipconfig查看 用这个就行了如果不想用自动生成的ip地址 也可以自己配置ipv4地址和网关&#xff08…

升级Nginx

目录 前言 一、升级Nginx 1&#xff09;首先在官网下载一个新版本的Nginx 2&#xff09;首先将下载的压缩包进行解包 3&#xff09;进入已解包的目录中 4&#xff09;配置安装路径 5&#xff09;make 6&#xff09;备份原来Nginx的资源 7&#xff09;重启Nginx服务 8&#…