通知 网站从因情语写改为晴雨,这个网站的模板也从calmlog_ex改为 whimurmur

springMVC学习记录3-拦截器和文件上传

1002人浏览 / 0人评论 / | 作者:因情语写  | 分类: springmvc  | 标签: springmvc

作者:因情语写

链接:https://www.qingyu.blue/article/373

声明:请尊重原作者的劳动,如需转载请注明出处


  拦截器和文件上传算是springmvc中比较高级一点的内容了吧,让我们一起看一下。  

  下面先说说拦截器。拦截器和过滤器有点像,都可以在请求被处理之前和请求被处理之到做一些额外的操作。

  1. 实现HandlerInterceptor接口。

package com.sxt.interceptor;

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

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

   
public class MyInterceptor implements HandlerInterceptor {
 
    /**  
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等   
     *   
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()  
     */
    @Override
    public void afterCompletion(HttpServletRequest request,    HttpServletResponse response, Object handler, Exception ex)    throws Exception {
        System.out.println("最后执行!!!一般用于释放资源!!");
        
    }

    /** 
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作    
     * 可在modelAndView中加入数据,比如当前时间 
     */
    @Override
    public void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler,    ModelAndView modelAndView) throws Exception {
        System.out.println("Action执行之后,生成视图之前执行!!");
    }

    
    /**  
     * 在业务处理器处理请求之前被调用  
     * 如果返回false  
     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链 
     * 如果返回true  
     *    执行下一个拦截器,直到所有的拦截器都执行完毕  
     *    再执行被拦截的Controller  
     *    然后进入拦截器链,  
     *    从最后一个拦截器往回执行所有的postHandle()  
     *    接着再从最后一个拦截器往回执行所有的afterCompletion()  
     */
    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
        System.out.println("action之前执行!!!");
        return true;  //继续执行action
    }

}

  要实现三个方法,比较繁锁,下面看一下第二种。

  2. 继承HandlerInterceptorAdapter类。

package com.sxt.interceptor;

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

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    

public class MyInterceptor2 extends HandlerInterceptorAdapter {

    @Override  
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor2.preHandle()");
        return true;   //继续执行action
    }

}

  这是个Adapter类,Adapter类在Swing中应该有所接触,只要覆写自己需要用到的方法的就可以了。

  配置文件

<mvc:interceptors>
        <bean class="com.sxt.interceptor.MyInterceptor"></bean> <!-- 拦截所有springmvc的url! -->
        <mvc:interceptor>
            <mvc:mapping path="/user.do" /><!-- 拦截指定路径 -->
            <!--<mvc:mapping path="/test/*" />-->
            <bean class="com.sxt.interceptor.MyInterceptor2"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

  关于拦截器的更多知识,可以看一下下面的文章:

  第五章 处理器拦截器详解——跟着开涛学SpringMVC

  再说说文件上传。分两部分:spring3的文件上传和spring4的文件上传。

  1. spring3的文件上传。

  页面

<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>测试springmvc中上传的实现</title>
    </head>
    <body>
    <form action="upload.do"  method="post" enctype="multipart/form-data">
        <input type="text" name="name" />
        <input type="file" name="file" />
        <input type="submit" value="单文件上传"/>
    </form>
    
    </body>
</html>

  控制器

package com.sxt.action;

import java.io.File;
import java.util.Date;

import javax.servlet.ServletContext;

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.context.ServletContextAware;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

@Controller
public class FileUploadController implements ServletContextAware {
    // 用来获取上传路径
    private ServletContext servletContext;
    
    @Override
    public void setServletContext(ServletContext context) {
        this.servletContext  = context;
    }
    
    @RequestMapping(value="/upload.do", method = RequestMethod.POST)
    public String handleUploadData(String name,@RequestParam("file") CommonsMultipartFile file){
        if (file != null && !file.isEmpty()) {
               String path = this.servletContext.getRealPath("/tmp/");  //获取本地存储路径
               System.out.println(path);
               
               String fileName = file.getOriginalFilename();
               String fileType = fileName.substring(fileName.lastIndexOf("."));
               System.out.println(fileType); 
               File file2 = new File(path,new Date().getTime() + (int)(Math.random() * 1000000) + fileType); //新建一个文件
               try {
                    file.getFileItem().write(file2);
               } catch (Exception e) {
                    e.printStackTrace();
               }
               
               return "redirect:upload_ok.jsp";
            }else{
                return "redirect:upload_error.jsp";
            }
    }
        
}

  实现了ServletContextAware,用来获取应用上下文,利用它获取上传的文件目录。注意一下方法参数,@RequestParam("file") CommonsMultipartFile file,用来获取保存上传的文件,然后getOriginalFilename获取文件的名字,getFileItem获取上传的文件的相关信息,FileItem的write方法用来写上传文件的内容到另一个文件中。

  配置文件

<!-- 处理文件上传 -->
    <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8" /> <!-- 默认编码 (ISO-8859-1) -->
        <property name="maxInMemorySize" value="10240" /> <!-- 最大内存大小 (10240)-->
        <property name="uploadTempDir" value="/upload/" /> <!-- 上传后的目录名 (WebUtils#TEMP_DIR_CONTEXT_ATTRIBUTE) -->
        <property name="maxUploadSize" value="-1" /> <!-- 最大文件大小,-1为无限止(-1) -->
    </bean>

  2. spring4的文件上传。

  多文件上传页面(单文件上传页面类似spring3文件上传,此处省略)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="upload2.do" method="post" enctype="multipart/form-data">
    <table>
        <tr>
            <th colspan="2">上传文件</th>
        </tr>
        <tr>
            <td>文件一</td>
            <td>
                <input type="file" name="file"/>
            </td>
        </tr>
        <tr>
            <td>文件二</td>
            <td>
                <input type="file" name="file"/>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="上传文件"/>
            </td>
        </tr>
    </table>
</form>
</body>
</html>

  控制器

package com.java1234.controller;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

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

@Controller
public class FileUploadController {

    /**
     * 单文件上传
     * @param file1
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/upload")
    public String uploadFile(@RequestParam("file1") MultipartFile file1,HttpServletRequest request)throws Exception{
        String filePath=request.getServletContext().getRealPath("/");
        System.out.println(filePath);
        file1.transferTo(new File(filePath+"upload/"+file1.getOriginalFilename()));
        return "redirect:success.html";
    }
    
    /**
     * 多文件上传
     * @param files
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("/upload2")
    public String uploadFiles(@RequestParam("file") MultipartFile[] files,HttpServletRequest request)throws Exception{
        String filePath=request.getServletContext().getRealPath("/");
        System.out.println(filePath);
        for(MultipartFile file:files){
            file.transferTo(new File(filePath+"upload/"+file.getOriginalFilename()));            
        }
        return "redirect:success.html";
    }
}

  这里单文件上传文件信息保存在MultipartFile对象中,通过对象的transferTo方法保存到新的文件中。

  多文件上传参数@RequestParam("file") MultipartFile[] files,是一个MultipartFile的数组,处理与单文件上传类似,通过transferTo方法保存到新的文件中。

  配置文件

<bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        
        <property name="defaultEncoding" value="UTF-8"/>  
        <property name="maxUploadSize" value="10000000"/>

    </bean>

   关于文件上传下载的更多内容,可以看下面的文章:

  Spring MVC 实现文件的上传和下载

  SpringMVC实现文件下载的两种方法

  关于springmvc的内容就这么多,照着代码弄的,代码很浅显,更多内容还要靠自己慢慢探索。

  一个小疑问:处理器到底是什么?处理器其实就是Controller,是我们编写控制逻辑的地方,那么处理器映射器的作用就是找到某个Controller,处理器适配器的作用就是执行Controller中相应的方法完成相应的逻辑。


自己写的文章声明标题示例:


点赞(0) 打赏

全部评论

还没有评论!