SpringMVC08:拦截器+文件下载

目录

一、概述

二、自定义拦截器

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>

③ 测试下载!

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

猜你喜欢

转载自blog.csdn.net/weixin_44740328/article/details/131288423