Spring MVC的文件上传和下载以及拦截器

一、文件上传

在使用form表单进行文件上传时,必须将method设置为 post,并将enctype设置为multipart/form-data。只有这样设置,浏览器才会将需要上传的文件已二进制数据发送到服务器。SpringMVC为文件上传提供了直接的支持,这种支持时即插即用的MultipartResolver实现的。

代码实例:

前台页面代码:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>文件上传</title>
</head>
<body>
    <h2>文件上传</h2>
    <form action="upload" enctype="multipart/form-data" method="post">
        <table>
            <tr>
                <td>文件描述:</td>
                <td><input type="text" name="description"/></td>
            </tr>
            <tr>
                <td>请选择文件</td>
                <td><input type="file" name="file"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="上传"/></td>
            </tr>
        </table>
    </form>

</body>
</html>

后台接受代码:

package com.hu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

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

@Controller
public class FileUploadController {

    @RequestMapping(value = "/uploadform")
    public String uploadForm() {
        return "uploadForm";
    }

    //上传文件会自动绑定到MultipartFile
    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public String upload(HttpServletRequest request,
                         @RequestParam("description") String description,
                         @RequestParam("file") MultipartFile file) throws Exception {
        //如果文件不为空,写入上传路径
        if (!file.isEmpty()) {
            //上传路径
            String path = request.getServletContext().getRealPath("/images/");
            //上传文件名
            String filename = file.getOriginalFilename();
            File filepath = new File(path,filename);
            //判断路径是否存在
            if (!filepath.getParentFile().exists()) {
                filepath.getParentFile().mkdirs();
            }
            //将上传文件保存到一个目标文件当中
            file.transferTo(new File(path+File.separator+filename));
            return "success";
        }
        return "error";
    }
}

MultipartFile对象中,有一系列的方法,常用方法如下:

~byte[] getBytes() —— 获取文件数据

~String getContentType() —— 获取文件MIME类型,如txt/jar等

~InputStream getInputStream() —— 获取文件流

~String getName() —— 获取表单中文件组件的名字

~String getOriginalFilename() —— 获取上传文件的原名

扫描二维码关注公众号,回复: 2745779 查看本文章

~long getSize() —— 获取文件的字节大小,单位为byte

~boolean isEmpty() —— 是否有上传的文件

~void transferTo(File dest) —— 将上传文件保存到一个目标文件中

为完成文件上传还需在配置问价中添加MultipartResolver的配置:


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

二、文件下载

文件下载比较简单,直接在页面给出一个超链接,该链接href的属性等于要下载文件的文件名,就可以实现文件下载了。

三、拦截器

拦截器Interceptor是SpringMVC中重要功能,它的主要功能就是拦截用户的请求并进行相应的处理。如用通过拦截器来判断用户是否已经登录等操作。spring AOP的思想就可以用拦截器来实现,对切面操作进行拦截处理。

SpringMVC中的拦截器是通过实现HandlerInterceptor接口来实现的。在springMVC定义一个拦截器非常简单,只要其定义的拦截器实现HandlerInterceptor接口,或者继承抽象类HandlerInterceptorAdapter。

HandlerInterceptorAdapter接口中定义了三个方法:

~boolean preHandler(HttpServletRequest request,HttpServletResponse response,Object handle)。该方法将在请求处理之前被调用。并且SpringMVC中的Interceptor实行的是链式调用,即在一个应用中或者说一个请求中可以同时存在多个Interceptor中的preHandle方法。每个Interceptor的调用会依据它的声明顺序依次执行。并且只有当preHandler方法返回值为true时才会继续向下执行。

~void postHandle(HttpServletRequest request,HttpServletResponse response,Object handler,ModelAndView mv)。该方法只有在preHandler方法返回的值为 true时才执行。postHandle方法,就是在当前请求被处理之后,也就是Controller方法被调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用,所以这个方法可以在这个方法中对Controller处理之后的ModelAndView对象进行操作。

~void afterCompletion(HttpServletRequest request,HttpServletResponse response,Object handler,Exception exception)。该方法只有在preHandler方法返回的值为 true时才执行。该方法将在整个请求结束之后在执行。

拦截器拦截未登录用户代码实例:

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

         pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Hello World</title>
</head>
<body>
    <h3>登录页面</h3>
    <form action="login3" method="post">
        <%--提示信息--%>
        <font color="red">${requestScope.message}</font>
        <table>
            <tr>
                <td><label>登录名:</label></td>
                <td><input type="text" id="loginname" name="loginname"/></td>
            </tr>
            <tr>
                <td><label>密码:</label></td>
                <td><input type="password" id="password" name="password"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="登录"/></td>
            </tr>
        </table>

    </form>

</body>
</html>

后台代码:

package com.hu.controller;

import com.hu.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;

@Controller
public class User3Controller {

    @RequestMapping(value = "/login3")
    public ModelAndView login3(String loginname, String password, ModelAndView mv, HttpSession session) {
        if (loginname != null && loginname.equals("hu") && password != null && password.equals("123")) {
            User user = new User();
            user.setLoginname(loginname);
            user.setPassword(password);
            user.setUsername("管理员");
            //登录成功,将user对象设置到HttpSession作用域
            session.setAttribute("user", user);
            //转发到main请求
            mv.setViewName("redirect:main");
        } else {
            //登录失败,设置失败提示信息,并跳转到登录页面
            mv.addObject("message","登录名或密码错误,请重新输入!");
            mv.setViewName("loginForm3");

        }

        return mv;

    }
}
package com.hu.controller;

import com.hu.model.Book;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.ArrayList;
import java.util.List;

@Controller
public class BookController {

    @RequestMapping(value = "/main")
    public String main(Model model) {
        //模拟数据库获得所有图书集合
        List<Book> bookList = new ArrayList<>();
        bookList.add(new Book("java.jpg","java核心思想","小李子",55.0));
        bookList.add(new Book("123.jpg","倚天屠龙记","金庸",61.0));
        bookList.add(new Book("456.jpg","神雕侠侣","金庸",66.0));
        model.addAttribute("bookList",bookList);
        return "main";

    }
}

拦截器代码:用户没有登录不能访问其他页面

package com.hu.controller;

import com.hu.model.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * 拦截器必须实现HandlerInterceptor
 */
public class AuthorizationInterceptor implements HandlerInterceptor {

    //不拦截"/loginForm3"和"/login"请求
    private static final String[] IGNORE_URL = {"/loginForm3","/login"};

    /**
     * preHandle 方法是进行处理器拦截的,方法在Controller处理之前进行调用
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        boolean flag = false;
        //获取请求的路径
        String servletPath = httpServletRequest.getServletPath();
        //判断请求是否需要拦截
        for (String s : IGNORE_URL) {
            if (servletPath.contains(s)) {
                flag = true;
                break;
            }
        }
        //拦截请求
        if (!flag) {
            //1.获取session中的用户
            User user = (User) httpServletRequest.getSession().getAttribute("user");
            //2.判断是登录
            if (user == null) {
                System.out.println("请求被拦截:");
                httpServletRequest.setAttribute("message", "未登录,请先登录");
                httpServletRequest.getRequestDispatcher("loginForm3").forward(httpServletRequest,httpServletResponse);
            } else {
                System.out.println("请求未拦截");
                flag = true;
            }
        }
        return flag;
    }

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

    }

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

    }
}

最后在配置文件中加入拦截器的配置

<!--定义拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/*"/>
            <!--使用bean定义一个Interceptor-->
            <bean class="com.hu.controller.AuthorizationInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

猜你喜欢

转载自blog.csdn.net/huxiaodong1994/article/details/81605841